diff --git a/src/App.tsx b/src/App.tsx index a587432..86965da 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,7 +23,6 @@ import AddSession from './screens/AddSession'; import WalletConnect from './screens/WalletConnect'; import ApproveTransaction from './screens/ApproveTransaction'; import { StackParamsList } from './types'; -import { web3wallet } from './utils/wallet-connect/WalletConnectUtils'; import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Data'; import { getSignParamsMessage } from './utils/wallet-connect/helpers'; import ApproveTransfer from './screens/ApproveTransfer'; @@ -40,7 +39,7 @@ const App = (): React.JSX.Element => { const navigation = useNavigation>(); - const { setActiveSessions } = useWalletConnect(); + const { web3wallet, setActiveSessions } = useWalletConnect(); const { accounts, setCurrentIndex } = useAccounts(); const { networksData, selectedNetwork, setSelectedNetwork } = useNetworks(); const [modalVisible, setModalVisible] = useState(false); @@ -62,7 +61,7 @@ const App = (): React.JSX.Element => { setModalVisible(true); setCurrentProposal(proposal); }, - [accounts], + [accounts, web3wallet], ); const onSessionRequest = useCallback( @@ -196,13 +195,14 @@ const App = (): React.JSX.Element => { setSelectedNetwork, setCurrentIndex, selectedNetwork, + web3wallet ], ); const onSessionDelete = useCallback(() => { const sessions = web3wallet!.getActiveSessions(); setActiveSessions(sessions); - }, [setActiveSessions]); + }, [setActiveSessions, web3wallet]); useEffect(() => { web3wallet?.on('session_proposal', onSessionProposal); diff --git a/src/components/Accounts.tsx b/src/components/Accounts.tsx index fd7770a..29de844 100644 --- a/src/components/Accounts.tsx +++ b/src/components/Accounts.tsx @@ -11,7 +11,7 @@ import styles from '../styles/stylesheet'; import HDPathDialog from './HDPathDialog'; import AccountDetails from './AccountDetails'; import { useAccounts } from '../context/AccountsContext'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; +import { useWalletConnect } from '../context/WalletConnectContext'; import { useNetworks } from '../context/NetworksContext'; import ConfirmDialog from './ConfirmDialog'; import { getNamespaces } from '../utils/wallet-connect/helpers'; @@ -26,6 +26,8 @@ const Accounts = () => { useAccounts(); const { networksData, selectedNetwork, setNetworksData, setSelectedNetwork } = useNetworks(); + + const {web3wallet} = useWalletConnect(); const [expanded, setExpanded] = useState(false); const [isAccountCreating, setIsAccountCreating] = useState(false); const [hdDialog, setHdDialog] = useState(false); @@ -74,7 +76,7 @@ const Accounts = () => { // Call the updateSessions function when the 'accounts' dependency changes updateSessions(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [accounts]); + }, [accounts, web3wallet]); const addAccountHandler = async () => { setIsAccountCreating(true); diff --git a/src/components/PairingModal.tsx b/src/components/PairingModal.tsx index 39ba1df..ec08b81 100644 --- a/src/components/PairingModal.tsx +++ b/src/components/PairingModal.tsx @@ -7,7 +7,6 @@ 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'; @@ -86,7 +85,7 @@ const PairingModal = ({ }); }, [currentProposal]); - const { setActiveSessions } = useWalletConnect(); + const { setActiveSessions, web3wallet } = useWalletConnect(); useEffect(() => { const getSupportedNamespaces = async () => { @@ -131,6 +130,7 @@ const PairingModal = ({ currentIndex, setCurrentProposal, setModalVisible, + web3wallet ]); const namespaces = useMemo(() => { diff --git a/src/context/WalletConnectContext.tsx b/src/context/WalletConnectContext.tsx index 903319d..34b6d5f 100644 --- a/src/context/WalletConnectContext.tsx +++ b/src/context/WalletConnectContext.tsx @@ -1,14 +1,16 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; import { SessionTypes } from '@walletconnect/types'; +import { IWeb3Wallet } from '@walletconnect/web3wallet'; import { WalletConnectContextProps } from '../types'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import useInitialization from '../hooks/useInitialization'; const WalletConnectContext = createContext({ activeSessions: {}, setActiveSessions: () => {}, + web3wallet: {} as IWeb3Wallet, + setWeb3wallet: () => {}, }); const useWalletConnect = () => { @@ -17,12 +19,14 @@ const useWalletConnect = () => { }; const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => { - useInitialization(); + const [web3wallet, setWeb3wallet] = useState(); + + useInitialization(setWeb3wallet); useEffect(() => { const sessions = (web3wallet && web3wallet.getActiveSessions()) || {}; setActiveSessions(sessions); - }, []); + }, [web3wallet]); const [activeSessions, setActiveSessions] = useState< Record @@ -33,6 +37,8 @@ const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => { value={{ activeSessions, setActiveSessions, + web3wallet, + setWeb3wallet, }}> {children} diff --git a/src/hooks/useInitialization.ts b/src/hooks/useInitialization.ts index 3759e5c..1cd5908 100644 --- a/src/hooks/useInitialization.ts +++ b/src/hooks/useInitialization.ts @@ -1,17 +1,23 @@ import { useCallback, useEffect, useState } from 'react'; + +import { IWeb3Wallet } from '@walletconnect/web3wallet'; + import { createWeb3Wallet } from '../utils/wallet-connect/WalletConnectUtils'; -export default function useInitialization() { +export default function useInitialization( + setWeb3wallet: React.Dispatch>, +) { const [initialized, setInitialized] = useState(false); const onInitialize = useCallback(async () => { try { - await createWeb3Wallet(); + const web3walletInstance = await createWeb3Wallet(); + setWeb3wallet(web3walletInstance); setInitialized(true); } catch (err: unknown) { console.error('Error for initializing', err); } - }, []); + }, [setWeb3wallet]); useEffect(() => { if (!initialized) { diff --git a/src/screens/AddSession.tsx b/src/screens/AddSession.tsx index 72a2d60..55fa2b3 100644 --- a/src/screens/AddSession.tsx +++ b/src/screens/AddSession.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { View } from 'react-native'; import { Button, Text, TextInput } from 'react-native-paper'; @@ -8,6 +8,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { web3WalletPair } from '../utils/wallet-connect/WalletConnectUtils'; import styles from '../styles/stylesheet'; import { StackParamsList } from '../types'; +import { useWalletConnect } from '../context/WalletConnectContext'; const AddSession = () => { const navigation = @@ -15,11 +16,17 @@ const AddSession = () => { const [currentWCURI, setCurrentWCURI] = useState(''); - const pair = async () => { - const pairing = await web3WalletPair({ uri: currentWCURI }); + const {web3wallet} = useWalletConnect(); + + const pair = useCallback(async () => { + if (!web3wallet) { + return; + } + + const pairing = await web3WalletPair(web3wallet, { uri: currentWCURI }); navigation.navigate('WalletConnect'); return pairing; - }; + }, [currentWCURI, navigation, web3wallet]); return ( diff --git a/src/screens/ApproveTransaction.tsx b/src/screens/ApproveTransaction.tsx index 97f4c1a..cfc6ea1 100644 --- a/src/screens/ApproveTransaction.tsx +++ b/src/screens/ApproveTransaction.tsx @@ -23,7 +23,7 @@ import { approveWalletConnectRequest, rejectWalletConnectRequest, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; +import { useWalletConnect } from '../context/WalletConnectContext'; import { MEMO } from './ApproveTransfer'; import TxErrorDialog from '../components/TxErrorDialog'; import AccountDetails from '../components/AccountDetails'; @@ -65,6 +65,8 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => { ); const namespace = requestedNetwork!.namespace; + const { web3wallet } = useWalletConnect(); + useEffect(() => { if (namespace !== COSMOS) { return; @@ -106,7 +108,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => { }; setClient(); - }, [account, requestedNetwork, chainId, namespace, requestEventId, topic]); + }, [account, requestedNetwork, chainId, namespace, requestEventId, topic, web3wallet]); const retrieveData = useCallback( async (requestAddress: string) => { @@ -158,7 +160,7 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => { } }; getCosmosGas(); - }, [cosmosStargateClient, transactionMessage, requestEventId, topic]); + }, [cosmosStargateClient, transactionMessage, requestEventId, topic, web3wallet]); useEffect(() => { const gasPrice = GasPrice.fromString( diff --git a/src/screens/ApproveTransfer.tsx b/src/screens/ApproveTransfer.tsx index 9ca98eb..71ee07d 100644 --- a/src/screens/ApproveTransfer.tsx +++ b/src/screens/ApproveTransfer.tsx @@ -33,7 +33,7 @@ import { rejectWalletConnectRequest, WalletConnectRequests, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; +import { useWalletConnect } from '../context/WalletConnectContext'; import DataBox from '../components/DataBox'; import { getPathKey } from '../utils/misc'; import { useNetworks } from '../context/NetworksContext'; @@ -53,6 +53,7 @@ type SignRequestProps = NativeStackScreenProps< const ApproveTransfer = ({ route }: SignRequestProps) => { const { networksData } = useNetworks(); + const { web3wallet } = useWalletConnect(); const requestSession = route.params.requestSessionData; const requestName = requestSession.peer.metadata.name; diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx index 259f3ce..db7ee75 100644 --- a/src/screens/HomeScreen.tsx +++ b/src/screens/HomeScreen.tsx @@ -16,7 +16,6 @@ import styles from '../styles/stylesheet'; import { useAccounts } from '../context/AccountsContext'; import { useWalletConnect } from '../context/WalletConnectContext'; import { NetworksDataState, StackParamsList } from '../types'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { useNetworks } from '../context/NetworksContext'; const WCLogo = () => { @@ -33,7 +32,7 @@ const HomeScreen = () => { const { networksData, selectedNetwork, setSelectedNetwork, setNetworksData } = useNetworks(); - const { setActiveSessions } = useWalletConnect(); + const { setActiveSessions, web3wallet } = useWalletConnect(); const navigation = useNavigation>(); @@ -115,6 +114,7 @@ const HomeScreen = () => { setCurrentIndex, setNetworksData, setSelectedNetwork, + web3wallet ]); const updateNetwork = (networkData: NetworksDataState) => { diff --git a/src/screens/SignRequest.tsx b/src/screens/SignRequest.tsx index b768d17..472c0e6 100644 --- a/src/screens/SignRequest.tsx +++ b/src/screens/SignRequest.tsx @@ -19,7 +19,7 @@ import { rejectWalletConnectRequest, WalletConnectRequests, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; +import { useWalletConnect } from '../context/WalletConnectContext'; import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data'; import { useNetworks } from '../context/NetworksContext'; import { COSMOS_METHODS } from '../utils/wallet-connect/COSMOSData'; @@ -28,6 +28,7 @@ type SignRequestProps = NativeStackScreenProps; const SignRequest = ({ route }: SignRequestProps) => { const { networksData } = useNetworks(); + const {web3wallet} = useWalletConnect(); const requestSession = route.params.requestSessionData; const requestName = requestSession?.peer?.metadata?.name; diff --git a/src/screens/WalletConnect.tsx b/src/screens/WalletConnect.tsx index c0e80d9..f581930 100644 --- a/src/screens/WalletConnect.tsx +++ b/src/screens/WalletConnect.tsx @@ -5,11 +5,10 @@ import { List, Text } from 'react-native-paper'; import { getSdkError } from '@walletconnect/utils'; import { useWalletConnect } from '../context/WalletConnectContext'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import styles from '../styles/stylesheet'; export default function WalletConnect() { - const { activeSessions, setActiveSessions } = useWalletConnect(); + const { web3wallet, activeSessions, setActiveSessions } = useWalletConnect(); const disconnect = async (sessionId: string) => { await web3wallet!.disconnectSession({ @@ -24,7 +23,7 @@ export default function WalletConnect() { useEffect(() => { const sessions = web3wallet?.getActiveSessions() || {}; setActiveSessions(sessions); - }, [setActiveSessions]); + }, [web3wallet, setActiveSessions]); return ( diff --git a/src/types.ts b/src/types.ts index 45bdfe3..4f87bb4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,7 @@ import { PopulatedTransaction } from 'ethers'; import { SignClientTypes, SessionTypes } from '@walletconnect/types'; -import { Web3WalletTypes } from '@walletconnect/web3wallet'; +import { IWeb3Wallet, Web3WalletTypes } from '@walletconnect/web3wallet'; import { EncodeObject } from '@cosmjs/proto-signing'; export type StackParamsList = { @@ -129,4 +129,6 @@ export interface WalletConnectContextProps { setActiveSessions: ( activeSessions: Record, ) => void; + web3wallet: IWeb3Wallet | undefined; + setWeb3wallet: React.Dispatch>; } diff --git a/src/utils/wallet-connect/WalletConnectUtils.tsx b/src/utils/wallet-connect/WalletConnectUtils.tsx index 22da64e..362bca0 100644 --- a/src/utils/wallet-connect/WalletConnectUtils.tsx +++ b/src/utils/wallet-connect/WalletConnectUtils.tsx @@ -14,7 +14,7 @@ export async function createWeb3Wallet() { projectId: process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID, }); - web3wallet = await Web3Wallet.init({ + const web3wallet = await Web3Wallet.init({ core, metadata: { name: 'Laconic Wallet', @@ -23,9 +23,14 @@ export async function createWeb3Wallet() { icons: ['https://avatars.githubusercontent.com/u/92608123'], }, }); + + return web3wallet; } -export async function web3WalletPair(params: { uri: string }) { +export async function web3WalletPair( + web3wallet: IWeb3Wallet, + params: { uri: string }, +) { if (web3wallet) { return await web3wallet.core.pairing.pair({ uri: params.uri }); }