laconic-wallet/components/Accounts.tsx
Adwait Gharpure 1f0e8aecd4
Update sessions on adding accounts (#53)
* Replace QR icon with WC logo

* Change screen title

* Change title

* Display session topic in list item

* Move useEffect to WalletConnectContext

* Disconnect sessions on resetting wallet

* Update dapp session on adding account

* Update sessions inside useEffect

* Remove button from toast

* Clean up code

* Remove question mark

* Remove label from snackbar

---------

Co-authored-by: Adw8 <adwait@deepstacksoft.com>
2024-03-13 19:04:12 +05:30

174 lines
5.1 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { ScrollView, TouchableOpacity, View } from 'react-native';
import { Button, List, Text, useTheme } from 'react-native-paper';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { AccountsProps, StackParamsList, Account } from '../types';
import { addAccount } from '../utils/accounts';
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';
const Accounts = ({
network,
currentIndex,
updateIndex: updateId,
}: AccountsProps) => {
const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>();
const { accounts, setAccounts } = useAccounts();
const [expanded, setExpanded] = useState(false);
const [isAccountCreating, setIsAccountCreating] = useState(false);
const [hdDialog, setHdDialog] = useState(false);
const [pathCode, setPathCode] = useState('');
const theme = useTheme();
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!');
}
};
useEffect(() => {
const updateSessions = async () => {
const sessions = web3wallet.getActiveSessions();
for (const sessionId in sessions) {
const session = sessions[sessionId];
const requiredNamespaces = session.requiredNamespaces;
const namespaces = session.namespaces;
if (namespaces.hasOwnProperty('eip155')) {
requiredNamespaces.eip155.chains?.forEach(chainId => {
namespaces.eip155.accounts = accounts.ethAccounts.map(
ethAccount => `${chainId}:${ethAccount.address}`,
);
});
}
if (namespaces.hasOwnProperty('cosmos')) {
requiredNamespaces?.cosmos.chains?.forEach(chainId => {
namespaces.cosmos.accounts = accounts.cosmosAccounts.map(
cosmosAccount => `${chainId}:${cosmosAccount.address}`,
);
});
}
await web3wallet.updateSession({ topic: sessionId, namespaces });
}
};
updateSessions();
}, [accounts]);
const addAccountHandler = async () => {
setIsAccountCreating(true);
const newAccount = await addAccount(network);
setIsAccountCreating(false);
if (newAccount) {
updateAccounts(newAccount);
updateId(newAccount.counterId);
}
};
const selectedAccounts: Account[] = (() => {
switch (network) {
case 'eth':
return accounts.ethAccounts;
case 'cosmos':
return accounts.cosmosAccounts;
default:
return [];
}
})();
const renderAccountItems = () =>
selectedAccounts.map(account => (
<List.Item
key={account.counterId}
title={`Account ${account.counterId + 1}`}
onPress={() => {
updateId(account.counterId);
setExpanded(false);
}}
/>
));
return (
<ScrollView>
<View>
<HDPathDialog
visible={hdDialog}
hideDialog={() => setHdDialog(false)}
updateAccounts={updateAccounts}
updateIndex={updateId}
pathCode={pathCode}
/>
<List.Accordion
title={`Account ${currentIndex + 1}`}
expanded={expanded}
onPress={handlePress}>
{renderAccountItems()}
</List.Accordion>
<View style={styles.addAccountButton}>
<Button
mode="contained"
onPress={addAccountHandler}
loading={isAccountCreating}>
{isAccountCreating ? 'Adding' : 'Add Account'}
</Button>
</View>
<View style={styles.addAccountButton}>
<Button
mode="contained"
onPress={() => {
setHdDialog(true);
setPathCode(network === 'eth' ? "m/44'/60'/" : "m/44'/118'/");
}}>
Add Account from HD path
</Button>
</View>
<AccountDetails account={selectedAccounts[currentIndex]} />
<View style={styles.signLink}>
<TouchableOpacity
onPress={() => {
navigation.navigate('SignMessage', {
selectedNetwork: network,
accountInfo: selectedAccounts[currentIndex],
});
}}>
<Text
variant="titleSmall"
style={[styles.hyperlink, { color: theme.colors.primary }]}>
Sign Message
</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
};
export default Accounts;