Part of cerc-io/laconic-wallet-web#11 Co-authored-by: IshaVenikar <ishavenikar7@gmail.com> Reviewed-on: cerc-io/laconic-wallet-web#13
220 lines
6.8 KiB
TypeScript
220 lines
6.8 KiB
TypeScript
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { View, ActivityIndicator, Image } from 'react-native';
|
|
import { Button, Text } from 'react-native-paper';
|
|
|
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|
import { useNavigation } from '@react-navigation/native';
|
|
import { getSdkError } from '@walletconnect/utils';
|
|
import { Portal, Snackbar } from '@mui/material';
|
|
|
|
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
|
|
import { MnemonicDialog } from '../components/MnemonicDialog';
|
|
import ImportWalletDialog from '../components/ImportWalletDialog';
|
|
import { NetworkDropdown } from '../components/NetworkDropdown';
|
|
import Accounts from '../components/Accounts';
|
|
import CreateWallet from '../components/CreateWallet';
|
|
import ConfirmDialog from '../components/ConfirmDialog';
|
|
import styles from '../styles/stylesheet';
|
|
import { useAccounts } from '../context/AccountsContext';
|
|
import { useWalletConnect } from '../context/WalletConnectContext';
|
|
import { NetworksDataState, StackParamsList } from '../types';
|
|
import { useNetworks } from '../context/NetworksContext';
|
|
|
|
const WCLogo = () => {
|
|
return (
|
|
<Image
|
|
style={styles.walletConnectLogo}
|
|
source={require('../assets/WalletConnect-Icon-Blueberry.png')}
|
|
/>
|
|
);
|
|
};
|
|
|
|
const HomeScreen = () => {
|
|
const { accounts, setAccounts, setCurrentIndex } = useAccounts();
|
|
|
|
const { networksData, selectedNetwork, setSelectedNetwork, setNetworksData } =
|
|
useNetworks();
|
|
const { setActiveSessions, web3wallet } = useWalletConnect();
|
|
|
|
const navigation =
|
|
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
|
useEffect(() => {
|
|
if (accounts.length > 0) {
|
|
navigation.setOptions({
|
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
headerRight: () => (
|
|
<Button onPress={() => navigation.navigate('WalletConnect')}>
|
|
{<WCLogo />}
|
|
</Button>
|
|
),
|
|
});
|
|
} else {
|
|
navigation.setOptions({
|
|
headerRight: undefined,
|
|
});
|
|
}
|
|
}, [navigation, accounts]);
|
|
|
|
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
|
|
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);
|
|
const [importWalletDialog, setImportWalletDialog] = useState<boolean>(false);
|
|
const [mnemonicDialog, setMnemonicDialog] = useState<boolean>(false);
|
|
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
|
|
const [toastVisible, setToastVisible] = useState(false);
|
|
const [invalidMnemonicError, setInvalidMnemonicError] = useState('');
|
|
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(true);
|
|
const [phrase, setPhrase] = useState('');
|
|
|
|
const hideMnemonicDialog = () => setMnemonicDialog(false);
|
|
const hideResetDialog = () => setResetWalletDialog(false);
|
|
|
|
const fetchAccounts = useCallback(async () => {
|
|
if (!selectedNetwork) {
|
|
return;
|
|
}
|
|
|
|
const loadedAccounts = await retrieveAccounts(selectedNetwork);
|
|
|
|
if (loadedAccounts) {
|
|
setAccounts(loadedAccounts);
|
|
setIsWalletCreated(true);
|
|
}
|
|
|
|
setIsAccountsFetched(true);
|
|
}, [selectedNetwork, setAccounts]);
|
|
|
|
const createWalletHandler = async () => {
|
|
setIsWalletCreating(true);
|
|
const mnemonic = await createWallet(networksData);
|
|
if (mnemonic) {
|
|
fetchAccounts();
|
|
setMnemonicDialog(true);
|
|
setPhrase(mnemonic);
|
|
setSelectedNetwork(networksData[0]);
|
|
}
|
|
};
|
|
|
|
const importWalletHandler = async (recoveryPhrase: string) => {
|
|
try{
|
|
const mnemonic = await createWallet(networksData, recoveryPhrase);
|
|
if (mnemonic) {
|
|
fetchAccounts();
|
|
setPhrase(mnemonic);
|
|
setSelectedNetwork(networksData[0]);
|
|
setImportWalletDialog(false);
|
|
}
|
|
} catch (error: any) {
|
|
setInvalidMnemonicError((error.message as string).toUpperCase())
|
|
setToastVisible(true);
|
|
}
|
|
};
|
|
|
|
const confirmResetWallet = useCallback(async () => {
|
|
setIsWalletCreated(false);
|
|
setIsWalletCreating(false);
|
|
setAccounts([]);
|
|
setCurrentIndex(0);
|
|
setNetworksData([]);
|
|
setSelectedNetwork(undefined);
|
|
await resetWallet();
|
|
const sessions = web3wallet!.getActiveSessions();
|
|
|
|
Object.keys(sessions).forEach(async sessionId => {
|
|
await web3wallet!.disconnectSession({
|
|
topic: sessionId,
|
|
reason: getSdkError('USER_DISCONNECTED'),
|
|
});
|
|
});
|
|
setActiveSessions({});
|
|
|
|
hideResetDialog();
|
|
}, [
|
|
setAccounts,
|
|
setActiveSessions,
|
|
setCurrentIndex,
|
|
setNetworksData,
|
|
setSelectedNetwork,
|
|
web3wallet
|
|
]);
|
|
|
|
const updateNetwork = (networkData: NetworksDataState) => {
|
|
setSelectedNetwork(networkData);
|
|
setCurrentIndex(0);
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchAccounts();
|
|
}, [networksData, setAccounts, selectedNetwork, fetchAccounts]);
|
|
|
|
return (
|
|
<View style={styles.appContainer}>
|
|
{!isAccountsFetched ? (
|
|
<View style={styles.spinnerContainer}>
|
|
<Text style={styles.LoadingText}>Loading...</Text>
|
|
<ActivityIndicator size="large" color="#0000ff" />
|
|
</View>
|
|
) : isWalletCreated && selectedNetwork ? (
|
|
<>
|
|
<NetworkDropdown updateNetwork={updateNetwork} />
|
|
<View style={styles.accountComponent}>
|
|
<Accounts />
|
|
</View>
|
|
<View style={styles.resetContainer}>
|
|
<Button
|
|
style={styles.resetButton}
|
|
mode="contained"
|
|
buttonColor="#B82B0D"
|
|
onPress={() => {
|
|
setResetWalletDialog(true);
|
|
}}>
|
|
Reset Wallet
|
|
</Button>
|
|
</View>
|
|
</>
|
|
) : (
|
|
<>
|
|
<CreateWallet
|
|
isWalletCreating={isWalletCreating}
|
|
createWalletHandler={createWalletHandler}
|
|
/>
|
|
<View style={styles.createWalletContainer}>
|
|
<Button
|
|
mode="contained"
|
|
onPress={() => setImportWalletDialog(true)}>
|
|
Import Wallet
|
|
</Button>
|
|
</View>
|
|
</>
|
|
)}
|
|
<ImportWalletDialog
|
|
visible={importWalletDialog}
|
|
hideDialog={() => setImportWalletDialog(false)}
|
|
importWalletHandler={importWalletHandler}
|
|
/>
|
|
<MnemonicDialog
|
|
visible={mnemonicDialog}
|
|
hideDialog={hideMnemonicDialog}
|
|
contentText={phrase}
|
|
/>
|
|
<ConfirmDialog
|
|
title="Reset wallet"
|
|
visible={resetWalletDialog}
|
|
hideDialog={hideResetDialog}
|
|
onConfirm={confirmResetWallet}
|
|
/>
|
|
<Portal>
|
|
<Snackbar
|
|
open={toastVisible}
|
|
autoHideDuration={3000}
|
|
message={invalidMnemonicError}
|
|
onClose={() => setToastVisible(false)}
|
|
anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}
|
|
ContentProps={{ style: { backgroundColor: 'red', color: 'white'} }}
|
|
/>
|
|
</Portal>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default HomeScreen;
|