diff --git a/examples/vite-core/src/App.tsx b/examples/vite-core/src/App.tsx index b3f2062..19ead68 100644 --- a/examples/vite-core/src/App.tsx +++ b/examples/vite-core/src/App.tsx @@ -73,6 +73,7 @@ const App = () => {
+ @@ -522,4 +523,200 @@ const SendOnchain = () => { ) } +const MnemonicManager = () => { + const [mnemonicState, setMnemonicState] = useState('') + const [inputMnemonic, setInputMnemonic] = useState('') + const [activeAction, setActiveAction] = useState< + 'get' | 'set' | 'generate' | null + >(null) + const [isLoading, setIsLoading] = useState(false) + const [message, setMessage] = useState<{ + text: string + type: 'success' | 'error' + }>() + const [showMnemonic, setShowMnemonic] = useState(false) + + const clearMessage = () => setMessage(undefined) + + // Helper function to extract user-friendly error messages + const extractErrorMessage = (error: any): string => { + let errorMsg = 'Operation failed' + + if (error instanceof Error) { + errorMsg = error.message + } else if (typeof error === 'object' && error !== null) { + // Handle RPC error objects + const rpcError = error as any + if (rpcError.error) { + errorMsg = rpcError.error + } else if (rpcError.message) { + errorMsg = rpcError.message + } + } + + return errorMsg + } + + const handleAction = async (action: 'get' | 'set' | 'generate') => { + if (activeAction === action) { + setActiveAction(null) + return + } + setActiveAction(action) + clearMessage() + + if (action === 'get') { + await handleGetMnemonic() + } else if (action === 'generate') { + await handleGenerateMnemonic() + } + } + + const handleGenerateMnemonic = async () => { + setIsLoading(true) + try { + const newMnemonic = await director.generateMnemonic() + setMnemonicState(newMnemonic.join(' ')) + setMessage({ text: 'New mnemonic generated!', type: 'success' }) + setShowMnemonic(true) + } catch (error) { + console.error('Error generating mnemonic:', error) + const errorMsg = extractErrorMessage(error) + setMessage({ text: errorMsg, type: 'error' }) + } finally { + setIsLoading(false) + } + } + + const handleGetMnemonic = async () => { + setIsLoading(true) + try { + const mnemonic = await director.getMnemonic() + if (mnemonic && mnemonic.length > 0) { + setMnemonicState(mnemonic.join(' ')) + setMessage({ text: 'Mnemonic retrieved!', type: 'success' }) + setShowMnemonic(true) + } else { + setMessage({ text: 'No mnemonic found', type: 'error' }) + } + } catch (error) { + console.error('Error getting mnemonic:', error) + const errorMsg = extractErrorMessage(error) + setMessage({ text: errorMsg, type: 'error' }) + } finally { + setIsLoading(false) + } + } + + const handleSetMnemonic = async (e: React.FormEvent) => { + e.preventDefault() + if (!inputMnemonic.trim()) return + + setIsLoading(true) + try { + const words = inputMnemonic.trim().split(/\s+/) + await director.setMnemonic(words) + setMessage({ text: 'Mnemonic set successfully!', type: 'success' }) + setInputMnemonic('') + setMnemonicState(words.join(' ')) + setActiveAction(null) + } catch (error) { + console.error('Error setting mnemonic:', error) + const errorMsg = extractErrorMessage(error) + setMessage({ text: errorMsg, type: 'error' }) + } finally { + setIsLoading(false) + } + } + + const copyToClipboard = async () => { + try { + await navigator.clipboard.writeText(mnemonicState) + setMessage({ text: 'Copied to clipboard!', type: 'success' }) + } catch (error) { + setMessage({ text: 'Failed to copy', type: 'error' }) + } + } + + return ( +
+

🔑 Mnemonic Manager

+ +
+ + + +
+ + {activeAction === 'set' && ( +
+