forked from cerc-io/laconic-wallet
227 lines
6.7 KiB
TypeScript
227 lines
6.7 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { Image, View, Modal } from 'react-native';
|
|
import { Button, Text } from 'react-native-paper';
|
|
|
|
import { SessionTypes } from '@walletconnect/types';
|
|
import { getSdkError } from '@walletconnect/utils';
|
|
|
|
import { PairingModalProps } from '../types';
|
|
import styles from '../styles/stylesheet';
|
|
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
|
|
import { useAccounts } from '../context/AccountsContext';
|
|
import { useWalletConnect } from '../context/WalletConnectContext';
|
|
|
|
const PairingModal = ({
|
|
visible,
|
|
currentProposal,
|
|
setCurrentProposal,
|
|
setModalVisible,
|
|
setToastVisible,
|
|
}: PairingModalProps) => {
|
|
const { accounts } = useAccounts();
|
|
|
|
const url = currentProposal?.params?.proposer?.metadata.url;
|
|
const icon = currentProposal?.params.proposer?.metadata.icons[0];
|
|
|
|
const [walletConnectData, setWalletConnectData] = useState<{
|
|
walletConnectMethods: string[];
|
|
walletConnectEvents: string[];
|
|
walletConnectChains: string[];
|
|
}>({
|
|
walletConnectMethods: [],
|
|
walletConnectEvents: [],
|
|
walletConnectChains: [],
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!currentProposal) {
|
|
return;
|
|
}
|
|
const { params } = currentProposal;
|
|
const { requiredNamespaces } = params;
|
|
Object.keys(requiredNamespaces).forEach(key => {
|
|
switch (key) {
|
|
case 'eip155':
|
|
const {
|
|
methods: ethMethods,
|
|
events: ethEvents,
|
|
chains: ethChains,
|
|
} = currentProposal?.params?.requiredNamespaces.eip155;
|
|
|
|
setWalletConnectData(prevData => {
|
|
return {
|
|
walletConnectMethods: [
|
|
...prevData.walletConnectMethods,
|
|
...ethMethods,
|
|
],
|
|
walletConnectEvents: [
|
|
...prevData.walletConnectEvents,
|
|
...ethEvents,
|
|
],
|
|
walletConnectChains: ethChains
|
|
? [...prevData.walletConnectChains, ...ethChains]
|
|
: [...prevData.walletConnectChains],
|
|
};
|
|
});
|
|
break;
|
|
case 'cosmos':
|
|
const {
|
|
methods: cosmosMethods,
|
|
events: cosmosEvents,
|
|
chains: cosmosChains,
|
|
} = currentProposal?.params?.requiredNamespaces.cosmos;
|
|
|
|
setWalletConnectData(prevData => {
|
|
return {
|
|
walletConnectMethods: [
|
|
...prevData.walletConnectMethods,
|
|
...cosmosMethods,
|
|
],
|
|
walletConnectEvents: [
|
|
...prevData.walletConnectEvents,
|
|
...cosmosEvents,
|
|
],
|
|
walletConnectChains: cosmosChains
|
|
? [...prevData.walletConnectChains, ...cosmosChains]
|
|
: [...prevData.walletConnectChains],
|
|
};
|
|
});
|
|
break;
|
|
default:
|
|
throw new Error(`${key} not supported`);
|
|
}
|
|
});
|
|
}, [currentProposal]);
|
|
|
|
const { setActiveSessions } = useWalletConnect();
|
|
|
|
const handleAccept = async () => {
|
|
if (currentProposal) {
|
|
const { id, params } = currentProposal;
|
|
const { requiredNamespaces, relays } = params;
|
|
const namespaces: SessionTypes.Namespaces = {};
|
|
|
|
Object.keys(requiredNamespaces).forEach(key => {
|
|
let currentAddresses: string[];
|
|
|
|
switch (key) {
|
|
case 'eip155':
|
|
if (accounts.ethAccounts.length > 0) {
|
|
currentAddresses = accounts.ethAccounts.map(
|
|
account => account.address,
|
|
);
|
|
}
|
|
break;
|
|
case 'cosmos':
|
|
if (accounts.cosmosAccounts.length > 0) {
|
|
currentAddresses = accounts.cosmosAccounts.map(
|
|
account => account.address,
|
|
);
|
|
}
|
|
break;
|
|
default:
|
|
throw new Error(`${key} not supported`);
|
|
}
|
|
|
|
const namespaceAccounts: string[] = [];
|
|
requiredNamespaces[key].chains!.map((chain: string) => {
|
|
currentAddresses.map(acc =>
|
|
namespaceAccounts.push(`${chain}:${acc}`),
|
|
);
|
|
});
|
|
|
|
namespaces[key] = {
|
|
accounts: namespaceAccounts,
|
|
methods: requiredNamespaces[key].methods,
|
|
events: requiredNamespaces[key].events,
|
|
};
|
|
});
|
|
|
|
await web3wallet.approveSession({
|
|
id,
|
|
relayProtocol: relays[0].protocol,
|
|
namespaces,
|
|
});
|
|
|
|
const sessions = web3wallet.getActiveSessions();
|
|
setActiveSessions(sessions);
|
|
setModalVisible(false);
|
|
setToastVisible(true);
|
|
setCurrentProposal(undefined);
|
|
setWalletConnectData({
|
|
walletConnectMethods: [],
|
|
walletConnectEvents: [],
|
|
walletConnectChains: [],
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleReject = async () => {
|
|
if (currentProposal) {
|
|
const { id } = currentProposal;
|
|
await web3wallet.rejectSession({
|
|
id,
|
|
reason: getSdkError('USER_REJECTED_METHODS'),
|
|
});
|
|
|
|
setModalVisible(false);
|
|
setCurrentProposal(undefined);
|
|
setWalletConnectData({
|
|
walletConnectMethods: [],
|
|
walletConnectEvents: [],
|
|
walletConnectChains: [],
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Modal visible={visible} animationType="slide" transparent>
|
|
<View style={styles.container}>
|
|
<View style={styles.modalContentContainer}>
|
|
{icon && (
|
|
<Image
|
|
style={styles.dappLogo}
|
|
source={icon ? { uri: icon } : undefined}
|
|
/>
|
|
)}
|
|
|
|
<Text variant="bodyMedium">{url}</Text>
|
|
<View style={styles.marginVertical8} />
|
|
<Text variant="titleMedium">Connect to this site?</Text>
|
|
<Text>Chains: {walletConnectData.walletConnectChains}</Text>
|
|
|
|
<View style={styles.marginVertical8}>
|
|
<Text variant="titleMedium">Methods Requested:</Text>
|
|
{walletConnectData.walletConnectMethods.map(method => (
|
|
<Text style={styles.centerText} key={method}>
|
|
{method}
|
|
</Text>
|
|
))}
|
|
</View>
|
|
|
|
<View style={styles.marginVertical8}>
|
|
<Text variant="titleMedium">Events Requested:</Text>
|
|
{walletConnectData.walletConnectEvents.map(event => (
|
|
<Text style={styles.centerText} key={event}>
|
|
{event}
|
|
</Text>
|
|
))}
|
|
</View>
|
|
|
|
<View style={styles.flexRow}>
|
|
<Button mode="contained" onPress={() => handleAccept()}>
|
|
Accept
|
|
</Button>
|
|
<View style={styles.space} />
|
|
<Button mode="outlined" onPress={() => handleReject()}>
|
|
Cancel
|
|
</Button>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default PairingModal;
|