import { useEffect, useCallback } from 'react'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useAccounts } from '../context/AccountsContext'; import { useNetworks } from '../context/NetworksContext'; import { StackParamsList } from '../types'; import useGetOrCreateAccounts from './useGetOrCreateAccounts'; import { retrieveAccountsForNetwork } from '../utils/accounts'; export const useWebViewHandler = () => { // Navigation and context hooks const navigation = useNavigation>(); const { selectedNetwork } = useNetworks(); const { accounts, currentIndex } = useAccounts(); // Initialize accounts useGetOrCreateAccounts(); // Core navigation handler const navigateToSignRequest = useCallback((message: string) => { try { // Validation checks if (!selectedNetwork?.namespace || !selectedNetwork?.chainId) { window.Android?.onSignatureError?.('Invalid network configuration'); return; } if (!accounts?.length) { window.Android?.onSignatureError?.('No accounts available'); return; } const currentAccount = accounts[currentIndex]; if (!currentAccount) { window.Android?.onSignatureError?.('Current account not found'); return; } // Create the path and validate with regex const path = `/sign/${selectedNetwork.namespace}/${selectedNetwork.chainId}/${currentAccount.address}/${encodeURIComponent(message)}`; const pathRegex = /^\/sign\/(eip155|cosmos)\/(.+)\/(.+)\/(.+)$/; const match = path.match(pathRegex); if (!match) { window.Android?.onSignatureError?.('Invalid signing path'); return; } const [, pathNamespace, pathChainId, pathAddress, pathMessage] = match; // Reset navigation stack and navigate to sign request navigation.reset({ index: 0, routes: [ { name: 'SignRequest', path, params: { namespace: pathNamespace, chainId: pathChainId, address: pathAddress, message: decodeURIComponent(pathMessage), accountInfo: currentAccount, }, }, ], }); } catch (error) { window.Android?.onSignatureError?.(`Navigation error: ${error}`); } }, [selectedNetwork, accounts, currentIndex, navigation]); // Handle incoming transfer requests const navigateToTransfer = useCallback(async (to: string, amount: string, namespace: String, chainId: string) => { const chainSpecs = { namespace, chainId, }; try { // Get all accounts const chainAccounts = await retrieveAccountsForNetwork( `${chainSpecs.namespace}:${chainSpecs.chainId}`, '0' // Use the first account ); if (!chainAccounts || chainAccounts.length === 0) { console.error('Accounts not found'); if (window.Android?.onTransferError) { window.Android.onTransferError('Accounts not found'); } return; } const chainAccount = chainAccounts[0]; // Use the first account const path = `/transfer/${chainSpecs.namespace}/${chainSpecs.chainId}/${chainAccount.address}/${to}/${amount}`; navigation.reset({ index: 0, routes: [ { name: 'ApproveTransfer', path: path, params: { namespace: chainSpecs.namespace, chainId: `${chainSpecs.namespace}:${chainSpecs.chainId}`, transaction: { from: chainAccount.address, to: to, value: amount, data: '' }, accountInfo: chainAccount, }, }, ], }); } catch (error) { console.error('Navigation error:', error); if (window.Android?.onTransferError) { window.Android.onTransferError(`Navigation error: ${error}`); } } }, [navigation]); useEffect(() => { // Assign the function to the window object window.receiveSignRequestFromAndroid = navigateToSignRequest; window.receiveTransferRequestFromAndroid = navigateToTransfer; return () => { window.receiveSignRequestFromAndroid = undefined; window.receiveTransferRequestFromAndroid = undefined; }; }, [navigateToSignRequest, navigateToTransfer]); // Only the function reference as dependency };