laconic-wallet/components/SignRequest.tsx
shreerang6921 9ab8c2ce4f
Display details coming from dapp in sign request page (#44)
* Add qr-code scanner button in homescreen header

* Display dapp details on sign request page

* Center details coming from dapp

* Remove request event state from request context
2024-03-07 16:02:35 +05:30

194 lines
5.1 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { Alert, Image, 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 {
approveEIP155Request,
rejectEIP155Request,
} from '../utils/wallet-connect/EIP155Requests';
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
import { useRequests } from '../context/RequestContext';
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
const SignRequest = ({ route }: SignRequestProps) => {
const { requestSession } = useRequests();
const requestName = requestSession?.peer?.metadata?.name;
const requestIcon = requestSession?.peer?.metadata?.icons[0];
const requestURL = requestSession?.peer?.metadata?.url;
const [account, setAccount] = useState<Account>();
const [message, setMessage] = useState<string>('');
const [network, setNetwork] = useState<string>('');
const [isLoading, setIsLoading] = useState(true);
const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>();
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 handleEIP155Request = async () => {
const { requestEvent } = route.params || {};
if (!account) {
throw new Error('account not found');
}
const response = await approveEIP155Request(
requestEvent,
account.counterId,
);
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 handleEIP155Request();
} 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 ? (
<View style={styles.spinnerContainer}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
) : (
<View style={styles.appContainer}>
<View style={styles.dappDetails}>
<Image
style={styles.dappLogo}
source={{
uri: requestIcon,
}}
/>
<Text>{requestName}</Text>
<Text variant="bodyMedium">{requestURL}</Text>
</View>
<AccountDetails account={account} />
<View style={styles.requestMessage}>
<Text variant="bodyLarge">{message}</Text>
</View>
<View style={styles.buttonContainer}>
<Button mode="contained" onPress={signMessageHandler}>
Yes
</Button>
<Button
mode="contained"
onPress={rejectRequestHandler}
buttonColor="#B82B0D">
No
</Button>
</View>
</View>
)}
</>
);
};
export default SignRequest;