Add support to configure networks (#76)

* Add support to configure cosmos networks

* Fix intents functionality for configured networks

* Add address prefix while initializing stargate client

* Remove unnecessary functions

* Update style for add network page

* Handle review changes

* Fix eth accounts not showing up on configured eth chain
This commit is contained in:
shreerang6921 2024-04-03 19:07:30 +05:30 committed by Nabarun Gogoi
parent bdd1b58140
commit e4fe88939c
11 changed files with 270 additions and 111 deletions

View File

@ -1,30 +1,22 @@
import React, { useMemo, useState } from 'react'; import React, { useState } from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { List } from 'react-native-paper'; import { List } from 'react-native-paper';
import { NetworkDropdownProps } from '../types'; import { NetworkDropdownProps, NetworksDataState } from '../types';
import styles from '../styles/stylesheet'; import styles from '../styles/stylesheet';
import { useAccounts } from '../context/AccountsContext'; import { useAccounts } from '../context/AccountsContext';
const NetworkDropdown = ({ updateNetwork }: NetworkDropdownProps) => { const NetworkDropdown = ({ updateNetwork }: NetworkDropdownProps) => {
const [expanded, setExpanded] = useState<boolean>(false);
const [selectedNetwork, setSelectedNetwork] = useState<string>('Ethereum');
const { networksData } = useAccounts(); const { networksData } = useAccounts();
const networks = useMemo(() => { const [expanded, setExpanded] = useState<boolean>(false);
return networksData.map(network => { const [selectedNetwork, setSelectedNetwork] = useState<string>(
return { networksData[0].networkName,
value: network.networkType, );
chainId: network.chainId,
displayName: network.networkName,
};
});
}, [networksData]);
const handleNetworkPress = (network: string, displayName: string) => { const handleNetworkPress = (networksData: NetworksDataState) => {
updateNetwork(network); updateNetwork(networksData);
setSelectedNetwork(displayName); setSelectedNetwork(networksData.networkName);
setExpanded(false); setExpanded(false);
}; };
@ -34,13 +26,11 @@ const NetworkDropdown = ({ updateNetwork }: NetworkDropdownProps) => {
title={selectedNetwork} title={selectedNetwork}
expanded={expanded} expanded={expanded}
onPress={() => setExpanded(!expanded)}> onPress={() => setExpanded(!expanded)}>
{networks.map(network => ( {networksData.map(networkData => (
<List.Item <List.Item
key={network.chainId} key={networkData.chainId}
title={network.displayName} title={networkData.networkName}
onPress={() => onPress={() => handleNetworkPress(networkData)}
handleNetworkPress(network.value, network.displayName)
}
/> />
))} ))}
</List.Accordion> </List.Accordion>

View File

@ -0,0 +1,48 @@
import React, { useState } from 'react';
import { View } from 'react-native';
import { Text, List } from 'react-native-paper';
import styles from '../styles/stylesheet';
const SelectNetworkType = ({
updateNetworkType,
}: {
updateNetworkType: (networkType: string) => void;
}) => {
const [expanded, setExpanded] = useState<boolean>(false);
const [selectedNetwork, setSelectedNetwork] = useState<string>('ETH');
const networks = ['ETH', 'COSMOS'];
const handleNetworkPress = (network: string) => {
setSelectedNetwork(network);
updateNetworkType(network.toLowerCase());
setExpanded(false);
};
return (
<View style={styles.networkDropdown}>
<Text
style={{
fontWeight: 'bold',
marginBottom: 10,
}}>
Select Network Type
</Text>
<List.Accordion
title={selectedNetwork}
expanded={expanded}
onPress={() => setExpanded(!expanded)}>
{networks.map(network => (
<List.Item
key={network}
title={network}
onPress={() => handleNetworkPress(network)}
/>
))}
</List.Accordion>
</View>
);
};
export { SelectNetworkType };

View File

@ -34,6 +34,7 @@ const AccountsProvider = ({ children }: { children: any }) => {
ethAccounts: [], ethAccounts: [],
cosmosAccounts: [], cosmosAccounts: [],
}); });
// TODO: Replace chainId values with testnet chainIds
const [networksData, setNetworksData] = useState<NetworksDataState[]>([ const [networksData, setNetworksData] = useState<NetworksDataState[]>([
{ {
chainId: 'eip155:11155111', chainId: 'eip155:11155111',
@ -47,7 +48,9 @@ const AccountsProvider = ({ children }: { children: any }) => {
networkName: COSMOS_TESTNET_CHAINS['cosmos:theta-testnet-001'].name, networkName: COSMOS_TESTNET_CHAINS['cosmos:theta-testnet-001'].name,
networkType: 'cosmos', networkType: 'cosmos',
rpcUrl: COSMOS_TESTNET_CHAINS['cosmos:theta-testnet-001'].rpc, rpcUrl: COSMOS_TESTNET_CHAINS['cosmos:theta-testnet-001'].rpc,
currencySymbol: 'ATOM', nativeDenom: 'ATOM',
addressPrefix: 'cosmos',
coinType: '118',
}, },
]); ]);
const [currentIndex, setCurrentIndex] = useState<number>(0); const [currentIndex, setCurrentIndex] = useState<number>(0);

View File

@ -1,13 +1,15 @@
import React from 'react'; import React, { useCallback, useState } from 'react';
import { View } from 'react-native'; import { ScrollView } from 'react-native';
import { useForm, Controller } from 'react-hook-form'; import { useForm, Controller } from 'react-hook-form';
import { TextInput, Button, HelperText } from 'react-native-paper'; import { TextInput, Button, HelperText } from 'react-native-paper';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import styles from '../styles/stylesheet'; import styles from '../styles/stylesheet';
import { NetworksDataState, StackParamsList } from '../types'; import { NetworksDataState, StackParamsList } from '../types';
import { useAccounts } from '../context/AccountsContext'; import { useAccounts } from '../context/AccountsContext';
import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { SelectNetworkType } from '../components/SelectNetworkType';
import { useNavigation } from '@react-navigation/native';
// TODO: Add validation to form inputs // TODO: Add validation to form inputs
const AddNetwork = () => { const AddNetwork = () => {
@ -24,12 +26,28 @@ const AddNetwork = () => {
const { networksData, setNetworksData } = useAccounts(); const { networksData, setNetworksData } = useAccounts();
const submit = (data: NetworksDataState) => { const [networkType, setNetworkType] = useState<string>('eth');
setNetworksData([...networksData, data]);
navigation.navigate('Laconic'); // TODO: Update session when new network is added with updated addresses
const updateNetworkType = (newNetworkType: string) => {
setNetworkType(newNetworkType);
}; };
const submit = useCallback(
async (data: NetworksDataState) => {
const updatedData = {
...data,
networkType,
};
setNetworksData([...networksData, updatedData]);
navigation.navigate('Laconic');
},
[navigation, networkType, networksData, setNetworksData],
);
return ( return (
<View style={styles.signPage}> // TODO: get form data from json file
<ScrollView contentContainerStyle={styles.addNetwork}>
<Controller <Controller
control={control} control={control}
defaultValue="" defaultValue=""
@ -81,23 +99,6 @@ const AddNetwork = () => {
</> </>
)} )}
/> />
<Controller
control={control}
name="currencySymbol"
defaultValue=""
render={({ field: { onChange, onBlur, value } }) => (
<>
<TextInput
mode="outlined"
value={value}
label="Currency Symbol"
onBlur={onBlur}
onChangeText={value => onChange(value)}
/>
</>
)}
/>
<HelperText type="error">{errors.currencySymbol?.message}</HelperText>
<Controller <Controller
control={control} control={control}
defaultValue="" defaultValue=""
@ -111,35 +112,99 @@ const AddNetwork = () => {
onBlur={onBlur} onBlur={onBlur}
onChangeText={value => onChange(value)} onChangeText={value => onChange(value)}
/> />
<HelperText type="error">
{errors.blockExplorerUrl?.message}
</HelperText>
</> </>
)} )}
/> />
<HelperText type="error">{errors.blockExplorerUrl?.message}</HelperText> <SelectNetworkType updateNetworkType={updateNetworkType} />
<Controller {networkType === 'eth' ? (
control={control} <Controller
// TODO: Use state to toggle between 'eth' and 'cosmos' control={control}
defaultValue="eth" name="currencySymbol"
name="networkType" defaultValue=""
render={({ field: { onBlur, value } }) => ( render={({ field: { onChange, onBlur, value } }) => (
<> <>
<TextInput <TextInput
mode="outlined" mode="outlined"
value={value} value={value}
disabled label="Currency Symbol"
label="Block Explorer URL (Optional)" onBlur={onBlur}
onBlur={onBlur} onChangeText={value => onChange(value)}
/> />
</> <HelperText type="error">
)} {errors.currencySymbol?.message}
/> </HelperText>
<HelperText type="error">{errors.blockExplorerUrl?.message}</HelperText> </>
)}
/>
) : (
<>
<Controller
control={control}
name="nativeDenom"
defaultValue=""
render={({ field: { onChange, onBlur, value } }) => (
<>
<TextInput
mode="outlined"
value={value}
label="Native Denom"
onBlur={onBlur}
onChangeText={value => onChange(value)}
/>
<HelperText type="error">
{errors.nativeDenom?.message}
</HelperText>
</>
)}
/>
<Controller
control={control}
name="addressPrefix"
defaultValue=""
render={({ field: { onChange, onBlur, value } }) => (
<>
<TextInput
mode="outlined"
value={value}
label="Address Prefix"
onBlur={onBlur}
onChangeText={value => onChange(value)}
/>
<HelperText type="error">
{errors.addressPrefix?.message}
</HelperText>
</>
)}
/>
<Controller
control={control}
name="coinType"
defaultValue=""
render={({ field: { onChange, onBlur, value } }) => (
<>
<TextInput
mode="outlined"
value={value}
label="Coin Type"
onBlur={onBlur}
onChangeText={value => onChange(value)}
/>
<HelperText type="error">{errors.coinType?.message}</HelperText>
</>
)}
/>
</>
)}
<Button <Button
mode="contained" mode="contained"
onPress={handleSubmit(submit)} onPress={handleSubmit(submit)}
disabled={!isValid}> disabled={!isValid}>
Submit Submit
</Button> </Button>
</View> </ScrollView>
); );
}; };

View File

@ -55,19 +55,19 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
const [cosmosStargateClient, setCosmosStargateClient] = const [cosmosStargateClient, setCosmosStargateClient] =
useState<SigningStargateClient>(); useState<SigningStargateClient>();
const requestedChain = networksData.find(
networkData => networkData.chainId === chainId,
);
const provider = useMemo(() => { const provider = useMemo(() => {
if (network === 'eth') { if (network === 'eth') {
const currentChain = networksData.find( if (!requestedChain) {
networkData => networkData.chainId === chainId,
);
if (!currentChain) {
throw new Error('Requested chain not supported'); throw new Error('Requested chain not supported');
} }
return new providers.JsonRpcProvider(currentChain.rpcUrl); return new providers.JsonRpcProvider(requestedChain.rpcUrl);
} }
}, [chainId, network, networksData]); }, [requestedChain, network]);
const navigation = const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>(); useNavigation<NativeStackNavigationProp<StackParamsList>>();
@ -77,6 +77,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
const requestAccount = await retrieveSingleAccount( const requestAccount = await retrieveSingleAccount(
network, network,
requestAddress, requestAddress,
requestedChain?.addressPrefix,
); );
if (!requestAccount) { if (!requestAccount) {
navigation.navigate('InvalidPath'); navigation.navigate('InvalidPath');
@ -86,7 +87,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
setAccount(requestAccount); setAccount(requestAccount);
setIsLoading(false); setIsLoading(false);
}, },
[navigation, network], [navigation, network, requestedChain],
); );
const gasFees = useMemo(() => { const gasFees = useMemo(() => {
@ -199,6 +200,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
const sender = await DirectSecp256k1Wallet.fromKey( const sender = await DirectSecp256k1Wallet.fromKey(
Buffer.from(cosmosPrivKey.split('0x')[1], 'hex'), Buffer.from(cosmosPrivKey.split('0x')[1], 'hex'),
requestedChain?.addressPrefix,
); );
const client = await SigningStargateClient.connectWithSigner( const client = await SigningStargateClient.connectWithSigner(
@ -210,7 +212,7 @@ const ApproveTransaction = ({ route }: SignRequestProps) => {
}; };
setClient(); setClient();
}, [account, chainId, network]); }, [account, requestedChain, chainId, network]);
return ( return (
<> <>

View File

@ -15,7 +15,7 @@ import ResetWalletDialog from '../components/ResetWalletDialog';
import styles from '../styles/stylesheet'; import styles from '../styles/stylesheet';
import { useAccounts } from '../context/AccountsContext'; import { useAccounts } from '../context/AccountsContext';
import { useWalletConnect } from '../context/WalletConnectContext'; import { useWalletConnect } from '../context/WalletConnectContext';
import { StackParamsList } from '../types'; import { NetworksDataState, StackParamsList } from '../types';
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
const WCLogo = () => { const WCLogo = () => {
@ -35,6 +35,7 @@ const HomeScreen = () => {
setCurrentIndex, setCurrentIndex,
networkType, networkType,
setNetworkType, setNetworkType,
networksData,
} = useAccounts(); } = useAccounts();
const { setActiveSessions } = useWalletConnect(); const { setActiveSessions } = useWalletConnect();
@ -59,6 +60,9 @@ const HomeScreen = () => {
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false); const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false); const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);
const [walletDialog, setWalletDialog] = useState<boolean>(false); const [walletDialog, setWalletDialog] = useState<boolean>(false);
const [currentChainId, setCurrentChainId] = useState<string>(
networksData[0].chainId,
);
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false); const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(false); const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(false);
const [phrase, setPhrase] = useState(''); const [phrase, setPhrase] = useState('');
@ -103,8 +107,9 @@ const HomeScreen = () => {
setNetworkType('eth'); setNetworkType('eth');
}; };
const updateNetwork = (newNetwork: string) => { const updateNetwork = (networksData: NetworksDataState) => {
setNetworkType(newNetwork); setNetworkType(networksData.networkType);
setCurrentChainId(networksData.chainId);
setCurrentIndex(0); setCurrentIndex(0);
}; };
@ -114,18 +119,25 @@ const HomeScreen = () => {
useEffect(() => { useEffect(() => {
const fetchAccounts = async () => { const fetchAccounts = async () => {
if (isAccountsFetched) { if (!currentChainId) {
return; return;
} }
const { ethLoadedAccounts, cosmosLoadedAccounts } =
await retrieveAccounts();
if (ethLoadedAccounts && cosmosLoadedAccounts) { const currentNetwork = networksData.find(
networkData => networkData.chainId === currentChainId,
);
if (!currentNetwork) {
throw new Error('Current Network not found');
}
const { ethLoadedAccounts, cosmosLoadedAccounts } =
await retrieveAccounts(currentNetwork.addressPrefix);
if (cosmosLoadedAccounts && ethLoadedAccounts) {
setAccounts({ setAccounts({
ethAccounts: ethLoadedAccounts, ethAccounts: ethLoadedAccounts,
cosmosAccounts: cosmosLoadedAccounts, cosmosAccounts: cosmosLoadedAccounts,
}); });
setIsWalletCreated(true); setIsWalletCreated(true);
} }
@ -133,7 +145,7 @@ const HomeScreen = () => {
}; };
fetchAccounts(); fetchAccounts();
}, [isAccountsFetched, setAccounts]); }, [currentChainId, networksData, setAccounts]);
return ( return (
<View style={styles.appContainer}> <View style={styles.appContainer}>
@ -144,10 +156,7 @@ const HomeScreen = () => {
</View> </View>
) : isWalletCreated ? ( ) : isWalletCreated ? (
<> <>
<NetworkDropdown <NetworkDropdown updateNetwork={updateNetwork} />
selectedNetwork={networkType}
updateNetwork={updateNetwork}
/>
<View style={styles.accountComponent}> <View style={styles.accountComponent}>
<Accounts <Accounts
network={networkType} network={networkType}

View File

@ -21,10 +21,13 @@ import {
} from '../utils/wallet-connect/WalletConnectRequests'; } from '../utils/wallet-connect/WalletConnectRequests';
import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils'; import { web3wallet } from '../utils/wallet-connect/WalletConnectUtils';
import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data'; import { EIP155_SIGNING_METHODS } from '../utils/wallet-connect/EIP155Data';
import { useAccounts } from '../context/AccountsContext';
type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>; type SignRequestProps = NativeStackScreenProps<StackParamsList, 'SignRequest'>;
const SignRequest = ({ route }: SignRequestProps) => { const SignRequest = ({ route }: SignRequestProps) => {
const { networksData } = useAccounts();
const requestSession = route.params.requestSessionData; const requestSession = route.params.requestSessionData;
const requestName = requestSession?.peer?.metadata?.name; const requestName = requestSession?.peer?.metadata?.name;
const requestIcon = requestSession?.peer?.metadata?.icons[0]; const requestIcon = requestSession?.peer?.metadata?.icons[0];
@ -35,6 +38,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
const [network, setNetwork] = useState<string>(''); const [network, setNetwork] = useState<string>('');
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isApproving, setIsApproving] = useState(false); const [isApproving, setIsApproving] = useState(false);
const [isRejecting, setIsRejecting] = useState(false);
const navigation = const navigation =
useNavigation<NativeStackNavigationProp<StackParamsList>>(); useNavigation<NativeStackNavigationProp<StackParamsList>>();
@ -68,9 +72,16 @@ const SignRequest = ({ route }: SignRequestProps) => {
requestAddress: string, requestAddress: string,
requestMessage: string, requestMessage: string,
) => { ) => {
const currentChain = networksData.find(networkData => {
if (networkData.addressPrefix) {
return requestAddress.includes(networkData.addressPrefix);
}
});
const requestAccount = await retrieveSingleAccount( const requestAccount = await retrieveSingleAccount(
requestNetwork, requestNetwork,
requestAddress, requestAddress,
currentChain?.addressPrefix,
); );
if (!requestAccount) { if (!requestAccount) {
navigation.navigate('InvalidPath'); navigation.navigate('InvalidPath');
@ -88,7 +99,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
} }
setIsLoading(false); setIsLoading(false);
}, },
[account, message, navigation, network], [account, message, navigation, network, networksData],
); );
const sanitizePath = useCallback( const sanitizePath = useCallback(
@ -178,6 +189,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
}; };
const rejectRequestHandler = async () => { const rejectRequestHandler = async () => {
setIsRejecting(true);
if (route.params?.requestEvent) { if (route.params?.requestEvent) {
const response = rejectWalletConnectRequest(route.params?.requestEvent); const response = rejectWalletConnectRequest(route.params?.requestEvent);
const { topic } = route.params?.requestEvent; const { topic } = route.params?.requestEvent;
@ -186,6 +198,8 @@ const SignRequest = ({ route }: SignRequestProps) => {
response, response,
}); });
} }
setIsRejecting(false);
navigation.navigate('Laconic'); navigation.navigate('Laconic');
}; };
@ -263,6 +277,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
<Button <Button
mode="contained" mode="contained"
onPress={rejectRequestHandler} onPress={rejectRequestHandler}
loading={isRejecting}
buttonColor="#B82B0D"> buttonColor="#B82B0D">
No No
</Button> </Button>

View File

@ -48,6 +48,10 @@ const styles = StyleSheet.create({
signPage: { signPage: {
paddingHorizontal: 24, paddingHorizontal: 24,
}, },
addNetwork: {
paddingHorizontal: 24,
marginTop: 30,
},
accountInfo: { accountInfo: {
marginTop: 12, marginTop: 12,
marginBottom: 30, marginBottom: 30,

View File

@ -45,12 +45,7 @@ export type AccountsProps = {
}; };
export type NetworkDropdownProps = { export type NetworkDropdownProps = {
selectedNetwork: string; updateNetwork: (networksData: NetworksDataState) => void;
updateNetwork: (network: string) => void;
customNetwork?: {
value: string;
displayName: string;
};
}; };
export type AccountsState = { export type AccountsState = {
@ -62,9 +57,12 @@ export type NetworksDataState = {
networkName: string; networkName: string;
rpcUrl: string; rpcUrl: string;
chainId: string; chainId: string;
currencySymbol: string; currencySymbol?: string;
blockExplorerUrl?: string; blockExplorerUrl?: string;
networkType: string; networkType: string;
nativeDenom?: string;
addressPrefix?: string;
coinType?: string;
}; };
export type SignMessageParams = { export type SignMessageParams = {

View File

@ -124,16 +124,17 @@ const addAccountFromHDPath = async (
} }
}; };
const retrieveAccountsForNetwork = async ( export const retrieveAccountsForNetwork = async (
network: string, network: string,
count: string, accountsIndices: string,
prefix: string = 'cosmos',
): Promise<Account[]> => { ): Promise<Account[]> => {
const elementsArray = count.split(','); const accountsIndexArray = accountsIndices.split(',');
const loadedAccounts = await Promise.all( const loadedAccounts = await Promise.all(
elementsArray.map(async i => { accountsIndexArray.map(async i => {
const pubKey = (await getPathKey(network, Number(i))).pubKey; const pubKey = (await getPathKey(network, Number(i), prefix)).pubKey;
const address = (await getPathKey(network, Number(i))).address; const address = (await getPathKey(network, Number(i), prefix)).address;
const path = (await getPathKey(network, Number(i))).path; const path = (await getPathKey(network, Number(i))).path;
const hdPath = getHDPath(network, path); const hdPath = getHDPath(network, path);
@ -150,7 +151,9 @@ const retrieveAccountsForNetwork = async (
return loadedAccounts; return loadedAccounts;
}; };
const retrieveAccounts = async (): Promise<{ const retrieveAccounts = async (
prefix: string = 'cosmos',
): Promise<{
ethLoadedAccounts?: Account[]; ethLoadedAccounts?: Account[];
cosmosLoadedAccounts?: Account[]; cosmosLoadedAccounts?: Account[];
}> => { }> => {
@ -163,13 +166,17 @@ const retrieveAccounts = async (): Promise<{
? await retrieveAccountsForNetwork('eth', ethCounter) ? await retrieveAccountsForNetwork('eth', ethCounter)
: undefined; : undefined;
const cosmosLoadedAccounts = cosmosCounter const cosmosLoadedAccounts = cosmosCounter
? await retrieveAccountsForNetwork('cosmos', cosmosCounter) ? await retrieveAccountsForNetwork('cosmos', cosmosCounter, prefix)
: undefined; : undefined;
return { ethLoadedAccounts, cosmosLoadedAccounts }; return { ethLoadedAccounts, cosmosLoadedAccounts };
}; };
const retrieveSingleAccount = async (network: string, address: string) => { const retrieveSingleAccount = async (
network: string,
address: string,
prefix: string = 'cosmos',
) => {
let loadedAccounts; let loadedAccounts;
switch (network) { switch (network) {
@ -190,6 +197,7 @@ const retrieveSingleAccount = async (network: string, address: string) => {
loadedAccounts = await retrieveAccountsForNetwork( loadedAccounts = await retrieveAccountsForNetwork(
network, network,
cosmosCounter, cosmosCounter,
prefix,
); );
} }
break; break;
@ -228,6 +236,7 @@ const accountInfoFromHDPath = async (
| { privKey: string; pubKey: string; address: string; network: string } | { privKey: string; pubKey: string; address: string; network: string }
| undefined | undefined
> => { > => {
// TODO: move HDNode inside eth switch case
const mnemonicStore = await getInternetCredentials('mnemonicServer'); const mnemonicStore = await getInternetCredentials('mnemonicServer');
if (!mnemonicStore) { if (!mnemonicStore) {
throw new Error('Mnemonic not found!'); throw new Error('Mnemonic not found!');

View File

@ -10,7 +10,7 @@ import {
setInternetCredentials, setInternetCredentials,
} from 'react-native-keychain'; } from 'react-native-keychain';
import { AccountData } from '@cosmjs/amino'; import { AccountData, Secp256k1Wallet } from '@cosmjs/amino';
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';
import { stringToPath } from '@cosmjs/crypto'; import { stringToPath } from '@cosmjs/crypto';
@ -44,6 +44,7 @@ export const getDirectWallet = async (
const getPathKey = async ( const getPathKey = async (
network: string, network: string,
accountId: number, accountId: number,
prefix: string = 'cosmos',
): Promise<{ ): Promise<{
path: string; path: string;
privKey: string; privKey: string;
@ -62,8 +63,23 @@ const getPathKey = async (
const pathkey = pathKeyVal.split(','); const pathkey = pathKeyVal.split(',');
const path = pathkey[0]; const path = pathkey[0];
const privKey = pathkey[1]; const privKey = pathkey[1];
const pubKey = pathkey[2];
const address = pathkey[3]; let pubKey: string;
let address: string;
if (network === 'eth') {
pubKey = pathkey[2];
address = pathkey[3];
} else {
// TODO: Store pubkey and address for cosmos instead of deriving
const wallet = await Secp256k1Wallet.fromKey(
Uint8Array.from(Buffer.from(privKey.split('0x')[1], 'hex')),
prefix,
);
const currAccount = await wallet.getAccounts();
pubKey = '0x' + Buffer.from(currAccount[0].pubkey).toString('hex');
address = currAccount[0].address;
}
return { path, privKey, pubKey, address }; return { path, privKey, pubKey, address };
}; };