Remove console logs

This commit is contained in:
AdityaSalunkhe21 2025-04-11 14:08:09 +05:30
parent 6ad37d0fa5
commit 3eedadafc3
6 changed files with 85 additions and 272 deletions

View File

@ -133,28 +133,16 @@ const App = (): React.JSX.Element => {
break; break;
case EIP155_SIGNING_METHODS.PERSONAL_SIGN: case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
const chainId = request.params.chainId?.split(':')[1];
const account = accounts.find(acc => acc.address === request.params[1]);
if (!account) {
throw new Error('Account not found');
}
navigation.navigate("SignRequest", { navigation.navigate("SignRequest", {
namespace: EIP155, namespace: EIP155,
chainId,
address: request.params[1], address: request.params[1],
message: getSignParamsMessage(request.params), message: getSignParamsMessage(request.params),
accountInfo: account,
requestEvent, requestEvent,
requestSessionData, requestSessionData,
}); });
break; break;
case COSMOS_METHODS.COSMOS_SIGN_DIRECT: case COSMOS_METHODS.COSMOS_SIGN_DIRECT:
const cosmosChainId = request.params.chainId?.split(':')[1];
const cosmosAccount = accounts.find(acc => acc.address === request.params.signerAddress);
if (!cosmosAccount) {
throw new Error('Account not found');
}
const message = { const message = {
txbody: TxBody.toJSON( txbody: TxBody.toJSON(
TxBody.decode( TxBody.decode(
@ -173,27 +161,18 @@ const App = (): React.JSX.Element => {
}; };
navigation.navigate("SignRequest", { navigation.navigate("SignRequest", {
namespace: COSMOS, namespace: COSMOS,
chainId: cosmosChainId,
address: request.params.signerAddress, address: request.params.signerAddress,
message: JSON.stringify(message, undefined, 2), message: JSON.stringify(message, undefined, 2),
accountInfo: cosmosAccount,
requestEvent, requestEvent,
requestSessionData, requestSessionData,
}); });
break; break;
case COSMOS_METHODS.COSMOS_SIGN_AMINO: case COSMOS_METHODS.COSMOS_SIGN_AMINO:
const aminoChainId = request.params.chainId?.split(':')[1];
const aminoAccount = accounts.find(acc => acc.address === request.params.signerAddress);
if (!aminoAccount) {
throw new Error('Account not found');
}
navigation.navigate("SignRequest", { navigation.navigate("SignRequest", {
namespace: COSMOS, namespace: COSMOS,
chainId: aminoChainId,
address: request.params.signerAddress, address: request.params.signerAddress,
message: request.params.signDoc.memo, message: request.params.signDoc.memo,
accountInfo: aminoAccount,
requestEvent, requestEvent,
requestSessionData, requestSessionData,
}); });
@ -228,7 +207,6 @@ const App = (): React.JSX.Element => {
setCurrentIndex, setCurrentIndex,
selectedNetwork, selectedNetwork,
web3wallet, web3wallet,
accounts,
], ],
); );
@ -277,7 +255,7 @@ const App = (): React.JSX.Element => {
).privKey; ).privKey;
const sender = await DirectSecp256k1Wallet.fromKey( const sender = await DirectSecp256k1Wallet.fromKey(
Uint8Array.from(Buffer.from(cosmosPrivKey.split('0x')[1], 'hex')), Buffer.from(cosmosPrivKey.split('0x')[1], 'hex'),
network.addressPrefix network.addressPrefix
); );

21
src/global.d.ts vendored
View File

@ -1,20 +1,29 @@
// Extends the Window interface for Android WebView communication
declare global { declare global {
interface Window { interface Window {
// Android bridge callbacks for signature-related events
Android?: { Android?: {
// Called when signature is successfully generated
onSignatureComplete?: (signature: string) => void; onSignatureComplete?: (signature: string) => void;
// Called when signature generation fails
onSignatureError?: (error: string) => void; onSignatureError?: (error: string) => void;
// Called when signature process is cancelled
onSignatureCancelled?: () => void; onSignatureCancelled?: () => void;
// Called when JS bridge is initialized
onJsBridgeReady?: () => void; onJsBridgeReady?: () => void;
// Called when accounts are ready for use
onAccountsReady?: () => void; onAccountsReady?: () => void;
}; };
// Android WebView bridge methods (from TimeDisplay)
receiveTimeFromAndroid?: (timestamp: number) => void; // Handles incoming signature requests from Android
receiveDataFromAndroid?: (data: string) => void;
receiveSignRequestFromAndroid?: (message: string) => void; receiveSignRequestFromAndroid?: (message: string) => void;
// Handles request to create or retrieve accounts
receiveCreateOrGetAccountsRequestFromAndroid?: () => void; receiveCreateOrGetAccountsRequestFromAndroid?: () => void;
// Android native bridge object (from useGetOrCreateAccount)
} }
} }

View File

@ -35,32 +35,8 @@ const useGetOrCreateAccounts = (onWalletCreated?: () => void) => {
); );
}; };
const autoCreateAccounts = async () => {
const defaultChainId = networksData[0]?.chainId;
if (!defaultChainId) return;
let accountsData = await getAccountsData(defaultChainId);
if (accountsData.length === 0) {
console.log("Auto-creating wallet...");
await createWallet(networksData);
accountsData = await getAccountsData(defaultChainId);
onWalletCreated?.();
}
// Notify Android that accounts are ready
if (window.Android?.onAccountsReady) {
window.Android.onAccountsReady();
}
};
window.addEventListener('message', handleCreateAccounts); window.addEventListener('message', handleCreateAccounts);
const isAndroidWebView = !!(window.Android);
if (isAndroidWebView) {
autoCreateAccounts();
}
return () => { return () => {
window.removeEventListener('message', handleCreateAccounts); window.removeEventListener('message', handleCreateAccounts);
}; };

View File

@ -1,141 +1,94 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useAccounts } from '../context/AccountsContext'; import { useAccounts } from '../context/AccountsContext';
import { useNetworks } from '../context/NetworksContext'; import { useNetworks } from '../context/NetworksContext';
import { StackParamsList } from '../types'; import { StackParamsList } from '../types';
import useGetOrCreateAccounts from './useGetOrCreateAccounts'; import useGetOrCreateAccounts from './useGetOrCreateAccounts';
/**
* Hook to manage sign request data state and Android bridge notifications
*/
export const useSignRequestData = () => { export const useSignRequestData = () => {
const { selectedNetwork } = useNetworks(); const { selectedNetwork } = useNetworks();
const { accounts, currentIndex } = useAccounts(); const { accounts, currentIndex } = useAccounts();
const [isDataReady, setIsDataReady] = useState(false); const [isDataReady, setIsDataReady] = useState(false);
useEffect(() => { useEffect(() => {
const logData = {
selectedNetwork: selectedNetwork ? {
namespace: selectedNetwork.namespace,
chainId: selectedNetwork.chainId,
} : 'undefined',
accounts: accounts ? `Array of length ${accounts.length}` : 'undefined',
currentIndex
};
console.log('Checking data readiness:', JSON.stringify(logData, null, 2));
if (selectedNetwork && accounts && accounts.length > 0) { if (selectedNetwork && accounts && accounts.length > 0) {
setIsDataReady(true); setIsDataReady(true);
// Notify Android that accounts are ready // Notify Android when accounts are ready for signing
if (window.Android?.onAccountsReady) { window.Android?.onAccountsReady?.();
window.Android.onAccountsReady();
}
} }
}, [selectedNetwork, accounts, currentIndex]); }, [selectedNetwork, accounts, currentIndex]);
return { isDataReady, selectedNetwork, accounts, currentIndex }; return { isDataReady, selectedNetwork, accounts, currentIndex };
}; };
/**
* Hook to handle navigation for sign requests with validation
*/
export const useSignRequestNavigation = () => { export const useSignRequestNavigation = () => {
const navigation = useNavigation<NativeStackNavigationProp<StackParamsList>>(); const navigation = useNavigation<NativeStackNavigationProp<StackParamsList>>();
const { isDataReady, selectedNetwork, accounts, currentIndex } = useSignRequestData(); const { isDataReady, selectedNetwork, accounts, currentIndex } = useSignRequestData();
const pendingMessageRef = useRef<string | null>(null); const pendingMessageRef = useRef<string | null>(null);
const navigateToSignRequest = useCallback(async (message: string) => { const navigateToSignRequest = useCallback(async (message: string) => {
const logData = { // Queue message if data isn't ready yet
isDataReady,
selectedNetwork: selectedNetwork ? {
namespace: selectedNetwork.namespace,
chainId: selectedNetwork.chainId,
} : 'undefined',
accounts: accounts ? `Array of length ${accounts.length}` : 'undefined',
currentIndex,
message
};
console.log('Attempting to navigate with data:', JSON.stringify(logData, null, 2));
if (!isDataReady) { if (!isDataReady) {
console.log('Delaying sign request until data is ready...');
pendingMessageRef.current = message; pendingMessageRef.current = message;
return; return;
} }
// Validate required data
if (!selectedNetwork) { if (!selectedNetwork) {
console.error('No network selected'); window.Android?.onSignatureError?.('No network selected');
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('No network selected');
}
return; return;
} }
if (!accounts || accounts.length === 0) { if (!accounts?.length) {
console.error('No accounts available'); window.Android?.onSignatureError?.('No accounts available');
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('No accounts available');
}
return; return;
} }
const currentAccount = accounts[currentIndex]; const currentAccount = accounts[currentIndex];
if (!currentAccount) { if (!currentAccount) {
console.error('Current account not found'); window.Android?.onSignatureError?.('Current account not found');
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('Current account not found');
}
return; return;
} }
// Verify network properties exist before using them // Validate network properties
if (!selectedNetwork.namespace || !selectedNetwork.chainId) { if (!selectedNetwork.namespace || !selectedNetwork.chainId) {
const errorData = { window.Android?.onSignatureError?.('Network missing required properties');
namespace: selectedNetwork.namespace,
chainId: selectedNetwork.chainId
};
console.error('Network missing required properties:', JSON.stringify(errorData, null, 2));
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('Network missing required properties');
}
return; return;
} }
const navigationData = {
namespace: selectedNetwork.namespace,
chainId: selectedNetwork.chainId,
address: currentAccount.address,
message
};
console.log('Navigating to SignRequest with:', JSON.stringify(navigationData, null, 2));
try { try {
// Ensure the path matches the expected regex pattern: /sign/(eip155|cosmos)/(.+)/(.+)/(.+) // Build and validate signing path
const path = `/sign/${selectedNetwork.namespace}/${selectedNetwork.chainId}/${currentAccount.address}/${encodeURIComponent(message)}`; const path = `/sign/${selectedNetwork.namespace}/${selectedNetwork.chainId}/${currentAccount.address}/${encodeURIComponent(message)}`;
// Verify the path matches the expected pattern
const pathRegex = /^\/sign\/(eip155|cosmos)\/(.+)\/(.+)\/(.+)$/; const pathRegex = /^\/sign\/(eip155|cosmos)\/(.+)\/(.+)\/(.+)$/;
if (!pathRegex.test(path)) { if (!pathRegex.test(path)) {
console.error('Path does not match expected pattern:', path); window.Android?.onSignatureError?.('Invalid path format');
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('Invalid path format');
}
return; return;
} }
// Parse the path to get the components
const match = path.match(pathRegex); const match = path.match(pathRegex);
if (!match) { if (!match) {
console.error('Failed to parse path:', path); window.Android?.onSignatureError?.('Failed to parse path');
if (window.Android?.onSignatureError) {
window.Android.onSignatureError('Failed to parse path');
}
return; return;
} }
const [, pathNamespace, pathChainId, pathAddress, pathMessage] = match; const [, pathNamespace, pathChainId, pathAddress, pathMessage] = match;
// Navigate to sign request screen
navigation.reset({ navigation.reset({
index: 0, index: 0,
routes: [ routes: [
{ {
name: 'SignRequest', name: 'SignRequest',
path: `/sign/${selectedNetwork.namespace}/${selectedNetwork.chainId}/${currentAccount.address}/${encodeURIComponent(message)}`, path,
params: { params: {
namespace: pathNamespace, namespace: pathNamespace,
chainId: pathChainId, chainId: pathChainId,
@ -147,14 +100,11 @@ export const useSignRequestNavigation = () => {
], ],
}); });
} catch (error) { } catch (error) {
console.error('Navigation error:', error); window.Android?.onSignatureError?.(`Navigation error: ${error}`);
if (window.Android?.onSignatureError) {
window.Android.onSignatureError(`Navigation error: ${error}`);
}
} }
}, [isDataReady, selectedNetwork, accounts, currentIndex, navigation]); }, [isDataReady, selectedNetwork, accounts, currentIndex, navigation]);
// Handle pending message when data becomes ready // Process any pending message when data becomes ready
useEffect(() => { useEffect(() => {
if (pendingMessageRef.current && isDataReady) { if (pendingMessageRef.current && isDataReady) {
const message = pendingMessageRef.current; const message = pendingMessageRef.current;
@ -166,28 +116,26 @@ export const useSignRequestNavigation = () => {
return { navigateToSignRequest }; return { navigateToSignRequest };
}; };
/**
* Hook to set up Android bridge communication
*/
export const useAndroidBridge = () => { export const useAndroidBridge = () => {
const { navigateToSignRequest } = useSignRequestNavigation(); const { navigateToSignRequest } = useSignRequestNavigation();
useEffect(() => { useEffect(() => {
// Handle sign requests from Android
window.receiveSignRequestFromAndroid = (message: string) => { window.receiveSignRequestFromAndroid = (message: string) => {
console.log('Sign request received with message:', message);
navigateToSignRequest(message); navigateToSignRequest(message);
}; };
// Handle create/get accounts request // Set up accounts request handler
window.receiveCreateOrGetAccountsRequestFromAndroid = () => { window.receiveCreateOrGetAccountsRequestFromAndroid = () => {
console.log('SignRequestHandler: Create/get accounts request received'); // Handled by useGetOrCreateAccounts hook
// The useGetOrCreateAccounts hook will handle this
}; };
// Initialize Android bridge
if (window.Android) { if (window.Android) {
setTimeout(() => { setTimeout(() => window.Android?.onJsBridgeReady?.(), 100);
console.log('SignRequestHandler: Calling onJsBridgeReady');
window.Android?.onJsBridgeReady?.();
}, 100);
} else {
console.log('SignRequestHandler: Android bridge is not available');
} }
return () => { return () => {
@ -197,6 +145,9 @@ export const useAndroidBridge = () => {
}, [navigateToSignRequest]); }, [navigateToSignRequest]);
}; };
/**
* Main hook that combines all sign request handling functionality
*/
export const useSignRequestHandler = () => { export const useSignRequestHandler = () => {
useGetOrCreateAccounts(); useGetOrCreateAccounts();
useSignRequestData(); useSignRequestData();

View File

@ -18,8 +18,6 @@ import { useNetworks } from "../context/NetworksContext";
import ImportWalletDialog from "../components/ImportWalletDialog"; import ImportWalletDialog from "../components/ImportWalletDialog";
import { MnemonicDialog } from "../components/MnemonicDialog"; import { MnemonicDialog } from "../components/MnemonicDialog";
import { Container } from "../components/Container"; import { Container } from "../components/Container";
import { useSignRequestHandler } from '../hooks/useSignRequestHandler';
import useGetOrCreateAccounts from '../hooks/useGetOrCreateAccounts';
import { IS_IMPORT_WALLET_ENABLED } from "../utils/constants"; import { IS_IMPORT_WALLET_ENABLED } from "../utils/constants";
const HomeScreen = () => { const HomeScreen = () => {
@ -66,20 +64,8 @@ const HomeScreen = () => {
setPhrase(mnemonic); setPhrase(mnemonic);
setSelectedNetwork(networksData[0]); setSelectedNetwork(networksData[0]);
} }
setIsWalletCreating(false);
}; };
const handleWalletCreated = useCallback(() => {
setIsWalletCreated(true);
fetchAccounts();
}, [fetchAccounts]);
useGetOrCreateAccounts(handleWalletCreated);
useEffect(() => {
fetchAccounts();
}, [networksData, setAccounts, selectedNetwork, fetchAccounts]);
const importWalletHandler = async (recoveryPhrase: string) => { const importWalletHandler = async (recoveryPhrase: string) => {
try { try {
const mnemonic = await createWallet(networksData, recoveryPhrase); const mnemonic = await createWallet(networksData, recoveryPhrase);
@ -128,7 +114,9 @@ const HomeScreen = () => {
setCurrentIndex(0); setCurrentIndex(0);
}; };
useSignRequestHandler(); useEffect(() => {
fetchAccounts();
}, [networksData, setAccounts, selectedNetwork, fetchAccounts]);
return ( return (
<View style={styles.appContainer}> <View style={styles.appContainer}>

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from "react"; import React, { useState } from "react";
import { Text, TextInput } from "react-native-paper"; import { Text, TextInput } from "react-native-paper";
import { Button, Divider, Stack, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; import { Button, Divider, Stack } from "@mui/material";
import { NativeStackScreenProps } from "@react-navigation/native-stack"; import { NativeStackScreenProps } from "@react-navigation/native-stack";
import { StackParamsList } from "../types"; import { StackParamsList } from "../types";
@ -10,82 +11,21 @@ import { Layout } from "../components/Layout";
type SignProps = NativeStackScreenProps<StackParamsList, "SignMessage">; type SignProps = NativeStackScreenProps<StackParamsList, "SignMessage">;
const SignMessage = ({ route, navigation }: SignProps) => { const SignMessage = ({ route }: SignProps) => {
const namespace = route.params.selectedNamespace; const namespace = route.params.selectedNamespace;
const chainId = route.params.selectedChainId; const chainId = route.params.selectedChainId;
const account = route.params.accountInfo; const account = route.params.accountInfo;
const prefillMessage = route.params.prefillMessage;
const [message, setMessage] = useState<string>(prefillMessage || ""); const [message, setMessage] = useState<string>("");
const [showConfirmDialog, setShowConfirmDialog] = useState<boolean>(false);
// If message is prefilled from Android, show the confirmation dialog immediately const signMessageHandler = async () => {
useEffect(() => {
if (prefillMessage) {
setMessage(prefillMessage);
// Show confirmation dialog immediately
setTimeout(() => {
setShowConfirmDialog(true);
}, 0);
}
}, [prefillMessage]);
const handleConfirmSignature = async () => {
try {
const signedMessage = await signMessage({ const signedMessage = await signMessage({
message, message,
namespace, namespace,
chainId, chainId,
accountId: account.index, accountId: account.index,
}); });
alert(`Signature ${signedMessage}`);
// Send the result back to Android and close dialog
if (window.Android?.onSignatureComplete) {
window.Android.onSignatureComplete(signedMessage || "");
} else {
alert(`Signature: ${signedMessage}`);
}
setShowConfirmDialog(false);
// If this was opened from Android, we should return
if (prefillMessage && window.Android) {
// Return to previous screen if applicable
if (navigation.canGoBack()) {
navigation.goBack();
}
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
// Send error back to Android
if (window.Android?.onSignatureError) {
window.Android.onSignatureError(errorMessage);
} else {
alert(`Error: ${errorMessage}`);
}
setShowConfirmDialog(false);
}
};
const handleCancelSignature = () => {
setShowConfirmDialog(false);
if (window.Android?.onSignatureCancelled) {
window.Android.onSignatureCancelled();
}
// If this was opened from Android, we should return
if (prefillMessage && window.Android) {
// Return to previous screen if applicable
if (navigation.canGoBack()) {
navigation.goBack();
}
}
};
const showSignConfirmation = () => {
setShowConfirmDialog(true);
}; };
return ( return (
@ -104,43 +44,14 @@ const SignMessage = ({ route, navigation }: SignProps) => {
value={message} value={message}
/> />
<Stack direction="row" spacing={2}>
<Button <Button
variant="contained" variant="contained"
onClick={showSignConfirmation} onClick={signMessageHandler}
sx={{ width: "200px", px: 4, py: 1, mt: 2 }} sx={{ width: "200px", px: 4, py: 1, mt: 2 }}
> >
Sign Sign
</Button> </Button>
<Button
variant="outlined"
onClick={handleCancelSignature}
sx={{ width: "200px", px: 4, py: 1, mt: 2 }}
>
Cancel
</Button>
</Stack> </Stack>
</Stack>
<Dialog
open={showConfirmDialog}
onClose={handleCancelSignature}
>
<DialogTitle>Confirm Signature</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to sign the following message?
</DialogContentText>
<DialogContentText sx={{ mt: 2, p: 2, backgroundColor: '#f5f5f5', borderRadius: 1, color: 'black' }}>
{message}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCancelSignature} variant="outlined">No, Cancel</Button>
<Button onClick={handleConfirmSignature} variant="contained" autoFocus>Yes, Sign</Button>
</DialogActions>
</Dialog>
</Layout> </Layout>
); );
}; };