forked from cerc-io/laconic-wallet
* 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
194 lines
5.1 KiB
TypeScript
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;
|