forked from cerc-io/laconic-wallet
Use context for maintaining accounts state (#41)
* Use context for maintaining accounts state * Remove custom hook from context
This commit is contained in:
parent
19e39281a6
commit
a4e0dc5406
31
App.tsx
31
App.tsx
@ -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();
|
||||
const currentEthAddresses = useMemo(() => {
|
||||
if (accounts.ethAccounts.length > 0) {
|
||||
return accounts.ethAccounts.map(account => account.address);
|
||||
}
|
||||
|
||||
if (ethLoadedAccounts) {
|
||||
const ethAddreses = ethLoadedAccounts.map(account => account.address);
|
||||
setCurrentEthAddresses(ethAddreses);
|
||||
}
|
||||
};
|
||||
|
||||
fetchEthAccounts();
|
||||
// TODO: Use context to maintain accounts state
|
||||
}, [modalVisible]);
|
||||
return [];
|
||||
}, [accounts]);
|
||||
|
||||
const linking = {
|
||||
prefixes: ['https://www.laconic-wallet.com'],
|
||||
|
@ -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);
|
||||
|
@ -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}>
|
||||
|
@ -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,
|
||||
|
25
context/AccountsContext.tsx
Normal file
25
context/AccountsContext.tsx
Normal 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 };
|
5
index.js
5
index.js
@ -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>
|
||||
<App />
|
||||
<AccountsProvider>
|
||||
<App />
|
||||
</AccountsProvider>
|
||||
</PaperProvider>
|
||||
);
|
||||
}
|
||||
|
5
types.ts
5
types.ts
@ -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 = {
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user