Create a custom hook that integrates Dynamic wallets with Rhinestone accounts. This demonstrates the core pattern: get the wallet client, then pass it to Rhinestone.
Copy
Ask AI
import { useDynamicContext } from '@dynamic-labs/sdk-react-core'import { createRhinestoneAccount } from "@rhinestone/sdk"import { isEthereumWallet } from '@dynamic-labs/ethereum'import { useState, useEffect, useMemo } from 'react'export function useGlobalWallet() { const { primaryWallet } = useDynamicContext(); const [rhinestoneAccount, setRhinestoneAccount] = useState(null) // Memoize the wallet address to use as a stable dependency const walletAddress = useMemo(() => { return primaryWallet?.address }, [primaryWallet?.address]) useEffect(() => { let isMounted = true async function initializeAccount() { if (!primaryWallet || !isEthereumWallet(primaryWallet) || !walletAddress) { setRhinestoneAccount(null) return } try { // Get the wallet client asynchronously const walletClient = await primaryWallet.getWalletClient() if (!isMounted) return // Dynamic sometimes needs address explicitly added to the client const walletClientWithAddress = { ...walletClient, address: walletAddress, }; // Pass the wallet client (from Dynamic) to Rhinestone // Rhinestone wraps it with cross-chain transaction capabilities const account = await createRhinestoneAccount({ owners: { type: "ecdsa", accounts: [walletClientWithAddress as any], // client from Dynamic }, rhinestoneApiKey: import.meta.env.VITE_RHINESTONE_API_KEY, }) if (isMounted) { setRhinestoneAccount(account) } } catch (error) { console.error('Failed to create Rhinestone account:', error) if (isMounted) { setRhinestoneAccount(null) } } } initializeAccount() // Cleanup function to prevent setting state on unmounted component return () => { isMounted = false } }, [primaryWallet?.address]) return { rhinestoneAccount, address: primaryWallet?.address }}