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 <shreerangkale@gmail.com>
Co-authored-by: Adw8 <adwaitgharpure@gmail.com>
Reviewed-on: cerc-io/laconic-wallet#8
This commit is contained in:
nabarun 2024-07-29 12:13:15 +00:00
parent 0bd9dec8a9
commit 361b79b696
16 changed files with 92 additions and 42 deletions

View File

@ -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) {

View File

@ -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",

View File

@ -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<NativeStackNavigationProp<StackParamsList>>();
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);

View File

@ -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);

View File

@ -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,
]);

View File

@ -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<WalletConnectContextProps>({
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<IWeb3Wallet | undefined>();
useInitialization(setWeb3wallet);
useEffect(() => {
const sessions = (web3wallet && web3wallet.getActiveSessions()) || {};
setActiveSessions(sessions);
}, []);
}, [web3wallet]);
const [activeSessions, setActiveSessions] = useState<
Record<string, SessionTypes.Struct>
@ -33,6 +37,8 @@ const WalletConnectProvider = ({ children }: { children: React.ReactNode }) => {
value={{
activeSessions,
setActiveSessions,
web3wallet,
setWeb3wallet,
}}>
{children}
</WalletConnectContext.Provider>

View File

@ -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<React.SetStateAction<IWeb3Wallet | undefined>>,
) {
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) {

View File

@ -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<string>('');
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) => {

View File

@ -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<Account>();
const [cosmosStargateClient, setCosmosStargateClient] =
useState<LaconicClient>();
@ -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(

View File

@ -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<Account>();
const [isLoading, setIsLoading] = useState(true);
const [balance, setBalance] = useState<string>('');

View File

@ -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<NativeStackNavigationProp<StackParamsList>>();
@ -110,6 +109,7 @@ const HomeScreen = () => {
hideResetDialog();
}, [
web3wallet,
setAccounts,
setActiveSessions,
setCurrentIndex,

View File

@ -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<StackParamsList, 'SignRequest'>;
@ -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<Account>();
const [message, setMessage] = useState<string>('');
const [namespace, setNamespace] = useState<string>('');

View File

@ -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 (
<View>

View File

@ -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<string, SessionTypes.Struct>,
) => void;
web3wallet: IWeb3Wallet | undefined;
setWeb3wallet: React.Dispatch<React.SetStateAction<IWeb3Wallet | undefined>>;
}

View File

@ -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 });
}

View File

@ -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"