import React, { useEffect, useMemo, useState } from 'react'; import { Alert, Image, ScrollView, View } from 'react-native'; import { ActivityIndicator, Button, Text } from 'react-native-paper'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp, NativeStackScreenProps, } from '@react-navigation/native-stack'; import { Account, StackParamsList } from '../types'; import AccountDetails from './AccountDetails'; import styles from '../styles/stylesheet'; import { signMessage } from '../utils/sign-message'; import { retrieveSingleAccount } from '../utils/accounts'; import { approveWalletConnectRequest, rejectEIP155Request, } from '../utils/wallet-connect/WalletConnectRequests'; import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { useWalletConnect } from '../context/WalletConnectContext'; type SignRequestProps = NativeStackScreenProps; const SignRequest = ({ route }: SignRequestProps) => { const { requestSession } = useWalletConnect(); const requestName = requestSession?.peer?.metadata?.name; const requestIcon = requestSession?.peer?.metadata?.icons[0]; const requestURL = requestSession?.peer?.metadata?.url; const [account, setAccount] = useState(); const [message, setMessage] = useState(''); const [network, setNetwork] = useState(''); const [isLoading, setIsLoading] = useState(true); const navigation = useNavigation>(); const isCosmosSignDirect = useMemo(() => { const requestParams = route.params!.requestEvent.params.request; return requestParams.method === 'cosmos_signDirect'; }, [route.params]); const retrieveData = async ( requestNetwork: string, requestAddress: string, requestMessage: string, ) => { const requestAccount = await retrieveSingleAccount( requestNetwork, requestAddress, ); if (!requestAccount) { navigation.navigate('InvalidPath'); return; } if (requestAccount !== account) { setAccount(requestAccount); } if (requestMessage !== message) { setMessage(decodeURIComponent(requestMessage)); } if (requestNetwork !== network) { setNetwork(requestNetwork); } setIsLoading(false); }; const sanitizePath = (path: string) => { const regex = /^\/sign\/(eth|cosmos)\/(.+)\/(.+)$/; const match = path.match(regex); if (match) { const [network, address, message] = match; return { network, address, message, }; } else { navigation.navigate('InvalidPath'); } return null; }; useEffect(() => { if (route.path) { const sanitizedRoute = sanitizePath(route.path); sanitizedRoute && route.params && retrieveData( route.params?.network, route.params?.address, route.params?.message, ); return; } route.params && retrieveData( route.params?.network, route.params?.address, route.params?.message, ); }, [route]); const handleWalletConnectRequest = async () => { const { requestEvent } = route.params || {}; if (!account) { throw new Error('account not found'); } const response = await approveWalletConnectRequest( requestEvent, account, network, message, ); const { topic } = requestEvent; await web3wallet.respondSessionRequest({ topic, response }); }; const handleIntent = async () => { if (!account) { throw new Error('Account is not valid'); } if (message) { const signedMessage = await signMessage({ message, network, accountId: account.counterId, }); Alert.alert('Signature', signedMessage); } }; const signMessageHandler = async () => { if (route.params?.requestEvent) { await handleWalletConnectRequest(); } else { await handleIntent(); } navigation.navigate('Laconic'); }; const rejectRequestHandler = async () => { if (route.params?.requestEvent) { const response = rejectEIP155Request(route.params?.requestEvent); const { topic } = route.params?.requestEvent; await web3wallet.respondSessionRequest({ topic, response, }); } navigation.navigate('Laconic'); }; return ( <> {isLoading ? ( ) : ( {requestIcon && ( )} {requestName} {requestURL} {isCosmosSignDirect ? ( {message} ) : ( {message} )} )} ); }; export default SignRequest;