import React, { useEffect, useMemo, useState } from 'react'; import { Image, View, Modal, ScrollView } from 'react-native'; import { Button, Text } from 'react-native-paper'; import { SvgUri } from 'react-native-svg'; import mergeWith from 'lodash/mergeWith'; import { buildApprovedNamespaces, 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'; import { useNetworks } from '../context/NetworksContext'; import { getNamespaces } from '../utils/wallet-connect/helpers'; const PairingModal = ({ visible, currentProposal, setCurrentProposal, setModalVisible, setToastVisible, }: PairingModalProps) => { const { accounts, currentIndex } = useAccounts(); const { selectedNetwork, networksData } = useNetworks(); const [isLoading, setIsLoading] = useState(false); const dappName = currentProposal?.params?.proposer?.metadata.name; 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: [], }); const [supportedNamespaces, setSupportedNamespaces] = useState< Record< string, { chains: string[]; methods: string[]; events: string[]; accounts: string[]; } > >(); useEffect(() => { if (!currentProposal) { return; } const { params } = currentProposal; const { requiredNamespaces, optionalNamespaces } = params; setWalletConnectData({ walletConnectMethods: [], walletConnectEvents: [], walletConnectChains: [], }); const combinedNamespaces = mergeWith( requiredNamespaces, optionalNamespaces, (obj, src) => Array.isArray(obj) && Array.isArray(src) ? [...src, ...obj] : undefined, ); Object.keys(combinedNamespaces).forEach(key => { const { methods, events, chains } = combinedNamespaces[key]; setWalletConnectData(prevData => { return { walletConnectMethods: [...prevData.walletConnectMethods, ...methods], walletConnectEvents: [...prevData.walletConnectEvents, ...events], walletConnectChains: chains ? [...prevData.walletConnectChains, ...chains] : [...prevData.walletConnectChains], }; }); }); }, [currentProposal]); const { setActiveSessions } = useWalletConnect(); useEffect(() => { const getSupportedNamespaces = async () => { if (!currentProposal) { return; } const { optionalNamespaces, requiredNamespaces } = currentProposal.params; const nameSpaces = await getNamespaces( optionalNamespaces, requiredNamespaces, networksData, selectedNetwork, accounts, currentIndex, ); setSupportedNamespaces(nameSpaces); }; getSupportedNamespaces(); }, [currentProposal, networksData, selectedNetwork, accounts, currentIndex]); const namespaces = useMemo(() => { return ( currentProposal && supportedNamespaces && buildApprovedNamespaces({ proposal: currentProposal.params, supportedNamespaces, }) ); }, [currentProposal, supportedNamespaces]); const handleAccept = async () => { try { if (currentProposal && namespaces) { setIsLoading(true); const { id } = currentProposal; await web3wallet!.approveSession({ id, namespaces, }); const sessions = web3wallet!.getActiveSessions(); setIsLoading(false); setActiveSessions(sessions); setModalVisible(false); setToastVisible(true); setCurrentProposal(undefined); setSupportedNamespaces(undefined); setWalletConnectData({ walletConnectMethods: [], walletConnectEvents: [], walletConnectChains: [], }); } } catch (error) { console.error('Error in approve session:', error); throw error; } }; 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 ( {icon && ( <> {icon.endsWith('.svg') ? ( ) : ( )} )} {dappName} {url} Connect to this site? {walletConnectData.walletConnectMethods.length > 0 && ( Chains: {walletConnectData.walletConnectChains.map(chain => ( {chain} ))} )} {walletConnectData.walletConnectMethods.length > 0 && ( Methods Requested: {walletConnectData.walletConnectMethods.map(method => ( {method} ))} )} {walletConnectData.walletConnectEvents.length > 0 && ( Events Requested: {walletConnectData.walletConnectEvents.map(event => ( {event} ))} )} ); }; export default PairingModal;