From 17cb1156d7e3098aaf03968c764aff872bd4dbc1 Mon Sep 17 00:00:00 2001 From: pranavjadhav007 Date: Mon, 4 Aug 2025 17:14:49 +0530 Subject: [PATCH 1/2] Add Android encrypted storage support --- src/global.d.ts | 12 ++++++++++++ src/hooks/useWebViewHandler.ts | 16 +++++++++++----- src/utils/key-store.ts | 25 ++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/global.d.ts b/src/global.d.ts index c691cf7..501f4a0 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -3,6 +3,18 @@ declare global { interface Window { // Android bridge callbacks for signature and accounts related events Android?: { + // Check if running in Android WebView environment + isAndroidWebView(): boolean; + + // Store a key-value pair securely in encrypted storage + setItem(key: string, value: string): boolean; + + // Retrieve a value by key from encrypted storage + getItem(key: string): string | null; + + // Remove a key-value pair from encrypted storage + removeItem(key: string): boolean; + // Called when signature is successfully generated onSignatureComplete?: (signature: string) => void; diff --git a/src/hooks/useWebViewHandler.ts b/src/hooks/useWebViewHandler.ts index b306a8f..c5c44d4 100644 --- a/src/hooks/useWebViewHandler.ts +++ b/src/hooks/useWebViewHandler.ts @@ -8,6 +8,7 @@ import { useNetworks } from '../context/NetworksContext'; import { StackParamsList } from '../types'; import useGetOrCreateAccounts from './useGetOrCreateAccounts'; import { retrieveAccountsForNetwork, createWallet, retrieveNetworksData, isWalletCreated } from '../utils/accounts'; +import { getInternetCredentials } from '../utils/key-store'; export const useWebViewHandler = () => { // Navigation and context hooks @@ -46,12 +47,9 @@ export const useWebViewHandler = () => { return; } - // Create wallet using the provided mnemonic if it doesn't exist + // Check if wallet exists and if account data exists for the requested network const walletExists = await isWalletCreated(); - if (!walletExists) { - await createWallet(networksData, mnemonic); - } - + // Find the requested network const requestedNetwork = networksData.find(network => network.chainId === chainId); if (!requestedNetwork) { @@ -59,6 +57,14 @@ export const useWebViewHandler = () => { return; } + // Check if account data exists for this network + const accountKey = `accounts/${requestedNetwork.namespace}:${requestedNetwork.chainId}/0`; + const accountData = await getInternetCredentials(accountKey); + + if (!walletExists || !accountData) { + await createWallet(networksData, mnemonic); + } + // Update networks context setNetworksData(networksData); setSelectedNetwork(requestedNetwork); diff --git a/src/utils/key-store.ts b/src/utils/key-store.ts index f71fdff..d096aec 100644 --- a/src/utils/key-store.ts +++ b/src/utils/key-store.ts @@ -1,13 +1,32 @@ +// Check if running in Android WebView with secure storage available +const isAndroidSecureStorageAvailable = (): boolean => { + return typeof window !== 'undefined' && + window.Android !== undefined && + window.Android.isAndroidWebView(); +}; + const setInternetCredentials = (name:string, username:string, password:string) => { - localStorage.setItem(name, password); + if (isAndroidSecureStorageAvailable()) { + window.Android!.setItem(name, password); + } else { + localStorage.setItem(name, password); + } }; const getInternetCredentials = (name:string) : string | null => { - return localStorage.getItem(name); + if (isAndroidSecureStorageAvailable()) { + return window.Android!.getItem(name); + } else { + return localStorage.getItem(name); + } }; const resetInternetCredentials = (name:string) => { - localStorage.removeItem(name); + if (isAndroidSecureStorageAvailable()) { + window.Android!.removeItem(name); + } else { + localStorage.removeItem(name); + } }; export { -- 2.45.2 From 52d6dfe200b2204786659afb1e1ddd0cc7f9d7ea Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 19 Aug 2025 14:49:22 +0530 Subject: [PATCH 2/2] Handle webView Java bridge undefined values --- package.json | 2 +- src/global.d.ts | 3 --- src/hooks/useWebViewHandler.ts | 20 +++++++------------- src/utils/key-store.ts | 22 +++++++++------------- 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index fcf0e1c..8a8f495 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "web-wallet", - "version": "0.1.7-nym-0.1.2", + "version": "0.1.7-nym-0.1.3", "private": true, "dependencies": { "@cerc-io/registry-sdk": "^0.2.5", diff --git a/src/global.d.ts b/src/global.d.ts index 501f4a0..8800b97 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -3,9 +3,6 @@ declare global { interface Window { // Android bridge callbacks for signature and accounts related events Android?: { - // Check if running in Android WebView environment - isAndroidWebView(): boolean; - // Store a key-value pair securely in encrypted storage setItem(key: string, value: string): boolean; diff --git a/src/hooks/useWebViewHandler.ts b/src/hooks/useWebViewHandler.ts index c5c44d4..2825764 100644 --- a/src/hooks/useWebViewHandler.ts +++ b/src/hooks/useWebViewHandler.ts @@ -8,7 +8,6 @@ import { useNetworks } from '../context/NetworksContext'; import { StackParamsList } from '../types'; import useGetOrCreateAccounts from './useGetOrCreateAccounts'; import { retrieveAccountsForNetwork, createWallet, retrieveNetworksData, isWalletCreated } from '../utils/accounts'; -import { getInternetCredentials } from '../utils/key-store'; export const useWebViewHandler = () => { // Navigation and context hooks @@ -41,15 +40,18 @@ export const useWebViewHandler = () => { try { // Get available networks data const networksData = await retrieveNetworksData(); - + if (!networksData || networksData.length === 0) { window.Android?.onAccountError?.('No networks configured'); return; } - - // Check if wallet exists and if account data exists for the requested network + + // Create wallet using the provided mnemonic if it doesn't exist const walletExists = await isWalletCreated(); - + if (!walletExists) { + await createWallet(networksData, mnemonic); + } + // Find the requested network const requestedNetwork = networksData.find(network => network.chainId === chainId); if (!requestedNetwork) { @@ -57,14 +59,6 @@ export const useWebViewHandler = () => { return; } - // Check if account data exists for this network - const accountKey = `accounts/${requestedNetwork.namespace}:${requestedNetwork.chainId}/0`; - const accountData = await getInternetCredentials(accountKey); - - if (!walletExists || !accountData) { - await createWallet(networksData, mnemonic); - } - // Update networks context setNetworksData(networksData); setSelectedNetwork(requestedNetwork); diff --git a/src/utils/key-store.ts b/src/utils/key-store.ts index d096aec..f19ba5c 100644 --- a/src/utils/key-store.ts +++ b/src/utils/key-store.ts @@ -1,29 +1,25 @@ -// Check if running in Android WebView with secure storage available -const isAndroidSecureStorageAvailable = (): boolean => { - return typeof window !== 'undefined' && - window.Android !== undefined && - window.Android.isAndroidWebView(); -}; - const setInternetCredentials = (name:string, username:string, password:string) => { - if (isAndroidSecureStorageAvailable()) { - window.Android!.setItem(name, password); + if (window.Android?.setItem) { + window.Android.setItem(name, password); } else { localStorage.setItem(name, password); } }; const getInternetCredentials = (name:string) : string | null => { - if (isAndroidSecureStorageAvailable()) { - return window.Android!.getItem(name); + if (window.Android?.getItem) { + const result = window.Android.getItem(name); + + // Normalize undefined to null to match localStorage behavior + return result === undefined ? null : result; } else { return localStorage.getItem(name); } }; const resetInternetCredentials = (name:string) => { - if (isAndroidSecureStorageAvailable()) { - window.Android!.removeItem(name); + if (window.Android?.removeItem) { + window.Android.removeItem(name); } else { localStorage.removeItem(name); } -- 2.45.2