diff --git a/examples/keystore-management/src/components/Tabs/KeystoreTab/KeystoreManagement.tsx b/examples/keystore-management/src/components/Tabs/KeystoreTab/KeystoreManagement.tsx index 36e5d02..99849d4 100644 --- a/examples/keystore-management/src/components/Tabs/KeystoreTab/KeystoreManagement.tsx +++ b/examples/keystore-management/src/components/Tabs/KeystoreTab/KeystoreManagement.tsx @@ -1,6 +1,6 @@ "use client"; -import React from 'react'; +import React, { useState } from 'react'; import { useKeystore } from '../../../contexts/keystore'; import { useAppState } from '../../../contexts/AppStateContext'; import { useRLN } from '../../../contexts/rln'; @@ -9,14 +9,16 @@ import { saveKeystoreToFile, readKeystoreFromFile } from '../../../utils/fileUti export function KeystoreManagement() { const { hasStoredCredentials, - storedCredentialsHashes, + storedCredentialsHashes, error, - exportKeystore, + exportCredential, importKeystore, removeCredential } = useKeystore(); const { setGlobalError } = useAppState(); const { isInitialized, isStarted } = useRLN(); + const [exportPassword, setExportPassword] = useState(''); + const [selectedCredential, setSelectedCredential] = useState(null); React.useEffect(() => { if (error) { @@ -24,12 +26,18 @@ export function KeystoreManagement() { } }, [error, setGlobalError]); - const handleExport = () => { + const handleExportCredential = async (hash: string) => { try { - const keystoreJson = exportKeystore(); - saveKeystoreToFile(keystoreJson); + if (!exportPassword) { + setGlobalError('Please enter your keystore password to export'); + return; + } + const keystoreJson = await exportCredential(hash, exportPassword); + saveKeystoreToFile(keystoreJson, `waku-rln-credential-${hash.slice(0, 8)}.json`); + setExportPassword(''); + setSelectedCredential(null); } catch (err) { - setGlobalError(err instanceof Error ? err.message : 'Failed to export keystore'); + setGlobalError(err instanceof Error ? err.message : 'Failed to export credential'); } }; @@ -61,14 +69,8 @@ export function KeystoreManagement() {
- {/* Import/Export Actions */} -
- + {/* Import Action */} +
+
+
+ + {hash} + +
+ + +
+
+ + {selectedCredential === hash && ( +
+ setExportPassword(e.target.value)} + placeholder="Enter keystore password" + className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" + /> + +
+ )}
))} diff --git a/examples/keystore-management/src/contexts/keystore/KeystoreContext.tsx b/examples/keystore-management/src/contexts/keystore/KeystoreContext.tsx index 260443c..07ba2b2 100644 --- a/examples/keystore-management/src/contexts/keystore/KeystoreContext.tsx +++ b/examples/keystore-management/src/contexts/keystore/KeystoreContext.tsx @@ -11,7 +11,7 @@ interface KeystoreContextType { hasStoredCredentials: boolean; storedCredentialsHashes: string[]; saveCredentials: (credentials: KeystoreEntity, password: string) => Promise; - exportKeystore: () => string; + exportCredential: (hash: string, password: string) => Promise; importKeystore: (keystoreJson: string) => boolean; removeCredential: (hash: string) => void; } @@ -82,12 +82,24 @@ export function KeystoreProvider({ children }: { children: ReactNode }) { } }; - const exportKeystore = (): string => { + const exportCredential = async (hash: string, password: string): Promise => { if (!keystore) { throw new Error("Keystore not initialized"); } - return keystore.toString(); + // Create a new keystore instance for the single credential + const singleCredentialKeystore = Keystore.create(); + + // Get the credential from the main keystore + const credential = await keystore.readCredential(hash, password); + if (!credential) { + throw new Error("Credential not found"); + } + + // Add the credential to the new keystore + await singleCredentialKeystore.addCredential(credential, password); + + return singleCredentialKeystore.toString(); }; const importKeystore = (keystoreJson: string): boolean => { @@ -124,7 +136,7 @@ export function KeystoreProvider({ children }: { children: ReactNode }) { hasStoredCredentials: storedCredentialsHashes.length > 0, storedCredentialsHashes, saveCredentials, - exportKeystore, + exportCredential, importKeystore, removeCredential };