laconic-wallet/components/SignRequest.tsx
Adwait Gharpure 05be6008de
Use page for handling sign requests (#42)
* Use sign request page instead of modal

* Fix context

* Remove multiple if statements

* Change metadata

* Remove sign modal

* Make review changes

* Remove state

---------

Co-authored-by: Adw8 <adwait@deepstacksoft.com>
2024-03-07 12:44:05 +05:30

170 lines
4.5 KiB
TypeScript

import React, { useContext, useEffect, useState } from 'react';
import { Alert, 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';
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
const SignRequest = ({ route }: SignRequestProps) => {
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 && requestAccount !== account) {
setAccount(requestAccount);
}
if (requestMessage && requestMessage !== message) {
setMessage(decodeURIComponent(requestMessage));
}
if (requestNetwork && requestNetwork !== network) {
setNetwork(requestNetwork);
}
};
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,
);
setIsLoading(false);
}, [route]);
const handleEIP155Request = async () => {
const { requestEvent } = route.params || {};
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 ? (
<ActivityIndicator />
) : (
<View style={styles.appContainer}>
<AccountDetails account={account} />
<View style={styles.requestMessage}>
<Text variant="bodyLarge">{message}</Text>
</View>
<View style={styles.buttonContainer}>
<Button
mode="contained"
onPress={rejectRequestHandler}
buttonColor="#B82B0D">
No
</Button>
<Button mode="contained" onPress={signMessageHandler}>
Yes
</Button>
</View>
</View>
)}
</>
);
};
export default SignRequest;