From 361b79b69614dc2a1fa47dd4ce31d7b384010f8e Mon Sep 17 00:00:00 2001 From: nabarun Date: Mon, 29 Jul 2024 12:13:15 +0000 Subject: [PATCH] Refactor wallet connect instance to use state variables (#8) Part of [laconicd testnet validator enrollment](https://www.notion.so/laconicd-testnet-validator-enrollment-6fc1d3cafcc64fef8c5ed3affa27c675) - Refactor `web3wallet` variable into a state variable Co-authored-by: Shreerang Kale Co-authored-by: Adw8 Reviewed-on: https://git.vdb.to/cerc-io/laconic-wallet/pulls/8 --- development.md | 13 ++++++----- package.json | 2 +- src/App.tsx | 8 +++---- src/components/Accounts.tsx | 6 +++-- src/components/PairingModal.tsx | 4 ++-- src/context/WalletConnectContext.tsx | 12 +++++++--- src/hooks/useInitialization.ts | 13 ++++++++--- src/screens/AddSession.tsx | 15 +++++++++---- src/screens/ApproveTransaction.tsx | 22 ++++++++++++++++--- src/screens/ApproveTransfer.tsx | 4 +++- src/screens/HomeScreen.tsx | 4 ++-- src/screens/SignRequest.tsx | 4 +++- src/screens/WalletConnect.tsx | 5 ++--- src/types.ts | 4 +++- .../wallet-connect/WalletConnectUtils.tsx | 10 ++++++--- yarn.lock | 8 +++---- 16 files changed, 92 insertions(+), 42 deletions(-) diff --git a/development.md b/development.md index e2bb3d8..e487aca 100644 --- a/development.md +++ b/development.md @@ -9,7 +9,6 @@ - Function for creating web3 wallet ```js - export let web3wallet: IWeb3Wallet; export let core: ICore; export async function createWeb3Wallet() { @@ -26,23 +25,27 @@ icons: ['https://avatars.githubusercontent.com/u/92608123'], }, }); + + return web3wallet; } ``` - Hook used for intializing web3 wallet ```js - export default function useInitialization() { + export default function useInitialization(setWeb3wallet) { const [initialized, setInitialized] = useState(false); const onInitialize = useCallback(async () => { try { - await createWeb3Wallet(); + const web3walletInstance = await createWeb3Wallet(); + setWeb3wallet(web3walletInstance); + setInitialized(true); } catch (err: unknown) { - console.log('Error for initializing', err); + console.error('Error for initializing', err); } - }, []); + }, [setWeb3wallet]); useEffect(() => { if (!initialized) { diff --git a/package.json b/package.json index 4be6ae9..7cf8d71 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "prepare": "husky" }, "dependencies": { - "@cerc-io/registry-sdk": "^0.2.3", + "@cerc-io/registry-sdk": "^0.2.4", "@cosmjs/amino": "^0.32.3", "@cosmjs/crypto": "^0.32.3", "@cosmjs/proto-signing": "^0.32.3", diff --git a/src/App.tsx b/src/App.tsx index 914e5ef..5051225 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,7 +24,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'; @@ -41,7 +40,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); @@ -63,7 +62,7 @@ const App = (): React.JSX.Element => { setModalVisible(true); setCurrentProposal(proposal); }, - [accounts], + [accounts, web3wallet], ); const onSessionRequest = useCallback( @@ -197,13 +196,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 ede9122..055a8c3 100644 --- a/src/components/Accounts.tsx +++ b/src/components/Accounts.tsx @@ -12,11 +12,11 @@ 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 { useNetworks } from '../context/NetworksContext'; import ConfirmDialog from './ConfirmDialog'; import { getNamespaces } from '../utils/wallet-connect/helpers'; import ShowPKDialog from './ShowPKDialog'; +import { useWalletConnect } from '../context/WalletConnectContext'; const Accounts = () => { const navigation = @@ -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 31abc13..5e335a8 100644 --- a/src/components/PairingModal.tsx +++ b/src/components/PairingModal.tsx @@ -8,7 +8,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'; @@ -87,7 +86,7 @@ const PairingModal = ({ }); }, [currentProposal]); - const { setActiveSessions } = useWalletConnect(); + const { setActiveSessions, web3wallet } = useWalletConnect(); useEffect(() => { const getSupportedNamespaces = async () => { @@ -131,6 +130,7 @@ const PairingModal = ({ selectedNetwork, accounts, currentIndex, + web3wallet, setCurrentProposal, setModalVisible, ]); 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..282f320 100644 --- a/src/hooks/useInitialization.ts +++ b/src/hooks/useInitialization.ts @@ -1,17 +1,24 @@ 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 a54c006..70472bb 100644 --- a/src/screens/AddSession.tsx +++ b/src/screens/AddSession.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { AppState, TouchableOpacity, View } from 'react-native'; import { Button, Text, TextInput } from 'react-native-paper'; import { @@ -15,6 +15,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 = @@ -23,6 +24,8 @@ const AddSession = () => { const { hasPermission, requestPermission } = useCameraPermission(); const device = useCameraDevice('back'); + const { web3wallet } = useWalletConnect(); + const [currentWCURI, setCurrentWCURI] = useState(''); const [isActive, setIsActive] = useState(AppState.currentState === 'active'); const [isScanning, setScanning] = useState(true); @@ -45,11 +48,15 @@ const AddSession = () => { await Linking.openSettings(); }; - const pair = async () => { - const pairing = await web3WalletPair({ uri: currentWCURI }); + const pair = useCallback(async () => { + if (!web3wallet) { + return; + } + + const pairing = await web3WalletPair(web3wallet, { uri: currentWCURI }); navigation.navigate('WalletConnect'); return pairing; - }; + }, [web3wallet, currentWCURI, navigation]); useEffect(() => { const handleAppStateChange = (newState: string) => { diff --git a/src/screens/ApproveTransaction.tsx b/src/screens/ApproveTransaction.tsx index 532d8a1..61ab455 100644 --- a/src/screens/ApproveTransaction.tsx +++ b/src/screens/ApproveTransaction.tsx @@ -25,10 +25,10 @@ import { approveWalletConnectRequest, rejectWalletConnectRequest, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { MEMO } from './ApproveTransfer'; import TxErrorDialog from '../components/TxErrorDialog'; import AccountDetails from '../components/AccountDetails'; +import { useWalletConnect } from '../context/WalletConnectContext'; type ApproveTransactionProps = NativeStackScreenProps< StackParamsList, @@ -49,6 +49,8 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => { const requestEventId = requestEvent.id; const topic = requestEvent.topic; + const { web3wallet } = useWalletConnect(); + const [account, setAccount] = useState(); const [cosmosStargateClient, setCosmosStargateClient] = useState(); @@ -104,7 +106,15 @@ const ApproveTransaction = ({ route }: ApproveTransactionProps) => { }; setClient(); - }, [account, requestedNetwork, chainId, namespace, requestEventId, topic]); + }, [ + account, + requestedNetwork, + chainId, + namespace, + requestEventId, + topic, + web3wallet, + ]); const retrieveData = useCallback( async (requestAddress: string) => { @@ -152,7 +162,13 @@ 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 f027433..6ba91e5 100644 --- a/src/screens/ApproveTransfer.tsx +++ b/src/screens/ApproveTransfer.tsx @@ -34,7 +34,6 @@ import { rejectWalletConnectRequest, WalletConnectRequests, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import DataBox from '../components/DataBox'; import { getPathKey } from '../utils/misc'; import { useNetworks } from '../context/NetworksContext'; @@ -42,6 +41,7 @@ import { COSMOS, EIP155, IS_NUMBER_REGEX } from '../utils/constants'; import TxErrorDialog from '../components/TxErrorDialog'; import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data'; import { COSMOS_METHODS } from '../utils/wallet-connect/COSMOSData'; +import { useWalletConnect } from '../context/WalletConnectContext'; export const MEMO = 'Sending signed tx from Laconic Wallet'; // Reference: https://ethereum.org/en/developers/docs/gas/#what-is-gas-limit @@ -64,6 +64,8 @@ const ApproveTransfer = ({ route }: SignRequestProps) => { const chainId = requestEvent.params.chainId; const requestMethod = requestEvent.params.request.method; + const { web3wallet } = useWalletConnect(); + const [account, setAccount] = useState(); const [isLoading, setIsLoading] = useState(true); const [balance, setBalance] = useState(''); diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx index af8dc61..98710cc 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 { web3wallet, setActiveSessions } = useWalletConnect(); const navigation = useNavigation>(); @@ -110,6 +109,7 @@ const HomeScreen = () => { hideResetDialog(); }, [ + web3wallet, setAccounts, setActiveSessions, setCurrentIndex, diff --git a/src/screens/SignRequest.tsx b/src/screens/SignRequest.tsx index 931115b..6f182bb 100644 --- a/src/screens/SignRequest.tsx +++ b/src/screens/SignRequest.tsx @@ -20,10 +20,10 @@ import { rejectWalletConnectRequest, WalletConnectRequests, } from '../utils/wallet-connect/wallet-connect-requests'; -import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data'; import { useNetworks } from '../context/NetworksContext'; import { COSMOS_METHODS } from '../utils/wallet-connect/COSMOSData'; +import { useWalletConnect } from '../context/WalletConnectContext'; type SignRequestProps = NativeStackScreenProps; @@ -35,6 +35,8 @@ const SignRequest = ({ route }: SignRequestProps) => { const requestIcon = requestSession?.peer?.metadata?.icons[0]; const requestURL = requestSession?.peer?.metadata?.url; + const { web3wallet } = useWalletConnect(); + const [account, setAccount] = useState(); const [message, setMessage] = useState(''); const [namespace, setNamespace] = useState(''); diff --git a/src/screens/WalletConnect.tsx b/src/screens/WalletConnect.tsx index e998f98..3d42e57 100644 --- a/src/screens/WalletConnect.tsx +++ b/src/screens/WalletConnect.tsx @@ -6,11 +6,10 @@ import { SvgUri } from 'react-native-svg'; 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({ @@ -25,7 +24,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 026f901..a58dd31 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 = { @@ -127,4 +127,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 40ded1c..559429f 100644 --- a/src/utils/wallet-connect/WalletConnectUtils.tsx +++ b/src/utils/wallet-connect/WalletConnectUtils.tsx @@ -6,7 +6,6 @@ import { Core } from '@walletconnect/core'; import { ICore } from '@walletconnect/types'; import { Web3Wallet, IWeb3Wallet } from '@walletconnect/web3wallet'; -export let web3wallet: IWeb3Wallet | undefined; export let core: ICore; export async function createWeb3Wallet() { @@ -14,7 +13,7 @@ export async function createWeb3Wallet() { projectId: Config.WALLET_CONNECT_PROJECT_ID, }); - web3wallet = await Web3Wallet.init({ + const web3wallet = await Web3Wallet.init({ core, metadata: { name: 'Laconic Wallet', @@ -23,9 +22,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 }); } diff --git a/yarn.lock b/yarn.lock index 8157702..f1ae519 100644 --- a/yarn.lock +++ b/yarn.lock @@ -752,10 +752,10 @@ deepmerge "^3.2.0" hoist-non-react-statics "^3.3.0" -"@cerc-io/registry-sdk@^0.2.3": - version "0.2.3" - resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fregistry-sdk/-/0.2.3/registry-sdk-0.2.3.tgz#73e955b4d49d7c97eea40c351bbc21f98bb330f9" - integrity sha512-8fXRdyiTXn8WsJ8r3DCSBYzUBNEZYPPk5JGUrEmkGQhKOJr+ZeakN+2t6HrqEVB9IMYTJK9BtVLPA0KlaXILYA== +"@cerc-io/registry-sdk@^0.2.4": + version "0.2.4" + resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fregistry-sdk/-/0.2.4/registry-sdk-0.2.4.tgz#60e4e75b1e6a957cf2b97490af4fda4af07b105f" + integrity sha512-hRZJP+s+uBvfrqtmQ38pmf74SyfFDC65AVwvWigJGxc6uKJG4jyuMyhsoD1P4XkjwAQSnFO89TuDC5JGkdXyrA== dependencies: "@cosmjs/amino" "^0.28.1" "@cosmjs/crypto" "^0.28.1"