This is an automated email from the ASF dual-hosted git repository.

apratim pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-resilientdb-resvault.git


The following commit(s) were added to refs/heads/main by this push:
     new 6c6d3f6  Added multi-key support to ResVault
6c6d3f6 is described below

commit 6c6d3f64cbceea36717b169712a51dd61f295317
Author: Apratim Shukla <[email protected]>
AuthorDate: Wed Oct 9 19:20:11 2024 -0700

    Added multi-key support to ResVault
    
    - Now supports adding multiple keys to the same ResVault profile.
    - Modified GlobalContext to handle state management.
    - Selected keys can now be exported using the download button.
---
 src/App.js                   |  35 +-
 src/context/GlobalContext.js | 182 +++++++-
 src/css/App.css              |  24 ++
 src/index.js                 |   5 +-
 src/pages/Dashboard.jsx      | 978 +++++++++++++++++++++++--------------------
 src/pages/Home.jsx           |  36 +-
 src/pages/Login.jsx          | 368 +++++++++-------
 src/pages/SignUp.jsx         |  81 ++--
 8 files changed, 988 insertions(+), 721 deletions(-)

diff --git a/src/App.js b/src/App.js
index 489056e..1223c1f 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,27 +1,34 @@
 /*global chrome*/
 import './css/App.css';
-import React from 'react';
+import React, { useContext } from 'react';
 import Home from "./pages/Home";
 import SignUp from "./pages/SignUp";
 import Login from "./pages/Login";
 import Dashboard from "./pages/Dashboard";
 import Logs from "./pages/Logs";
-import { Navigate, Route, Routes } from "react-router-dom";
-import { GlobalProvider } from './context/GlobalContext';
+import { Routes, Route, Navigate } from 'react-router-dom';
+import { GlobalContext } from './context/GlobalContext';
 
 function App() {
+  const { isAuthenticated } = useContext(GlobalContext);
+
   return (
-    <GlobalProvider>
-      <Routes>
-        <Route path='/' element={<Home />} />
-        <Route path='/signup' element={<SignUp />} />
-        <Route path='/login' element={<Login />} />
-        <Route path='/dashboard' element={<Dashboard />} />
-        <Route path='/logs' element={<Logs />} />
-        <Route path='*' element={<Navigate to='/' />} />
-      </Routes>
-    </GlobalProvider>
+    <Routes>
+      {!isAuthenticated ? (
+        <>
+          <Route path="/" element={<Home />} />
+          <Route path="/signup" element={<SignUp />} />
+          <Route path="/login" element={<Login />} />
+          <Route path="*" element={<Navigate to="/" replace />} />
+        </>
+      ) : (
+        <>
+          <Route path="/dashboard" element={<Dashboard />} />
+          <Route path="*" element={<Navigate to="/dashboard" replace />} />
+        </>
+      )}
+    </Routes>
   );
 }
 
-export default App;
+export default App;
\ No newline at end of file
diff --git a/src/context/GlobalContext.js b/src/context/GlobalContext.js
index 4c85e55..7a88a7a 100644
--- a/src/context/GlobalContext.js
+++ b/src/context/GlobalContext.js
@@ -1,57 +1,193 @@
 /*global chrome*/
 import React, { createContext, useState, useEffect } from 'react';
 import CryptoJS from 'crypto-js';
+import nacl from 'tweetnacl';
+import Base58 from 'bs58';
 
 export const GlobalContext = createContext();
 
 export const GlobalProvider = ({ children }) => {
   const [values, setValues] = useState({ password: '', showPassword: false });
-  const [loginValues, setLoginValues] = useState({ password: '', showPassword: 
false });
   const [confirmValues, setConfirmValues] = useState({ password: '', 
showPassword: false });
-  const [transactionData, setTransactionData] = useState({});
+  const [loginValues, setLoginValues] = useState({ password: '', showPassword: 
false });
   const [publicKey, setPublicKey] = useState('');
   const [privateKey, setPrivateKey] = useState('');
-  const [networks, setNetworks] = useState([]);
+  const [keyPairs, setKeyPairs] = useState([]);
+  const [selectedKeyPairIndex, setSelectedKeyPairIndex] = useState(0);
+  const [isAuthenticated, setIsAuthenticated] = useState(false);
+  const [storedPassword, setStoredPassword] = useState('');
+
+  // Function to encrypt and store key pairs
+  const saveKeyPairsToStorage = (keyPairs, password) => {
+    const encryptedKeyPairs = CryptoJS.AES.encrypt(
+      JSON.stringify(keyPairs),
+      password
+    ).toString();
+    chrome.storage.sync.set({ encryptedKeyPairs }, () => {
+      console.log('Encrypted key pairs saved to storage.');
+    });
+  };
+
+  // Function to load and decrypt key pairs
+  const loadKeyPairsFromStorage = (password, callback) => {
+    chrome.storage.sync.get(['encryptedKeyPairs'], (result) => {
+      if (result.encryptedKeyPairs) {
+        try {
+          const bytes = CryptoJS.AES.decrypt(result.encryptedKeyPairs, 
password);
+          const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
+          const decryptedKeyPairs = JSON.parse(decryptedData);
+          callback(decryptedKeyPairs);
+        } catch (err) {
+          console.error('Error decrypting key pairs:', err);
+          callback([]);
+        }
+      } else {
+        callback([]);
+      }
+    });
+  };
+
+  // Function to save selected key pair index
+  const saveSelectedKeyPairIndex = (index) => {
+    chrome.storage.local.set({ selectedKeyPairIndex: index }, () => {});
+  };
+
+  // Function to load selected key pair index
+  const loadSelectedKeyPairIndex = (callback) => {
+    chrome.storage.local.get(['selectedKeyPairIndex'], (result) => {
+      const index = result.selectedKeyPairIndex !== undefined ? 
result.selectedKeyPairIndex : 0;
+      callback(index);
+    });
+  };
+
+  // Function to generate new key pair and store it
+  const generateKeyPair = (callback) => {
+    const password = storedPassword;
+    if (!password) {
+      console.error('Password is not available');
+      return;
+    }
 
+    const keyPair = nacl.sign.keyPair();
+    const newPublicKey = Base58.encode(keyPair.publicKey);
+    const newPrivateKey = Base58.encode(keyPair.secretKey.slice(0, 32));
+    const newKeyPair = { publicKey: newPublicKey, privateKey: newPrivateKey };
+
+    // Load existing key pairs
+    loadKeyPairsFromStorage(password, (existingKeyPairs) => {
+      const updatedKeyPairs = [...existingKeyPairs, newKeyPair];
+      // Save updated key pairs
+      saveKeyPairsToStorage(updatedKeyPairs, password);
+      setKeyPairs(updatedKeyPairs);
+      setPublicKey(newPublicKey);
+      setPrivateKey(newPrivateKey);
+      const newIndex = updatedKeyPairs.length - 1;
+      setSelectedKeyPairIndex(newIndex);
+      saveSelectedKeyPairIndex(newIndex);
+      setIsAuthenticated(true);
+
+      // Encrypt the private key and save in 'store'
+      const encryptedPrivateKey = CryptoJS.AES.encrypt(newPrivateKey, 
password).toString();
+      const hash = CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex);
+      const store = {
+        hash,
+        publicKey: newPublicKey,
+        encryptedPrivateKey: encryptedPrivateKey,
+        history: [],
+      };
+      chrome.storage.sync.set({ store }, () => {
+        console.log('Store updated with new key pair');
+        if (callback) {
+          callback();
+        }
+      });
+    });
+  };
+
+  // Load key pairs from storage when context is initialized
   useEffect(() => {
-    // Retrieve publicKey and encryptedPrivateKey from storage on 
initialization
-    chrome.storage.sync.get('store', (data) => {
-      if (data.store && data.store.publicKey) {
-        setPublicKey(data.store.publicKey);
-        chrome.storage.local.get('password', (passwordData) => {
-          if (passwordData.password) {
-            const decryptedPrivateKey = CryptoJS.AES.decrypt(
-              data.store.encryptedPrivateKey,
-              passwordData.password
-            ).toString(CryptoJS.enc.Utf8);
-            setPrivateKey(JSON.parse(decryptedPrivateKey));
+    // Retrieve password from storage
+    chrome.storage.local.get(['password'], (result) => {
+      const password = result.password;
+      if (password) {
+        setStoredPassword(password);
+        loadKeyPairsFromStorage(password, (loadedKeyPairs) => {
+          if (loadedKeyPairs.length > 0) {
+            setKeyPairs(loadedKeyPairs);
+            // Load selected key pair index
+            loadSelectedKeyPairIndex((index) => {
+              if (loadedKeyPairs[index]) {
+                setPublicKey(loadedKeyPairs[index].publicKey);
+                setPrivateKey(loadedKeyPairs[index].privateKey);
+                setSelectedKeyPairIndex(index);
+              } else if (loadedKeyPairs.length > 0) {
+                setPublicKey(loadedKeyPairs[0].publicKey);
+                setPrivateKey(loadedKeyPairs[0].privateKey);
+                setSelectedKeyPairIndex(0);
+              }
+              setIsAuthenticated(true);
+            });
+          } else {
+            setIsAuthenticated(false);
           }
         });
+      } else {
+        setIsAuthenticated(false);
       }
     });
   }, []);
 
-  const updateTransaction = (data) => setTransactionData(data);
-  const clearData = () => setTransactionData({});
+  // Function to set selected key pair
+  const setSelectedKeyPair = (index) => {
+    if (keyPairs[index]) {
+      setPublicKey(keyPairs[index].publicKey);
+      setPrivateKey(keyPairs[index].privateKey);
+      setSelectedKeyPairIndex(index);
+      saveSelectedKeyPairIndex(index);
+
+      const password = storedPassword;
+      if (!password) {
+        console.error('Password is not available');
+        return;
+      }
+      // Encrypt the private key and save in 'store'
+      const encryptedPrivateKey = 
CryptoJS.AES.encrypt(keyPairs[index].privateKey, password).toString();
+      const hash = CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex);
+      const store = {
+        hash,
+        publicKey: keyPairs[index].publicKey,
+        encryptedPrivateKey: encryptedPrivateKey,
+        history: [],
+      };
+      chrome.storage.sync.set({ store }, () => {
+        console.log('Store updated with selected key pair');
+      });
+    }
+  };
 
   return (
     <GlobalContext.Provider
       value={{
         values,
         setValues,
-        loginValues,
-        setLoginValues,
         confirmValues,
         setConfirmValues,
-        transactionData,
-        updateTransaction,
-        clearData,
+        loginValues,
+        setLoginValues,
         publicKey,
         setPublicKey,
         privateKey,
         setPrivateKey,
-        networks,
-        setNetworks,
+        keyPairs,
+        setKeyPairs,
+        generateKeyPair,
+        selectedKeyPairIndex,
+        setSelectedKeyPairIndex,
+        setSelectedKeyPair,
+        isAuthenticated,
+        setIsAuthenticated,
+        storedPassword,
+        setStoredPassword,
       }}
     >
       {children}
diff --git a/src/css/App.css b/src/css/App.css
index ca2f49b..1ab679e 100644
--- a/src/css/App.css
+++ b/src/css/App.css
@@ -3683,3 +3683,27 @@ tr:hover {
   justify-content: flex-end;
 }
 
+.keypair-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.keypair-icons {
+  display: flex;
+  align-items: center;
+}
+
+.icon-button {
+  background: none;
+  border: none;
+  outline: none;
+  cursor: pointer;
+  padding: 0 5px;
+}
+
+.icon-button:hover {
+  opacity: 0.7;
+}
+
+
diff --git a/src/index.js b/src/index.js
index 9f69574..efcfd5b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -25,6 +25,7 @@ import reportWebVitals from './reportWebVitals';
 import { transitions, positions, Provider as AlertProvider } from 
'react-alert';
 import AlertTemplate from 'react-alert-template-basic';
 import { MemoryRouter } from "react-router-dom";
+import { GlobalProvider } from './context/GlobalContext';
 
 // optional configuration
 const options = {
@@ -41,7 +42,9 @@ root.render(
   <React.StrictMode>
     <MemoryRouter>
       <AlertProvider template={AlertTemplate} {...options}>
-        <App />
+        <GlobalProvider>
+          <App />
+        </GlobalProvider>
       </AlertProvider>
     </MemoryRouter>
   </React.StrictMode>
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index ce52a3c..10cafc2 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -1,25 +1,28 @@
 /**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-* 
-*   http://www.apache.org/licenses/LICENSE-2.0
-* 
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-* OF ANY KIND, either express or implied.  See the License for the
-* specific language governing permissions and limitations
-* under the License.    
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
 
 /*global chrome*/
 import '../css/App.css';
 import ExitToAppIcon from '@mui/icons-material/ExitToApp';
+import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
+import DownloadIcon from '@mui/icons-material/Download';
 import React, { useRef, useState, useEffect, useContext } from 'react';
 import Lottie from 'react-lottie';
 import versionData from '../data/version.json';
@@ -30,7 +33,19 @@ import { GlobalContext } from '../context/GlobalContext';
 import { useNavigate } from 'react-router-dom';
 
 function Dashboard() {
-    const { publicKey, privateKey } = useContext(GlobalContext);
+    const {
+        publicKey,
+        privateKey,
+        keyPairs,
+        generateKeyPair,
+        setPublicKey,
+        setPrivateKey,
+        selectedKeyPairIndex,
+        setSelectedKeyPairIndex,
+        setSelectedKeyPair,
+        setIsAuthenticated,
+    } = useContext(GlobalContext);
+
     const [tabId, setTabId] = useState(null);
     const [domain, setDomain] = useState('');
     const [selectedNet, setSelectedNet] = useState('');
@@ -46,7 +61,6 @@ function Dashboard() {
     const [error, setError] = useState('');
     const [jsonFileName, setJsonFileName] = useState('');
     const fileInputRef = useRef(null);
-    const inputRef = useRef(null);
     const navigate = useNavigate();
 
     // New state variables for transaction data and handling
@@ -58,18 +72,13 @@ function Dashboard() {
     // New state for copying transaction ID
     const [isIdCopied, setIsIdCopied] = useState(false);
 
-    useEffect(() => {
-        console.log('publicKey in Dashboard:', publicKey);
-        console.log('privateKey in Dashboard:', privateKey);
-    }, [publicKey, privateKey]);
-
     const defaultOptions = {
         loop: true,
         autoplay: true,
         animationData: require('../images/bg.json'),
         rendererSettings: {
-            preserveAspectRatio: 'xMidYMid slice',
-            renderer: 'svg'
+        preserveAspectRatio: 'xMidYMid slice',
+        renderer: 'svg'
         }
     };
 
@@ -78,83 +87,83 @@ function Dashboard() {
         autoplay: true,
         animationData: require('../images/modal.json'),
         rendererSettings: {
-            preserveAspectRatio: 'xMidYMid slice',
-            renderer: 'svg'
+        preserveAspectRatio: 'xMidYMid slice',
+        renderer: 'svg'
         }
     };
 
     // Function to get full hostname from URL
     function getBaseDomain(url) {
         try {
-            const urlObj = new URL(url);
-            return urlObj.hostname;
+        const urlObj = new URL(url);
+        return urlObj.hostname;
         } catch (error) {
-            console.error('Invalid URL:', url);
-            return '';
+        console.error('Invalid URL:', url);
+        return '';
         }
     }
 
     // Function to set connection status per domain and net
     const setDomainConnectionStatus = (domain, net, isConnected) => {
         chrome.storage.local.get(['connections'], (result) => {
-            let connections = result.connections || {};
-            if (!connections[domain]) {
-                connections[domain] = {};
-            }
-            connections[domain][net] = isConnected;
-            chrome.storage.local.set({ connections });
+        let connections = result.connections || {};
+        if (!connections[domain]) {
+            connections[domain] = {};
+        }
+        connections[domain][net] = isConnected;
+        chrome.storage.local.set({ connections });
         });
     };
 
     // Function to get connection status per domain and net
     const getDomainConnectionStatus = (domain, net, callback) => {
         chrome.storage.local.get(['connections'], (result) => {
-            const connections = result.connections || {};
-            const domainConnections = connections[domain] || {};
-            const isConnected = domainConnections[net] || false;
-            callback(isConnected);
+        const connections = result.connections || {};
+        const domainConnections = connections[domain] || {};
+        const isConnected = domainConnections[net] || false;
+        callback(isConnected);
         });
     };
 
     useEffect(() => {
         chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
-            if (tabs.length > 0 && tabs[0].url) {
-                const currentTab = tabs[0];
-                setTabId(currentTab.id);
-
-                const currentDomain = getBaseDomain(currentTab.url);
-                setDomain(currentDomain);
-
-                // Ensure selectedNet is set before checking connection status
-                if (selectedNet) {
-                    getDomainConnectionStatus(currentDomain, selectedNet, 
(connected) => {
-                        setIsConnected(connected);
-                    });
-                }
-            } else {
-                // If no active tab or no URL, set domain to 'extension'
-                setDomain('extension');
-
-                // Ensure selectedNet is set before checking connection status
-                if (selectedNet) {
-                    getDomainConnectionStatus('extension', selectedNet, 
(connected) => {
-                        setIsConnected(connected);
-                    });
-                }
+        if (tabs.length > 0 && tabs[0].url) {
+            const currentTab = tabs[0];
+            setTabId(currentTab.id);
+
+            const currentDomain = getBaseDomain(currentTab.url);
+            setDomain(currentDomain);
+
+            // Ensure selectedNet is set before checking connection status
+            if (selectedNet) {
+            getDomainConnectionStatus(currentDomain, selectedNet, (connected) 
=> {
+                setIsConnected(connected);
+            });
+            }
+        } else {
+            // If no active tab or no URL, set domain to 'extension'
+            setDomain('extension');
+
+            // Ensure selectedNet is set before checking connection status
+            if (selectedNet) {
+            getDomainConnectionStatus('extension', selectedNet, (connected) => 
{
+                setIsConnected(connected);
+            });
             }
+        }
         });
     }, [selectedNet]);
 
     useEffect(() => {
         if (domain && selectedNet) {
-            chrome.runtime.sendMessage({ action: "requestData", domain: 
domain, net: selectedNet }, function(response) {
-                if (response && response.faviconUrl) {
-                    setFaviconUrl(response.faviconUrl);
-                } else {
-                    setFaviconUrl('');
-                }
-                // Handle other response data if needed
-            });
+        chrome.runtime.sendMessage({ action: "requestData", domain: domain, 
net: selectedNet }, function(response) {
+            if (response && response.faviconUrl) {
+            setFaviconUrl(response.faviconUrl);
+            } else {
+            setFaviconUrl('');
+            }
+            // Handle other response data if needed
+        });
         }
     }, [domain, selectedNet]);
 
@@ -166,38 +175,38 @@ function Dashboard() {
     useEffect(() => {
         // Fetch active net URL from storage
         chrome.storage.local.get(['activeNetUrl'], (result) => {
-            if (result.activeNetUrl) {
-                setCompleteUrl(result.activeNetUrl); // Use the full URL with 
protocol
-
-                // Check if it's one of the known networks
-                if (result.activeNetUrl === 
'https://cloud.resilientdb.com/graphql') {
-                    setSelectedNet('ResilientDB Mainnet');
-                } else if (result.activeNetUrl === 
'http://localhost:8000/graphql') {
-                    setSelectedNet('ResilientDB Localnet');
-                } else {
-                    // Custom URL case
-                    const customNet = nets.find(net => net.url === 
result.activeNetUrl);
-                    if (customNet) {
-                        setSelectedNet(customNet.name); // Set the name of the 
custom network
-                    } else {
-                        setSelectedNet('Custom URL');
-                    }
-                    // Set customUrl by stripping the protocol and /graphql 
part
-                    
setCustomUrl(result.activeNetUrl.replace(/^https?:\/\/|\/graphql$/g, ''));
-                }
+        if (result.activeNetUrl) {
+            setCompleteUrl(result.activeNetUrl); // Use the full URL with 
protocol
+
+            // Check if it's one of the known networks
+            if (result.activeNetUrl === 
'https://cloud.resilientdb.com/graphql') {
+            setSelectedNet('ResilientDB Mainnet');
+            } else if (result.activeNetUrl === 
'http://localhost:8000/graphql') {
+            setSelectedNet('ResilientDB Localnet');
+            } else {
+            // Custom URL case
+            const customNet = nets.find(net => net.url === 
result.activeNetUrl);
+            if (customNet) {
+                setSelectedNet(customNet.name); // Set the name of the custom 
network
             } else {
-                // No active net URL, default to ResilientDB Mainnet
-                setCompleteUrl('https://cloud.resilientdb.com/graphql');
-                setSelectedNet('ResilientDB Mainnet'); // Ensure default 
network is selected
+                setSelectedNet('Custom URL');
             }
+            // Set customUrl by stripping the protocol and /graphql part
+            
setCustomUrl(result.activeNetUrl.replace(/^https?:\/\/|\/graphql$/g, ''));
+            }
+        } else {
+            // No active net URL, default to ResilientDB Mainnet
+            setCompleteUrl('https://cloud.resilientdb.com/graphql');
+            setSelectedNet('ResilientDB Mainnet'); // Ensure default network 
is selected
+        }
         });
     }, [nets]);
 
     useEffect(() => {
         if (domain && selectedNet) {
-            getDomainConnectionStatus(domain, selectedNet, (connected) => {
-                setIsConnected(connected);
-            });
+        getDomainConnectionStatus(domain, selectedNet, (connected) => {
+            setIsConnected(connected);
+        });
         }
     }, [domain, selectedNet]);
 
@@ -205,14 +214,14 @@ function Dashboard() {
         const newProtocol = protocol === 'http' ? 'https' : 'http';
         setProtocol(newProtocol);
         if (selectedNet === 'Custom URL' && customUrl) {
-            setCompleteUrl(`${newProtocol}://${customUrl}/graphql`);
+        setCompleteUrl(`${newProtocol}://${customUrl}/graphql`);
         }
     };
 
     const addNet = () => {
         if (!newNetName.trim() || !customUrl.trim()) {
-            setError('Both fields are required.');
-            return;
+        setError('Both fields are required.');
+        return;
         }
         setError('');
         const fullUrl = `${protocol}://${customUrl}/graphql`;
@@ -232,77 +241,77 @@ function Dashboard() {
 
     const toggleConnection = () => {
         if (!publicKey || !privateKey) {
-          console.error('Public or Private key is missing');
-          return;
+        console.error('Public or Private key is missing');
+        return;
         }
-    
+
         const newConnectionStatus = !isConnected;
         setIsConnected(newConnectionStatus);
-    
+
         if (newConnectionStatus) {
-          console.log('Connecting to net:', selectedNet, 'on domain:', domain);
-          chrome.runtime.sendMessage(
+        console.log('Connecting to net:', selectedNet, 'on domain:', domain);
+        chrome.runtime.sendMessage(
             {
-              action: 'storeKeys',
-              publicKey,
-              privateKey,
-              url: completeUrl,
-              domain: domain,
-              net: selectedNet,
+            action: 'storeKeys',
+            publicKey,
+            privateKey,
+            url: completeUrl,
+            domain: domain,
+            net: selectedNet,
             },
             () => {
-              setDomainConnectionStatus(domain, selectedNet, 
newConnectionStatus);
+            setDomainConnectionStatus(domain, selectedNet, 
newConnectionStatus);
             }
-          );
+        );
         } else {
-          console.log('Disconnecting from net:', selectedNet, 'on domain:', 
domain);
-          chrome.runtime.sendMessage(
+        console.log('Disconnecting from net:', selectedNet, 'on domain:', 
domain);
+        chrome.runtime.sendMessage(
             {
-              action: 'disconnectKeys',
-              domain: domain,
-              net: selectedNet,
+            action: 'disconnectKeys',
+            domain: domain,
+            net: selectedNet,
             },
             () => {
-              setDomainConnectionStatus(domain, selectedNet, false);
+            setDomainConnectionStatus(domain, selectedNet, false);
             }
-          );
+        );
         }
     };
 
     const switchNetwork = (value) => {
         if (value === 'Manage Nets') {
-            setShowModal(true);
+        setShowModal(true);
         } else {
-            let newCompleteUrl = '';
-            switch (value) {
-                case 'ResilientDB Mainnet':
-                    newCompleteUrl = 'https://cloud.resilientdb.com/graphql';
-                    break;
-                case 'ResilientDB Localnet':
-                    newCompleteUrl = 'http://localhost:8000/graphql';
-                    break;
-                case 'Custom URL':
-                    if (customUrl) {
-                        newCompleteUrl = `${protocol}://${customUrl}/graphql`;
-                    } else {
-                        newCompleteUrl = `${protocol}://`;
-                    }
-                    break;
-                default:
-                    const selectedNetwork = nets.find(net => net.name === 
value);
-                    if (selectedNetwork) {
-                        newCompleteUrl = selectedNetwork.url;
-                        
setCustomUrl(selectedNetwork.url.split('://')[1].replace('/graphql', ''));
-                    }
-                    break;
+        let newCompleteUrl = '';
+        switch (value) {
+            case 'ResilientDB Mainnet':
+            newCompleteUrl = 'https://cloud.resilientdb.com/graphql';
+            break;
+            case 'ResilientDB Localnet':
+            newCompleteUrl = 'http://localhost:8000/graphql';
+            break;
+            case 'Custom URL':
+            if (customUrl) {
+                newCompleteUrl = `${protocol}://${customUrl}/graphql`;
+            } else {
+                newCompleteUrl = `${protocol}://`;
+            }
+            break;
+            default:
+            const selectedNetwork = nets.find(net => net.name === value);
+            if (selectedNetwork) {
+                newCompleteUrl = selectedNetwork.url;
+                
setCustomUrl(selectedNetwork.url.split('://')[1].replace('/graphql', ''));
             }
-            setCompleteUrl(newCompleteUrl);
-            setSelectedNet(value); // Set this at the end to avoid premature 
updates
+            break;
+        }
+        setCompleteUrl(newCompleteUrl);
+        setSelectedNet(value); // Set this at the end to avoid premature 
updates
 
-            // Update activeNetUrl in storage using the new URL
-            chrome.storage.local.set({ activeNetUrl: newCompleteUrl }, () => {
-                console.log('Active net URL updated to', newCompleteUrl);
-            });
+        // Update activeNetUrl in storage using the new URL
+        chrome.storage.local.set({ activeNetUrl: newCompleteUrl }, () => {
+            console.log('Active net URL updated to', newCompleteUrl);
+        });
         }
     };
 
@@ -311,21 +320,21 @@ function Dashboard() {
         if (value === selectedNet) return; // Ignore if the value hasn't 
changed
 
         if (isConnected) {
-            // Disconnect from the current network and clear domain connection 
status
-            chrome.runtime.sendMessage({
-                action: 'disconnectKeys',
-                domain: domain,
-                net: selectedNet
-            }, () => {
-                console.log('Disconnected from previous network');
-                setIsConnected(false);
-                setDomainConnectionStatus(domain, selectedNet, false);
-                // Proceed with switching networks
-                switchNetwork(value);
-            });
-        } else {
-            // If not connected, just switch networks
+        // Disconnect from the current network and clear domain connection 
status
+        chrome.runtime.sendMessage({
+            action: 'disconnectKeys',
+            domain: domain,
+            net: selectedNet
+        }, () => {
+            console.log('Disconnected from previous network');
+            setIsConnected(false);
+            setDomainConnectionStatus(domain, selectedNet, false);
+            // Proceed with switching networks
             switchNetwork(value);
+        });
+        } else {
+        // If not connected, just switch networks
+        switchNetwork(value);
         }
     };
 
@@ -337,61 +346,73 @@ function Dashboard() {
     };
 
     const back = () => {
-        chrome.storage.local.clear(function() {
-            navigate("/login");
+        chrome.storage.local.remove(['password'], function() {
+          setIsAuthenticated(false);
+          navigate("/login");
         });
     };
 
-    const originalAccountId = publicKey || '';
-    const shortenedId = originalAccountId
-        ? `${originalAccountId.slice(0, 5)}...${originalAccountId.slice(-5)}`
-        : '';
-
-    const handleInputClick = () => {
+    // Function to copy public key
+    const handleCopyPublicKey = () => {
         try {
-            const tempInput = document.createElement('input');
-            tempInput.value = originalAccountId;
-            document.body.appendChild(tempInput);
-            tempInput.select();
-            document.execCommand('copy');
-            document.body.removeChild(tempInput);
-            setIsCopied(true);
-            setTimeout(() => {
-                setIsCopied(false);
-            }, 1500);
+        const tempInput = document.createElement('input');
+        tempInput.value = publicKey;
+        document.body.appendChild(tempInput);
+        tempInput.select();
+        document.execCommand('copy');
+        document.body.removeChild(tempInput);
+        setIsCopied(true);
+        setTimeout(() => {
+            setIsCopied(false);
+        }, 1500);
         } catch (err) {
-            console.error('Unable to copy text: ', err);
+        console.error('Unable to copy text: ', err);
         }
     };
 
+    // Function to download key pair as JSON
+    const handleDownloadKeyPair = () => {
+        const keyPair = {
+        publicKey: publicKey,
+        privateKey: privateKey,
+        };
+        const dataStr = "data:text/json;charset=utf-8," + 
encodeURIComponent(JSON.stringify(keyPair));
+        const downloadAnchorNode = document.createElement('a');
+        downloadAnchorNode.setAttribute("href", dataStr);
+        downloadAnchorNode.setAttribute("download", "keypair.json");
+        document.body.appendChild(downloadAnchorNode); // required for firefox
+        downloadAnchorNode.click();
+        downloadAnchorNode.remove();
+    };
+
     const handleFileUpload = (e) => {
         const file = e.target.files[0];
         if (file && file.type === 'application/json') {
-            setJsonFileName(file.name); // Show file name once uploaded
-
-            const reader = new FileReader();
-            reader.onload = (event) => {
-                try {
-                    const json = JSON.parse(event.target.result);
-                    // Validate JSON data
-                    if (json.asset && json.recipientAddress && json.amount) {
-                        setTransactionData(json);
-                        setTransactionError(''); // Clear any previous error
-                    } else {
-                        setTransactionData(null);
-                        setTransactionError('Invalid JSON format: Missing 
required fields.');
-                    }
-                } catch (err) {
-                    console.error('Error parsing JSON:', err);
-                    setTransactionData(null);
-                    setTransactionError('Invalid JSON format.');
-                }
-            };
-            reader.readAsText(file);
-        } else {
-            setJsonFileName(''); // Clear if the file is not JSON
+        setJsonFileName(file.name); // Show file name once uploaded
+
+        const reader = new FileReader();
+        reader.onload = (event) => {
+            try {
+            const json = JSON.parse(event.target.result);
+            // Validate JSON data
+            if (json.asset && json.recipientAddress && json.amount) {
+                setTransactionData(json);
+                setTransactionError(''); // Clear any previous error
+            } else {
+                setTransactionData(null);
+                setTransactionError('Invalid JSON format: Missing required 
fields.');
+            }
+            } catch (err) {
+            console.error('Error parsing JSON:', err);
             setTransactionData(null);
-            setTransactionError('Please upload a JSON file.');
+            setTransactionError('Invalid JSON format.');
+            }
+        };
+        reader.readAsText(file);
+        } else {
+        setJsonFileName(''); // Clear if the file is not JSON
+        setTransactionData(null);
+        setTransactionError('Please upload a JSON file.');
         }
     };
 
@@ -410,31 +431,31 @@ function Dashboard() {
         e.stopPropagation();
         const file = e.dataTransfer.files[0];
         if (file && file.type === 'application/json') {
-            setJsonFileName(file.name);
-
-            const reader = new FileReader();
-            reader.onload = (event) => {
-                try {
-                    const json = JSON.parse(event.target.result);
-                    // Validate JSON data
-                    if (json.asset && json.recipientAddress && json.amount) {
-                        setTransactionData(json);
-                        setTransactionError(''); // Clear any previous error
-                    } else {
-                        setTransactionData(null);
-                        setTransactionError('Invalid JSON format: Missing 
required fields.');
-                    }
-                } catch (err) {
-                    console.error('Error parsing JSON:', err);
-                    setTransactionData(null);
-                    setTransactionError('Invalid JSON format.');
-                }
-            };
-            reader.readAsText(file);
-        } else {
-            setJsonFileName('');
+        setJsonFileName(file.name);
+
+        const reader = new FileReader();
+        reader.onload = (event) => {
+            try {
+            const json = JSON.parse(event.target.result);
+            // Validate JSON data
+            if (json.asset && json.recipientAddress && json.amount) {
+                setTransactionData(json);
+                setTransactionError(''); // Clear any previous error
+            } else {
+                setTransactionData(null);
+                setTransactionError('Invalid JSON format: Missing required 
fields.');
+            }
+            } catch (err) {
+            console.error('Error parsing JSON:', err);
             setTransactionData(null);
-            setTransactionError('Please upload a JSON file.');
+            setTransactionError('Invalid JSON format.');
+            }
+        };
+        reader.readAsText(file);
+        } else {
+        setJsonFileName('');
+        setTransactionData(null);
+        setTransactionError('Please upload a JSON file.');
         }
     };
 
@@ -444,49 +465,49 @@ function Dashboard() {
 
     const handleSubmit = () => {
         if (!transactionData) {
-            setTransactionError('No valid transaction data found.');
-            return;
+        setTransactionError('No valid transaction data found.');
+        return;
         }
         if (!isConnected) {
-            setTransactionError('Please connect to a net before submitting a 
transaction.');
-            return;
+        setTransactionError('Please connect to a net before submitting a 
transaction.');
+        return;
         }
 
         // Send transaction data to background script
         chrome.runtime.sendMessage({
-            action: 'submitTransactionFromDashboard',
-            transactionData: transactionData,
-            domain: domain,
-            net: selectedNet,
+        action: 'submitTransactionFromDashboard',
+        transactionData: transactionData,
+        domain: domain,
+        net: selectedNet,
         }, (response) => {
-            if (response.success) {
-                setSuccessResponse(response.data);
-                setShowSuccessModal(true);
-                setTransactionError('');
-                setJsonFileName(''); // Clear the file name after successful 
submission
-                setTransactionData(null);
-            } else {
-                setTransactionError(response.error || 'Transaction submission 
failed.');
-            }
+        if (response.success) {
+            setSuccessResponse(response.data);
+            setShowSuccessModal(true);
+            setTransactionError('');
+            setJsonFileName(''); // Clear the file name after successful 
submission
+            setTransactionData(null);
+        } else {
+            setTransactionError(response.error || 'Transaction submission 
failed.');
+        }
         });
     };
 
     // New function to handle transaction ID click
     const handleIdClick = () => {
         try {
-            const transactionId = (successResponse && 
successResponse.postTransaction && successResponse.postTransaction.id) || '';
-            const tempInput = document.createElement('input');
-            tempInput.value = transactionId;
-            document.body.appendChild(tempInput);
-            tempInput.select();
-            document.execCommand('copy');
-            document.body.removeChild(tempInput);
-            setIsIdCopied(true);
-            setTimeout(() => {
-                setIsIdCopied(false);
-            }, 1500);
+        const transactionId = (successResponse && 
successResponse.postTransaction && successResponse.postTransaction.id) || '';
+        const tempInput = document.createElement('input');
+        tempInput.value = transactionId;
+        document.body.appendChild(tempInput);
+        tempInput.select();
+        document.execCommand('copy');
+        document.body.removeChild(tempInput);
+        setIsIdCopied(true);
+        setTimeout(() => {
+            setIsIdCopied(false);
+        }, 1500);
         } catch (err) {
-            console.error('Unable to copy text: ', err);
+        console.error('Unable to copy text: ', err);
         }
     };
 
@@ -495,214 +516,259 @@ function Dashboard() {
         setFaviconUrl(''); // This will trigger the globe icon to display
     };
 
+    const disconnectDueToKeysChange = () => {
+        if (isConnected) {
+            // Disconnect from the current network and clear domain connection 
status
+            chrome.runtime.sendMessage({
+                action: 'disconnectKeys',
+                domain: domain,
+                net: selectedNet
+            }, () => {
+                console.log('Disconnected from previous network');
+                setIsConnected(false);
+                setDomainConnectionStatus(domain, selectedNet, false);
+            });
+        }
+    }
+
+    const switchKeyPair = (index) => {
+        setSelectedKeyPair(index);
+        disconnectDueToKeysChange();
+    };
+
+    const handleGenerateKeyPair = () => {
+        generateKeyPair(() => {
+          setSelectedKeyPairIndex(keyPairs.length); // Select the newly 
generated key pair
+          disconnectDueToKeysChange();
+        });
+    };
+      
+
     return (
         <>
-            <div className="lottie-background">
-                <Lottie options={defaultOptions} height="100%" width="100%" />
+        <div className="lottie-background">
+            <Lottie options={defaultOptions} height="100%" width="100%" />
+        </div>
+        <div className="page page--main" data-page="buy">
+            <header className="header header--fixed">
+            <div className="header__inner header-container">
+                <div className="header__logo header__logo--text">
+                Res<strong>Vault</strong>
+                </div>
+                <div className="badge-container">
+                <span className="badge">KV Service</span>
+                </div>
+                <div className="header__icon open-panel">
+                <button
+                    style={{ background: 'none', color: 'white', fontWeight: 
'bolder', outline: 'none', borderStyle: 'none', cursor: 'pointer' }}
+                    onClick={back}
+                >
+                    <ExitToAppIcon />
+                </button>
+                </div>
             </div>
-            <div className="page page--main" data-page="buy">
-                <header className="header header--fixed">
-                    <div className="header__inner header-container">
-                        <div className="header__logo header__logo--text">
-                            Res<strong>Vault</strong>
-                        </div>
-                        <div className="badge-container">
-                            <span className="badge">KV Service</span>
-                        </div>
-                        <div className="header__icon open-panel">
-                            <button
-                                style={{ background: 'none', color: 'white', 
fontWeight: 'bolder', outline: 'none', borderStyle: 'none', cursor: 'pointer' }}
-                                onClick={back}
-                            >
-                                <ExitToAppIcon />
-                            </button>
-                        </div>
-                    </div>
-                </header>
-
-                {showModal && (
-                    <div className="overlay">
-                        <div className="modal">
-                            <div className="lottie-modal-background">
-                                <Lottie options={modalOptions} height="100%" 
width="100%" />
-                            </div>
-                            <div className="modal-content">
-                                <h2>Manage Nets</h2>
-                                {nets.length > 0 && (
-                                    <div className="table-container">
-                                        <table>
-                                            <thead>
-                                                <tr>
-                                                    <th>Net Name</th>
-                                                    <th>Action</th>
-                                                </tr>
-                                            </thead>
-                                            <tbody>
-                                                {nets.map(net => (
-                                                    <tr key={net.name}>
-                                                        <td>{net.name}</td>
-                                                        <td>
-                                                            <button 
className="icon-button" onClick={() => removeNet(net.name)}>
-                                                                <i 
className="fas fa-trash"></i>
-                                                            </button>
-                                                        </td>
-                                                    </tr>
-                                                ))}
-                                            </tbody>
-                                        </table>
-                                    </div>
-                                )}
-                                <input className="modal-net-input" type="text" 
placeholder="Net Name" value={newNetName} onChange={e => 
setNewNetName(e.target.value)} />
-                                <div className="modal-url-input-container">
-                                    <div className="modal-url-toggle" 
onClick={toggleProtocol}>
-                                        <FontAwesomeIcon icon={protocol === 
'https' ? faLock : faUnlock} className={`icon ${protocol === 'https' ? 
'icon-green' : 'icon-red'}`} />
-                                    </div>
-                                    <input type="text" placeholder="GraphQL 
URL" value={customUrl} onChange={handleCustomUrlChange} 
className="modal-url-input" />
-                                    <div className="modal-url-fixed">
-                                        <img src={graphql} 
className="graphql-icon" alt="GraphQL"></img>
-                                    </div>
-                                </div>
-                                <div className="save-container">
-                                    <button onClick={addNet} 
className="button-save">
-                                        Save
-                                    </button>
-                                    <button onClick={() => 
setShowModal(false)} className="button-close">
-                                        Close
-                                    </button>
-                                </div>
-                                {error && <p 
className="error-message">{error}</p>}
-                            </div>
-                        </div>
-                    </div>
-                )}
+            </header>
 
-                {showSuccessModal && (
-                    <div className="overlay">
-                        <div className="modal">
-                            <div className="modal-content">
-                                <h2>Transaction Submitted Successfully!</h2>
-                                {/* Extract transaction ID */}
-                                {successResponse && 
successResponse.postTransaction && successResponse.postTransaction.id ? (
-                                <div className="fieldset">
-                                    <div className="radio-option 
radio-option--full">
-                                        <input
-                                            type="radio"
-                                            name="transactionId"
-                                            id="txId"
-                                            
value={successResponse.postTransaction.id}
-                                            checked
-                                            readOnly
-                                            onClick={handleIdClick}
-                                        />
-                                        <label htmlFor="txId">
-                                            <span>{isIdCopied ? 'Copied' : 
`${successResponse.postTransaction.id.slice(0, 
5)}...${successResponse.postTransaction.id.slice(-5)}`}</span>
-                                        </label>
-                                    </div>
-                                </div>
-                                ) : (
-                                    <p>No transaction ID found.</p>
-                                )}
-                                <button onClick={() => 
setShowSuccessModal(false)} className="button-close">
-                                    Close
+            {showModal && (
+            <div className="overlay">
+                <div className="modal">
+                <div className="lottie-modal-background">
+                    <Lottie options={modalOptions} height="100%" width="100%" 
/>
+                </div>
+                <div className="modal-content">
+                    <h2>Manage Nets</h2>
+                    {nets.length > 0 && (
+                    <div className="table-container">
+                        <table>
+                        <thead>
+                            <tr>
+                            <th>Net Name</th>
+                            <th>Action</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            {nets.map(net => (
+                            <tr key={net.name}>
+                                <td>{net.name}</td>
+                                <td>
+                                <button className="icon-button" onClick={() => 
removeNet(net.name)}>
+                                    <i className="fas fa-trash"></i>
                                 </button>
-                            </div>
-                        </div>
+                                </td>
+                            </tr>
+                            ))}
+                        </tbody>
+                        </table>
+                    </div>
+                    )}
+                    <input className="modal-net-input" type="text" 
placeholder="Net Name" value={newNetName} onChange={e => 
setNewNetName(e.target.value)} />
+                    <div className="modal-url-input-container">
+                    <div className="modal-url-toggle" onClick={toggleProtocol}>
+                        <FontAwesomeIcon icon={protocol === 'https' ? faLock : 
faUnlock} className={`icon ${protocol === 'https' ? 'icon-green' : 
'icon-red'}`} />
+                    </div>
+                    <input type="text" placeholder="GraphQL URL" 
value={customUrl} onChange={handleCustomUrlChange} className="modal-url-input" 
/>
+                    <div className="modal-url-fixed">
+                        <img src={graphql} className="graphql-icon" 
alt="GraphQL"></img>
+                    </div>
+                    </div>
+                    <div className="save-container">
+                    <button onClick={addNet} className="button-save">
+                        Save
+                    </button>
+                    <button onClick={() => setShowModal(false)} 
className="button-close">
+                        Close
+                    </button>
+                    </div>
+                    {error && <p className="error-message">{error}</p>}
+                </div>
+                </div>
+            </div>
+            )}
+
+            {showSuccessModal && (
+            <div className="overlay">
+                <div className="modal">
+                <div className="modal-content">
+                    <h2>Transaction Submitted Successfully!</h2>
+                    {/* Extract transaction ID */}
+                    {successResponse && successResponse.postTransaction && 
successResponse.postTransaction.id ? (
+                    <div className="fieldset">
+                    <div className="radio-option radio-option--full">
+                        <input
+                        type="radio"
+                        name="transactionId"
+                        id="txId"
+                        value={successResponse.postTransaction.id}
+                        checked
+                        readOnly
+                        onClick={handleIdClick}
+                        />
+                        <label htmlFor="txId">
+                        <span>{isIdCopied ? 'Copied' : 
`${successResponse.postTransaction.id.slice(0, 
5)}...${successResponse.postTransaction.id.slice(-5)}`}</span>
+                        </label>
                     </div>
+                    </div>
+                    ) : (
+                    <p>No transaction ID found.</p>
+                    )}
+                    <button onClick={() => setShowSuccessModal(false)} 
className="button-close">
+                    Close
+                    </button>
+                </div>
+                </div>
+            </div>
+            )}
+
+            <div className="page__content page__content--with-header 
page__content--with-bottom-nav">
+            <h2 className="page__title">Dashboard</h2>
+
+            <div className="net">
+                <div className="net-header">
+                <div className="select-wrapper">
+                    <select value={selectedNet} onChange={handleNetworkChange} 
className="select">
+                    <option value="ResilientDB Mainnet">ResilientDB 
Mainnet</option>
+                    <option value="ResilientDB Localnet">ResilientDB 
Localnet</option>
+                    {nets.map(net => (
+                        <option key={net.name} 
value={net.name}>{net.name}</option>
+                    ))}
+                    <option value="Manage Nets">Manage Nets</option>
+                    </select>
+                    <i className="fas fa-chevron-down"></i>
+                </div>
+
+                <div className="icon-container" onClick={toggleConnection}>
+                    {faviconUrl ? (
+                    <img
+                        src={faviconUrl}
+                        alt="Favicon"
+                        className={`icon ${isConnected ? 'connected' : ''}`}
+                        onError={handleFaviconError}
+                    />
+                    ) : (
+                    <i className={`fa fa-globe icon ${isConnected ? 
'connected' : ''}`} aria-hidden="true"></i>
+                    )}
+                    <span className="status-dot"></span>
+                    <span className="tooltip">{isConnected ? 'Connected' : 
'Disconnected'}</span>
+                </div>
+                {selectedNet === 'Custom Net' && (
+                    <input
+                    type="text"
+                    value={customUrl}
+                    onChange={handleCustomUrlChange}
+                    placeholder="Enter custom URL"
+                    className="input"
+                    />
                 )}
+                </div>
 
-                <div className="page__content page__content--with-header 
page__content--with-bottom-nav">
-                    <h2 className="page__title">Dashboard</h2>
-
-                    <div className="net">
-                        <div className="net-header">
-                            <div className="select-wrapper">
-                                <select value={selectedNet} 
onChange={handleNetworkChange} className="select">
-                                    <option value="ResilientDB 
Mainnet">ResilientDB Mainnet</option>
-                                    <option value="ResilientDB 
Localnet">ResilientDB Localnet</option>
-                                    {nets.map(net => (
-                                        <option key={net.name} 
value={net.name}>{net.name}</option>
-                                    ))}
-                                    <option value="Manage Nets">Manage 
Nets</option>
-                                </select>
-                                <i className="fas fa-chevron-down"></i>
-                            </div>
-
-                            <div className="icon-container" 
onClick={toggleConnection}>
-                                {faviconUrl ? (
-                                    <img
-                                        src={faviconUrl}
-                                        alt="Favicon"
-                                        className={`icon ${isConnected ? 
'connected' : ''}`}
-                                        onError={handleFaviconError} // Add 
onError handler
-                                    />
-                                ) : (
-                                    <i className={`fa fa-globe icon 
${isConnected ? 'connected' : ''}`} aria-hidden="true"></i>
-                                )}
-                                <span className="status-dot"></span>
-                                <span className="tooltip">{isConnected ? 
'Connected' : 'Disconnected'}</span>
-                            </div>
-                            {selectedNet === 'Custom Net' && (
-                                <input
-                                    type="text"
-                                    value={customUrl}
-                                    onChange={handleCustomUrlChange}
-                                    placeholder="Enter custom URL"
-                                    className="input"
-                                />
-                            )}
-                        </div>
-                        <div className="file-upload">
-                            <div
-                                className={`drag_box_outline ${jsonFileName ? 
'file-uploaded' : ''}`}
-                                onDragEnter={handleDragEnter}
-                                onDragOver={handleDragOver}
-                                onDrop={handleDrop}
-                                onClick={handleFileClick}
-                            >
-                                <input
-                                    type="file"
-                                    ref={fileInputRef}
-                                    style={{ display: 'none' }}
-                                    accept="application/json"
-                                    onChange={handleFileUpload}
-                                />
-                                {jsonFileName ? (
-                                    <span className="filename">{jsonFileName} 
uploaded</span>
-                                ) : (
-                                    <span className="filename">Click to Upload 
JSON File</span>
-                                )}
-                            </div>
-                            {transactionError && <p 
className="error-message">{transactionError}</p>}
-                        </div>
+                <div className="file-upload">
+                    <div
+                    className={`drag_box_outline ${jsonFileName ? 
'file-uploaded' : ''}`}
+                    onDragEnter={handleDragEnter}
+                    onDragOver={handleDragOver}
+                    onDrop={handleDrop}
+                    onClick={handleFileClick}
+                    >
+                    <input
+                        type="file"
+                        ref={fileInputRef}
+                        style={{ display: 'none' }}
+                        accept="application/json"
+                        onChange={handleFileUpload}
+                    />
+                    {jsonFileName ? (
+                        <span className="filename">{jsonFileName} 
uploaded</span>
+                    ) : (
+                        <span className="filename">Click to Upload JSON 
File</span>
+                    )}
                     </div>
+                    {transactionError && <p 
className="error-message">{transactionError}</p>}
+                </div>
+            </div>
 
-                    <h2 className="page__title">Select Account</h2>
-                    <div className="fieldset">
-                        <div className="radio-option radio-option--full">
-                            <input
-                                type="radio"
-                                name="wallet"
-                                id="w3"
-                                value={originalAccountId}
-                                checked
-                                readOnly
-                                onClick={handleInputClick}
-                                ref={inputRef}
-                            />
-                            <label htmlFor="w3">
-                                <span>{isCopied ? 'Copied' : 
shortenedId}</span>
-                            </label>
-                        </div>
+            
+
+            <h2 className="page__title">Select Account</h2>
+            <div className="net">
+                <div className="keypair">
+                    <div className="keypair-header">
+                    <div className="select-wrapper">
+                        <select
+                        value={selectedKeyPairIndex}
+                        onChange={(e) => switchKeyPair(e.target.value)}
+                        className="select"
+                        >
+                        {keyPairs.map((keyPair, index) => (
+                            <option key={index} value={index}>
+                            {`${keyPair.publicKey.slice(0, 
4)}...${keyPair.publicKey.slice(-4)}`}
+                            </option>
+                        ))}
+                        </select>
+                        <i className="fas fa-chevron-down"></i>
+                    </div>
+                    <div className="keypair-icons">
+                        <button onClick={handleGenerateKeyPair} 
className="icon-button">
+                            <AddCircleOutlineIcon style={{ color: 'white' }} />
+                        </button>
+                        <button onClick={handleCopyPublicKey} 
className="icon-button">
+                            <ContentCopyIcon style={{ color: isCopied ? 
'green' : 'white' }} />
+                        </button>
+                        <button onClick={handleDownloadKeyPair} 
className="icon-button">
+                            <DownloadIcon style={{ color: 'white' }} />
+                        </button>
+                    </div>
                     </div>
-
-                    <button className="button button--full button--main 
open-popup" onClick={handleSubmit}>
-                        Submit
-                    </button>
-                    <p className="bottom-navigation" style={{ backgroundColor: 
'transparent', display: 'flex', justifyContent: 'center', textShadow: '1px 1px 
1px rgba(0, 0, 0, 0.3)', color: 'rgb(255, 255, 255, 0.5)', fontSize: '9px' }}>
-                        ResVault v{versionData.version}
-                    </p>
                 </div>
             </div>
+
+            <button className="button button--full button--main open-popup" 
onClick={handleSubmit}>
+                Submit
+            </button>
+            <p className="bottom-navigation" style={{ backgroundColor: 
'transparent', display: 'flex', justifyContent: 'center', textShadow: '1px 1px 
1px rgba(0, 0, 0, 0.3)', color: 'rgb(255, 255, 255, 0.5)', fontSize: '9px' }}>
+                ResVault v{versionData.version}
+            </p>
+            </div>
+        </div>
         </>
     );
 }
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index 0347311..951d31b 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -1,21 +1,21 @@
 /**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-* 
-*   http://www.apache.org/licenses/LICENSE-2.0
-* 
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied.  See the License for the
-* specific language governing permissions and limitations
-* under the License.    
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
 
 
 /*global chrome*/
@@ -52,7 +52,7 @@ function Home() {
             navigate("/login", { state: res.store });
           } else {
             // Decrypt private key and store both public and private keys
-            const bytes = CryptoJS.AES.decrypt(res.store.encryptedPrivateKey, 
result.password.password);
+            const bytes = CryptoJS.AES.decrypt(res.store.encryptedPrivateKey, 
result.password);
             const privateKey = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
             setPublicKey(res.store.publicKey);
             setPrivateKey(privateKey);
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
index 90b1cf7..a2d5bea 100644
--- a/src/pages/Login.jsx
+++ b/src/pages/Login.jsx
@@ -1,25 +1,6 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-* 
-*   http://www.apache.org/licenses/LICENSE-2.0
-* 
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied.  See the License for the
-* specific language governing permissions and limitations
-* under the License.    
-*/
-
 /*global chrome*/
 import '../css/App.css';
-import CryptoJS from "crypto-js";
+import CryptoJS from "crypto-js";  // Changed to default import
 import IconButton from "@material-ui/core/IconButton";
 import Visibility from "@material-ui/icons/Visibility";
 import InputAdornment from "@material-ui/core/InputAdornment";
@@ -32,147 +13,222 @@ import versionData from '../data/version.json';
 import { GlobalContext } from '../context/GlobalContext';
 
 function Login() {
-    const { loginValues, setLoginValues, setPublicKey, setPrivateKey } = 
useContext(GlobalContext);
-    const navigate = useNavigate();
-    const [showPasswordErrorModal, setShowPasswordErrorModal] = 
useState(false);
-
-    const defaultOptions = {
-        loop: true,
-        autoplay: true,
-        animationData: require('../images/signup.json'),
-        rendererSettings: {
-            preserveAspectRatio: 'xMidYMid slice',
-            renderer: 'svg'
+  const {
+    loginValues,
+    setLoginValues,
+    setPublicKey,
+    setPrivateKey,
+    setIsAuthenticated,
+    setKeyPairs,
+    setSelectedKeyPairIndex,
+    setStoredPassword
+  } = useContext(GlobalContext);
+  const navigate = useNavigate();
+  const [showPasswordErrorModal, setShowPasswordErrorModal] = useState(false);
+
+  const defaultOptions = {
+    loop: true,
+    autoplay: true,
+    animationData: require('../images/signup.json'),
+    rendererSettings: {
+      preserveAspectRatio: 'xMidYMid slice',
+      renderer: 'svg'
+    }
+  };
+
+  const removeAccount = async () => {
+    chrome.storage.sync.clear(function() {});
+    chrome.storage.local.clear(function() {});
+    localStorage.removeItem('nets');
+    setIsAuthenticated(false);
+    navigate("/");
+  };
+
+  const loginAccount = async (e) => {
+    e.preventDefault();
+    chrome.storage.sync.get(['store', 'encryptedKeyPairs'], (res) => {
+      if (res.store && 
CryptoJS.SHA256(loginValues.password).toString(CryptoJS.enc.Hex) === 
res.store.hash) {
+        try {
+          // Decrypt private key from store
+          const privateKeyBytes = 
CryptoJS.AES.decrypt(res.store.encryptedPrivateKey, loginValues.password);
+          const decryptedPrivateKey = 
privateKeyBytes.toString(CryptoJS.enc.Utf8);
+          const publicKey = res.store.publicKey;
+
+          // Check if encryptedKeyPairs exist
+          if (!res.encryptedKeyPairs) {
+            console.error('No encryptedKeyPairs found in storage.');
+            setShowPasswordErrorModal(true);
+            return;
+          }
+
+          // Load key pairs
+          const encryptedKeyPairs = res.encryptedKeyPairs;
+          const decryptedKeyPairsBytes = 
CryptoJS.AES.decrypt(encryptedKeyPairs, loginValues.password);
+          const decryptedKeyPairsString = 
decryptedKeyPairsBytes.toString(CryptoJS.enc.Utf8);
+
+          let decryptedKeyPairs;
+          try {
+            decryptedKeyPairs = JSON.parse(decryptedKeyPairsString);
+          } catch (parseError) {
+            console.error('Error parsing decrypted key pairs:', parseError, 
'decryptedKeyPairsString:', decryptedKeyPairsString);
+            setShowPasswordErrorModal(true);
+            return;
+          }
+
+          // Ensure decryptedKeyPairs is an array
+          if (!Array.isArray(decryptedKeyPairs)) {
+            console.error('Decrypted key pairs is not an array:', 
decryptedKeyPairs);
+            setShowPasswordErrorModal(true);
+            return;
+          }
+
+          // Update keyPairs and set keys
+          setKeyPairs(decryptedKeyPairs);
+          // Find the index of the key pair matching the publicKey
+          const keyPairIndex = decryptedKeyPairs.findIndex(kp => kp.publicKey 
=== publicKey);
+          if (keyPairIndex !== -1) {
+            setSelectedKeyPairIndex(keyPairIndex);
+            setPublicKey(decryptedKeyPairs[keyPairIndex].publicKey);
+            setPrivateKey(decryptedKeyPairs[keyPairIndex].privateKey);
+          } else {
+            // If not found, default to first key pair
+            setSelectedKeyPairIndex(0);
+            setPublicKey(decryptedKeyPairs[0].publicKey);
+            setPrivateKey(decryptedKeyPairs[0].privateKey);
+          }
+
+          // Store password in chrome.storage.local and set storedPassword in 
context
+          chrome.storage.local.set({ password: loginValues.password }, () => {
+            setStoredPassword(loginValues.password);
+            setIsAuthenticated(true);
+            navigate("/dashboard");
+          });
+        } catch (err) {
+          console.error('Error during login:', err);
+          setShowPasswordErrorModal(true);
         }
-    };
-
-    const removeAccount = async () => {
-        chrome.storage.sync.clear(function() {});
-        localStorage.removeItem('nets');
-        navigate("/");
-    };
-
-    useEffect(() => {
-        chrome.storage.local.get(['password'], (result) => {
-            if (result.password) {
-                chrome.storage.sync.get(['store'], (res) => {
-                    if (res.store) {
-                        setPublicKey(res.store.publicKey);
-                        setPrivateKey(res.store.encryptedPrivateKey);
-                        navigate("/dashboard");
+      } else {
+        setShowPasswordErrorModal(true);
+      }
+    });
+  };
+
+  const handleClickShowPassword = () => {
+    setLoginValues({ ...loginValues, showPassword: !loginValues.showPassword 
});
+  };
+
+  const handleMouseDownPassword = (event) => {
+    event.preventDefault();
+  };
+
+  const handlePasswordChange = (prop) => (event) => {
+    setLoginValues({ ...loginValues, [prop]: event.target.value });
+  };
+
+  const closeModal = () => {
+    setShowPasswordErrorModal(false);
+  };
+
+  // Reset loginValues when the component mounts
+  useEffect(() => {
+    setLoginValues({ password: '', showPassword: false });
+  }, [setLoginValues]);
+
+  return (
+    <>
+      <div className="lottie-background">
+        <Lottie options={defaultOptions} height="100%" width="100%" />
+      </div>
+      <div className="page page--login" data-page="login">
+        <div className="login">
+          <div className="login__content">
+            <h2 className="login__title">Login</h2>
+            <div className="login-form">
+              <form id="LoginForm" onSubmit={loginAccount}>
+                <div className="login-form__row">
+                  <label className="login-form__label">Password</label>
+                  <Input
+                    type={loginValues.showPassword ? "text" : "password"}
+                    onChange={handlePasswordChange("password")}
+                    placeholder="Password"
+                    className="login-form__input"
+                    value={loginValues.password}
+                    style={{ color: 'white', width: '100%' }}
+                    disableUnderline
+                    required
+                    endAdornment={
+                      <InputAdornment position="end">
+                        <IconButton
+                          onClick={handleClickShowPassword}
+                          onMouseDown={handleMouseDownPassword}
+                          style={{ color: 'white' }}
+                        >
+                          {loginValues.showPassword ? <Visibility /> : 
<VisibilityOff />}
+                        </IconButton>
+                      </InputAdornment>
                     }
-                });
-            }
-        });
-    }, [navigate, setPublicKey, setPrivateKey]);
-
-    const loginAccount = async (e) => {
-        e.preventDefault();
-        chrome.storage.sync.get(['store'], (res) => {
-            if (res.store && 
CryptoJS.SHA256(loginValues.password).toString(CryptoJS.enc.Hex) === 
res.store.hash) {
-                try {
-                    const bytes = 
CryptoJS.AES.decrypt(res.store.encryptedPrivateKey, loginValues.password);
-                    const decryptedPrivateKey = 
JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
-                    setPublicKey(res.store.publicKey);
-                    setPrivateKey(decryptedPrivateKey);
-                    
-                    chrome.storage.local.set({ password: { password: 
loginValues.password } }, () => {});
-                    navigate("/dashboard");
-                } catch (err) {
-                    setShowPasswordErrorModal(true);  // Show modal if 
decryption fails
-                }
-            } else {
-                setShowPasswordErrorModal(true);  // Show modal if password is 
incorrect
-            }
-        });
-    };
-
-    const handleClickShowPassword = () => {
-        setLoginValues({ ...loginValues, showPassword: 
!loginValues.showPassword });
-    };
-
-    const handleMouseDownPassword = (event) => {
-        event.preventDefault();
-    };
-
-    const handlePasswordChange = (prop) => (event) => {
-        setLoginValues({ ...loginValues, [prop]: event.target.value });
-    };
-
-    const closeModal = () => {
-        setShowPasswordErrorModal(false);
-    };
-
-    return (
-        <>
-            <div className="lottie-background">
-                <Lottie options={defaultOptions} height="100%" width="100%" />
-            </div>
-            <div className="page page--login" data-page="login">
-                <div className="login">
-                    <div className="login__content">   
-                        <h2 className="login__title">Login</h2>
-                        <div className="login-form">
-                            <form id="LoginForm" onSubmit={loginAccount}>
-                                <div className="login-form__row">
-                                    <label 
className="login-form__label">Password</label>
-                                    <Input
-                                        type={loginValues.showPassword ? 
"text" : "password"}
-                                        
onChange={handlePasswordChange("password")}
-                                        placeholder="Password"
-                                        className="login-form__input"
-                                        value={loginValues.password}
-                                        style={{color: 'white', width: '100%'}}
-                                        disableUnderline
-                                        required
-                                        endAdornment={
-                                            <InputAdornment position="end">
-                                                <IconButton
-                                                    
onClick={handleClickShowPassword}
-                                                    
onMouseDown={handleMouseDownPassword}
-                                                    style={{color: 'white'}}
-                                                >
-                                                    {loginValues.showPassword 
? <Visibility /> : <VisibilityOff />}
-                                                </IconButton>
-                                            </InputAdornment>
-                                        }
-                                    />
-                                </div>
-                                <div className="login-form__row">
-                                    <button disabled={!loginValues.password} 
className="login-form__submit button button--main button--full" type="submit">
-                                        Login
-                                    </button>
-                                </div>
-                            </form>
-                            <div className="login-form__bottom">
-                                <p>
-                                    Delete current account? <br />
-                                    <button style={{color: '#47e7ce', 
fontWeight: '600', fontSize: '1.2rem', background: 'transparent', border: 
'none', outline: 'none', cursor: 'pointer'}} onClick={removeAccount}>
-                                        Remove Account
-                                    </button>
-                                </p>
-                            </div>
-                            <p className="bottom-navigation" 
style={{backgroundColor: 'transparent', display: 'flex', justifyContent: 
'center', textShadow: '1px 1px 1px rgba(0, 0, 0, 0.3)', color: 'rgb(255, 255, 
255, 0.5)', fontSize: '9px'}}>
-                                ResVault v{versionData.version}
-                            </p>
-                        </div>
-                    </div>
+                  />
                 </div>
+                <div className="login-form__row">
+                  <button
+                    disabled={!loginValues.password}
+                    className="login-form__submit button button--main 
button--full"
+                    type="submit"
+                  >
+                    Login
+                  </button>
+                </div>
+              </form>
+              <div className="login-form__bottom">
+                <p>
+                  Delete current account? <br />
+                  <button
+                    style={{
+                      color: '#47e7ce',
+                      fontWeight: '600',
+                      fontSize: '1.2rem',
+                      background: 'transparent',
+                      border: 'none',
+                      outline: 'none',
+                      cursor: 'pointer',
+                    }}
+                    onClick={removeAccount}
+                  >
+                    Remove Account
+                  </button>
+                </p>
+              </div>
+              <p
+                className="bottom-navigation"
+                style={{
+                  backgroundColor: 'transparent',
+                  display: 'flex',
+                  justifyContent: 'center',
+                  textShadow: '1px 1px 1px rgba(0, 0, 0, 0.3)',
+                  color: 'rgb(255, 255, 255, 0.5)',
+                  fontSize: '9px',
+                }}
+              >
+                ResVault v{versionData.version}
+              </p>
+            </div>
+          </div>
+        </div>
 
-                {showPasswordErrorModal && (
-                    <div className="modal-overlay">
-                        <div className="modal">
-                            <h2>Password Incorrect!</h2>
-                            <p>Please check your password and try again.</p>
-                            <button className="button button--main 
button--full" onClick={closeModal}>
-                                OK
-                            </button>
-                        </div>
-                    </div>
-                )}
+        {showPasswordErrorModal && (
+          <div className="modal-overlay">
+            <div className="modal">
+              <h2>Password Incorrect!</h2>
+              <p>Please check your password and try again.</p>
+              <button className="button button--main button--full" 
onClick={closeModal}>
+                OK
+              </button>
             </div>
-        </>
-    );
+          </div>
+        )}
+      </div>
+    </>
+  );
 }
 
 export default Login;
\ No newline at end of file
diff --git a/src/pages/SignUp.jsx b/src/pages/SignUp.jsx
index b2ca816..1301621 100644
--- a/src/pages/SignUp.jsx
+++ b/src/pages/SignUp.jsx
@@ -1,23 +1,3 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-* 
-*   http://www.apache.org/licenses/LICENSE-2.0
-* 
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied.  See the License for the
-* specific language governing permissions and limitations
-* under the License.    
-*/
-
-
 /*global chrome*/
 import '../css/App.css';
 import CryptoJS from "crypto-js";
@@ -26,20 +6,28 @@ import Visibility from "@material-ui/icons/Visibility";
 import InputAdornment from "@material-ui/core/InputAdornment";
 import VisibilityOff from "@material-ui/icons/VisibilityOff";
 import Input from "@material-ui/core/Input";
-import Base58 from 'bs58';
-import nacl from 'tweetnacl';
 import PasswordStrengthBar from 'react-password-strength-bar';
 import backicon from "../images/icons/arrow-back.svg";
-import React, { useContext, useState } from 'react';
+import React, { useContext, useState, useEffect } from 'react'; // Note the 
import of useEffect
 import Lottie from 'react-lottie';
 import versionData from '../data/version.json';
 import { useNavigate } from 'react-router-dom';
 import { GlobalContext } from '../context/GlobalContext';
 
 function SignUp() {
-    const { values, setValues, confirmValues, setConfirmValues, setPublicKey, 
setPrivateKey } = useContext(GlobalContext);
+    const {
+        values,
+        setValues,
+        confirmValues,
+        setConfirmValues,
+        generateKeyPair,
+        setIsAuthenticated,
+        setStoredPassword,
+        storedPassword,
+    } = useContext(GlobalContext);
     const navigate = useNavigate();
     const [showPasswordMismatchModal, setShowPasswordMismatchModal] = 
useState(false);
+    const [shouldGenerateKeyPair, setShouldGenerateKeyPair] = useState(false);
 
     const defaultOptions = {
         loop: true,
@@ -47,7 +35,7 @@ function SignUp() {
         animationData: require('../images/signup.json'),
         rendererSettings: {
             preserveAspectRatio: 'xMidYMid slice',
-            renderer: 'svg'  
+            renderer: 'svg'
         }
     };
 
@@ -63,43 +51,30 @@ function SignUp() {
         outline: 'none',
     };
 
-    function generateKeyPair() {
-        const keyPair = nacl.sign.keyPair();
-        const pk = Base58.encode(keyPair.publicKey);
-        const sk = Base58.encode(keyPair.secretKey.slice(0, 32));
-        return { publicKey: pk, privateKey: sk };
-    };
-
     const createAccount = async (e) => {
         e.preventDefault();
         if (values.password === confirmValues.password) {
-            chrome.storage.sync.clear(async function () {
-                const keys = generateKeyPair();
-                const publicKey = keys.publicKey;
-                const privateKey = keys.privateKey;
-                const encryptedPrivateKey = CryptoJS.AES.encrypt(
-                    JSON.stringify(privateKey),
-                    values.password
-                ).toString();
-
-                const hash = 
CryptoJS.SHA256(values.password).toString(CryptoJS.enc.Hex);
-                const store = { publicKey, encryptedPrivateKey, hash };
-                const password = { password: values.password };
-
-                chrome.storage.local.set({ password }, () => {});
-
-                store.history = [];
-                chrome.storage.sync.set({ store }, () => {
-                    setPublicKey(publicKey);
-                    setPrivateKey(privateKey);
-                    navigate("/dashboard");
-                });
+            const password = values.password;
+            // Store password
+            chrome.storage.local.set({ password }, () => {
+                setStoredPassword(password);
+                setShouldGenerateKeyPair(true);
             });
         } else {
             setShowPasswordMismatchModal(true);
         }
     };
 
+    useEffect(() => {
+        if (shouldGenerateKeyPair && storedPassword) {
+            generateKeyPair(() => {
+                setIsAuthenticated(true);
+                navigate("/dashboard");
+            });
+            setShouldGenerateKeyPair(false);
+        }
+    }, [shouldGenerateKeyPair, storedPassword, generateKeyPair, 
setIsAuthenticated, navigate]);
+
     const handleClickShowPassword = () => {
         setValues({ ...values, showPassword: !values.showPassword });
     };


Reply via email to