Use context for maintaining accounts state (#41)

* Use context for maintaining accounts state

* Remove custom hook from context
This commit is contained in:
shreerang6921 2024-03-06 17:44:13 +05:30 committed by GitHub
parent 19e39281a6
commit a4e0dc5406
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 87 additions and 58 deletions

29
App.tsx
View File

@ -1,4 +1,10 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { SignClientTypes } from '@walletconnect/types';
import { NavigationContainer } from '@react-navigation/native';
@ -16,13 +22,15 @@ import useInitialization, {
web3wallet,
} from './utils/wallet-connect/WalletConnectUtils';
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib';
import { retrieveAccounts } from './utils/accounts';
import { AccountsContext } from './context/AccountsContext';
const Stack = createNativeStackNavigator<StackParamsList>();
const App = (): React.JSX.Element => {
useInitialization();
const { accounts } = useContext(AccountsContext);
const [modalVisible, setModalVisible] = useState(false);
//TODO: Remove any
const [currentProposal, setCurrentProposal] = useState<
@ -31,7 +39,6 @@ const App = (): React.JSX.Element => {
const [requestSession, setRequestSession] = useState<any>();
const [requestEventData, setRequestEventData] = useState<any>();
const [signModalVisible, setSignModalVisible] = useState(false);
const [currentEthAddresses, setCurrentEthAddresses] = useState<string[]>([]);
const onSessionProposal = useCallback(
(proposal: SignClientTypes.EventArguments['session_proposal']) => {
@ -65,19 +72,13 @@ const App = (): React.JSX.Element => {
//TODO: Investigate dependancies
});
useEffect(() => {
const fetchEthAccounts = async () => {
const { ethLoadedAccounts } = await retrieveAccounts();
if (ethLoadedAccounts) {
const ethAddreses = ethLoadedAccounts.map(account => account.address);
setCurrentEthAddresses(ethAddreses);
const currentEthAddresses = useMemo(() => {
if (accounts.ethAccounts.length > 0) {
return accounts.ethAccounts.map(account => account.address);
}
};
fetchEthAccounts();
// TODO: Use context to maintain accounts state
}, [modalVisible]);
return [];
}, [accounts]);
const linking = {
prefixes: ['https://www.laconic-wallet.com'],

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useContext, useState } from 'react';
import { ScrollView, TouchableOpacity, View } from 'react-native';
import { Button, List, Text, useTheme } from 'react-native-paper';
@ -10,16 +10,18 @@ import { addAccount } from '../utils/accounts';
import styles from '../styles/stylesheet';
import HDPathDialog from './HDPathDialog';
import AccountDetails from './AccountDetails';
import { AccountsContext } from '../context/AccountsContext';
const Accounts = ({
network,
accounts,
updateAccounts,
currentIndex,
updateIndex: updateId,
}: AccountsProps) => {
const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>();
const { accounts, setAccounts } = useContext(AccountsContext);
const [expanded, setExpanded] = useState(false);
const [isAccountCreating, setIsAccountCreating] = useState(false);
const [hdDialog, setHdDialog] = useState(false);
@ -28,6 +30,25 @@ const Accounts = ({
const handlePress = () => setExpanded(!expanded);
const updateAccounts = (account: Account) => {
switch (network) {
case 'eth':
setAccounts({
...accounts,
ethAccounts: [...accounts.ethAccounts, account],
});
break;
case 'cosmos':
setAccounts({
...accounts,
cosmosAccounts: [...accounts.cosmosAccounts, account],
});
break;
default:
console.error('Select a valid network!');
}
};
const addAccountHandler = async () => {
setIsAccountCreating(true);
const newAccount = await addAccount(network);

View File

@ -1,17 +1,19 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { View, ActivityIndicator } from 'react-native';
import { Button, Text } from 'react-native-paper';
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
import { DialogComponent } from './Dialog';
import { NetworkDropdown } from './NetworkDropdown';
import { Account, AccountsState } from '../types';
import Accounts from './Accounts';
import CreateWallet from './CreateWallet';
import ResetWalletDialog from './ResetWalletDialog';
import styles from '../styles/stylesheet';
import { AccountsContext } from '../context/AccountsContext';
const HomeScreen = () => {
const { accounts, setAccounts } = useContext(AccountsContext);
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);
const [walletDialog, setWalletDialog] = useState<boolean>(false);
@ -20,10 +22,6 @@ const HomeScreen = () => {
const [currentIndex, setCurrentIndex] = useState<number>(0);
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(false);
const [phrase, setPhrase] = useState('');
const [accounts, setAccounts] = useState<AccountsState>({
ethAccounts: [],
cosmosAccounts: [],
});
const hideWalletDialog = () => setWalletDialog(false);
const hideResetDialog = () => setResetWalletDialog(false);
@ -64,25 +62,6 @@ const HomeScreen = () => {
setCurrentIndex(index);
};
const updateAccounts = (account: Account) => {
switch (network) {
case 'eth':
setAccounts({
...accounts,
ethAccounts: [...accounts.ethAccounts, account],
});
break;
case 'cosmos':
setAccounts({
...accounts,
cosmosAccounts: [...accounts.cosmosAccounts, account],
});
break;
default:
console.error('Select a valid network!');
}
};
useEffect(() => {
const fetchAccounts = async () => {
if (isAccountsFetched) {
@ -104,7 +83,7 @@ const HomeScreen = () => {
};
fetchAccounts();
}, [isAccountsFetched]);
}, [isAccountsFetched, setAccounts]);
return (
<View style={styles.appContainer}>
@ -122,10 +101,8 @@ const HomeScreen = () => {
<View style={styles.accountComponent}>
<Accounts
network={network}
accounts={accounts}
currentIndex={currentIndex}
updateIndex={updateIndex}
updateAccounts={updateAccounts}
/>
</View>
<View style={styles.resetContainer}>

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useContext } from 'react';
import { Button, Text } from 'react-native-paper';
import { Image, Modal, View } from 'react-native';
@ -11,6 +11,7 @@ import {
import styles from '../styles/stylesheet';
import { SignModalProps } from '../types';
import { AccountsContext } from '../context/AccountsContext';
const SignModal = ({
visible,
@ -19,6 +20,8 @@ const SignModal = ({
requestSession,
currentEthAddresses,
}: SignModalProps) => {
const { accounts } = useContext(AccountsContext);
if (!requestEvent || !requestSession) {
return null;
}
@ -37,6 +40,7 @@ const SignModal = ({
const response = await approveEIP155Request(
requestEvent,
currentEthAddresses,
accounts.ethAccounts,
);
await web3wallet.respondSessionRequest({
topic,

View File

@ -0,0 +1,25 @@
import React, { createContext, useState } from 'react';
import { AccountsState } from '../types';
const AccountsContext = createContext<{
accounts: AccountsState;
setAccounts: (account: AccountsState) => void;
}>({
accounts: { ethAccounts: [], cosmosAccounts: [] },
setAccounts: () => {},
});
const AccountsProvider = ({ children }: { children: any }) => {
const [accounts, setAccounts] = useState<AccountsState>({
ethAccounts: [],
cosmosAccounts: [],
});
return (
<AccountsContext.Provider value={{ accounts, setAccounts }}>
{children}
</AccountsContext.Provider>
);
};
export { AccountsContext, AccountsProvider };

View File

@ -4,12 +4,15 @@ import { AppRegistry } from 'react-native';
import { PaperProvider } from 'react-native-paper';
import App from './App';
import { AccountsProvider } from './context/AccountsContext';
import { name as appName } from './app.json';
export default function Main() {
return (
<PaperProvider>
<AccountsProvider>
<App />
</AccountsProvider>
</PaperProvider>
);
}

View File

@ -25,13 +25,8 @@ export type WalletDetails = {
export type AccountsProps = {
network: string;
accounts: {
ethAccounts: Account[];
cosmosAccounts: Account[];
};
currentIndex: number;
updateIndex: (index: number) => void;
updateAccounts: (account: Account) => void;
};
export type NetworkDropdownProps = {

View File

@ -7,15 +7,18 @@ import { getSdkError } from '@walletconnect/utils';
import { EIP155_SIGNING_METHODS } from './EIP155Lib';
import { getSignParamsMessage, getAccountNumberFromParams } from './Helpers';
import { signEthMessage } from '../sign-message';
import { Account } from '../../types';
export async function approveEIP155Request(
requestEvent: SignClientTypes.EventArguments['session_request'],
currentEthAddresses: string[],
ethAccounts: Account[],
) {
const { params, id } = requestEvent;
const { request } = params;
const counterId = await getAccountNumberFromParams(
currentEthAddresses,
ethAccounts,
params,
);

View File

@ -1,9 +1,10 @@
// Taken from https://medium.com/walletconnect/how-to-build-a-wallet-in-react-native-with-the-web3wallet-sdk-b6f57bf02f9a
import { retrieveAccounts } from '../accounts';
import { EIP155_CHAINS, TEIP155Chain } from './EIP155Lib';
import { utils } from 'ethers';
import { Account } from '../../types';
import { EIP155_CHAINS, TEIP155Chain } from './EIP155Lib';
/**
* Truncates string (in the middle) via given lenght value
*/
@ -67,6 +68,7 @@ export function getSignTypedDataParamsData(params: string[]) {
*/
export async function getAccountNumberFromParams(
addresses: string[],
ethAccounts: Account[],
params: any,
) {
const paramsString = JSON.stringify(params);
@ -78,9 +80,7 @@ export async function getAccountNumberFromParams(
}
});
const { ethLoadedAccounts } = await retrieveAccounts();
const currentAccount = ethLoadedAccounts!.find(
const currentAccount = ethAccounts!.find(
account => account.address === address,
);