diff --git a/src/global.d.ts b/src/global.d.ts index 8b3e401..c4ef4a9 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -29,7 +29,7 @@ declare global { receiveSignRequestFromAndroid?: (message: string) => void; // Handles incoming transfer requests from Android - receiveTransferRequestFromAndroid?: (to: string, amount: string, namespace: String, chainId: string, addressPrefix: String) => void; + receiveTransferRequestFromAndroid?: (to: string, amount: string, namespace: String, chainId: string) => void; } } diff --git a/src/hooks/useWebViewHandler.ts b/src/hooks/useWebViewHandler.ts index b64f337..50d873b 100644 --- a/src/hooks/useWebViewHandler.ts +++ b/src/hooks/useWebViewHandler.ts @@ -75,20 +75,10 @@ export const useWebViewHandler = () => { }, [selectedNetwork, accounts, currentIndex, navigation]); // Handle incoming transfer requests - const navigateToTransfer = useCallback(async (to: string, amount: string, namespace: String, chainId: string, addressPrefix: String) => { - if (!accounts || accounts.length === 0) { - console.error('No accounts available'); - if (window.Android?.onTransferError) { - window.Android.onTransferError('No accounts available'); - } - - return; - } - + const navigateToTransfer = useCallback(async (to: string, amount: string, namespace: String, chainId: string) => { const chainSpecs = { namespace, chainId, - addressPrefix }; try { @@ -137,7 +127,7 @@ export const useWebViewHandler = () => { window.Android.onTransferError(`Navigation error: ${error}`); } } - }, [accounts, navigation]); + }, [navigation]); useEffect(() => { // Assign the function to the window object diff --git a/src/screens/ApproveTransfer.tsx b/src/screens/ApproveTransfer.tsx index 5589ccd..4169e0b 100644 --- a/src/screens/ApproveTransfer.tsx +++ b/src/screens/ApproveTransfer.tsx @@ -53,12 +53,12 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { const { web3wallet } = useWalletConnect(); // Extract data from route params or path - const requestSession = route.params.requestSessionData ?? null; + const requestSession = route.params.requestSessionData; const requestName = requestSession?.peer.metadata.name; const requestIcon = requestSession?.peer.metadata.icons?.[0]; const requestURL = requestSession?.peer.metadata.url; const transaction = route.params.transaction; - const requestEvent = route.params.requestEvent ?? null; + const requestEvent = route.params.requestEvent; const chainId = requestEvent?.params.chainId || route.params.chainId; const requestMethod = requestEvent?.params.request.method; @@ -186,24 +186,6 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { const navigation = useNavigation>(); - const sanitizePath = useCallback((path: string) => { - const regex = /^\/transfer\/(eip155|cosmos)\/(.+)\/(.+)\/(.+)\/(.+)$/; - const match = path.match(regex); - if (match) { - const [, pathNamespace, pathChainId, pathAddress, pathTo, pathAmount] = match; - return { - namespace: pathNamespace, - chainId: pathChainId, - address: pathAddress, - to: pathTo, - amount: pathAmount, - }; - } else { - navigation.navigate('InvalidPath'); - } - return null; - }, [navigation]); - const retrieveData = useCallback( async (requestAddress: string) => { const requestAccount = await retrieveSingleAccount( @@ -221,6 +203,47 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { [navigation, requestedNetwork], ); + const handleIntent = async () => { + if (!account) { + throw new Error('Account is not valid'); + } + + if (!requestedNetwork) { + throw new Error('Network not found'); + } + + if (!cosmosStargateClient) { + throw new Error('Cosmos stargate client not found'); + } + + const result = await cosmosStargateClient.signAndBroadcast( + account.address, + [sendMsg], + { + amount: [ + { + amount: fees, + denom: requestedNetwork.nativeDenom!, + }, + ], + gas: cosmosGasLimit, + }, + MEMO, + ); + + // Convert BigInt values to strings before sending to Android + const serializedResult = JSON.stringify(result, (key, value) => + typeof value === 'bigint' ? value.toString() : value + ); + + // Send the result back to Android and close dialog + if (window.Android?.onTransferComplete) { + window.Android.onTransferComplete(serializedResult); + } else { + alert(`Transaction: ${serializedResult}`); + } + }; + useEffect(() => { // Set loading to false when gas values for requested chain are fetched // If requested chain is EVM compatible, the cosmos gas values will be undefined and vice-versa, hence the condition checks only one of them at the same time @@ -277,101 +300,6 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { return false; }, [cosmosGasLimit, ethMaxFee, ethMaxPriorityFee]); - const handleIntent = async () => { - if (!account) { - throw new Error('Account is not valid'); - } - - if (route.path) { - const sanitizedRoute = sanitizePath(route.path); - if (!sanitizedRoute) { - throw new Error('Invalid path'); - } - - const requestedNetwork = networksData.find( - networkData => networkData.chainId === sanitizedRoute.chainId, - ); - - if (!requestedNetwork) { - throw new Error('Network not found'); - } - - const cosmosPrivKey = ( - await getPathKey( - `${requestedNetwork.namespace}:${requestedNetwork.chainId}`, - account.index, - ) - ).privKey; - - const sender = await DirectSecp256k1Wallet.fromKey( - Uint8Array.from(Buffer.from(cosmosPrivKey.split('0x')[1], 'hex')), - requestedNetwork.addressPrefix, - ); - - const client = await SigningStargateClient.connectWithSigner( - requestedNetwork.rpcUrl!, - sender, - ); - - const sendMsg: MsgSendEncodeObject = { - typeUrl: '/cosmos.bank.v1beta1.MsgSend', - value: { - fromAddress: account.address, - toAddress: sanitizedRoute.to, - amount: [ - { - amount: String(sanitizedRoute.amount), - denom: requestedNetwork.nativeDenom!, - }, - ], - }, - }; - - const gasEstimation = await client.simulate( - account.address, - [sendMsg], - MEMO, - ); - - const gasLimit = String( - Math.round(gasEstimation * Number(process.env.REACT_APP_GAS_ADJUSTMENT)), - ); - - const gasPrice = GasPrice.fromString( - requestedNetwork.gasPrice! + requestedNetwork.nativeDenom, - ); - - const cosmosFees = calculateFee(Number(gasLimit), gasPrice); - - const result = await client.signAndBroadcast( - account.address, - [sendMsg], - { - amount: [ - { - amount: cosmosFees.amount[0].amount, - denom: requestedNetwork.nativeDenom!, - }, - ], - gas: gasLimit, - }, - MEMO, - ); - - // Convert BigInt values to strings before sending to Android - const serializedResult = JSON.stringify(result, (key, value) => - typeof value === 'bigint' ? value.toString() : value - ); - - // Send the result back to Android and close dialog - if (window.Android?.onTransferComplete) { - window.Android.onTransferComplete(serializedResult); - } else { - alert(`Transaction: ${serializedResult}`); - } - } - }; - const acceptRequestHandler = async () => { setIsTxLoading(true); try { @@ -449,7 +377,6 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { await web3wallet!.respondSessionRequest({ topic, response }); navigation.navigate('Home'); } else { - // Handle direct intent await handleIntent(); navigation.navigate('Home'); } @@ -484,7 +411,7 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { useEffect(() => { const getAccountBalance = async () => { try { - if (!account || !requestedNetwork) { + if (!account) { return; } if (namespace === EIP155) { @@ -494,20 +421,20 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { const fetchedBalance = await provider.getBalance(account.address); setBalance(fetchedBalance ? fetchedBalance.toString() : '0'); } else { - if (!cosmosStargateClient) { - return; - } - const cosmosBalance = await cosmosStargateClient.getBalance( + const cosmosBalance = await cosmosStargateClient?.getBalance( account.address, - requestedNetwork.nativeDenom!.toLowerCase(), + requestedNetwork!.nativeDenom!.toLowerCase(), ); - setBalance(cosmosBalance?.amount || '0'); + + setBalance(cosmosBalance?.amount!); } } catch (error) { - console.error('Error fetching balance:', error); - setBalance('0'); - // Don't show error dialog for balance fetch failures - // Just set balance to 0 and let the transaction proceed + if (!(error instanceof Error)) { + throw error; + } + + setTxError(error.message); + setIsTxErrorDialogOpen(true); } }; @@ -651,7 +578,11 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => { label={`Balance (${ namespace === EIP155 ? 'wei' : requestedNetwork!.nativeDenom })`} - data={balance || '0'} + data={ + balance === '' || balance === undefined + ? 'Loading balance...' + : `${balance}` + } /> {transaction && (