forked from cerc-io/laconic-wallet
Add new account using hd path given by user
This commit is contained in:
parent
dbaf43f98c
commit
49613ef52f
@ -14,7 +14,7 @@ const Accounts: React.FC<AccountsProps> = ({
|
|||||||
accounts,
|
accounts,
|
||||||
updateAccounts,
|
updateAccounts,
|
||||||
currentIndex,
|
currentIndex,
|
||||||
updateIndex,
|
updateIndex: updateId,
|
||||||
}) => {
|
}) => {
|
||||||
const navigation =
|
const navigation =
|
||||||
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
useNavigation<NativeStackNavigationProp<StackParamsList>>();
|
||||||
@ -29,7 +29,7 @@ const Accounts: React.FC<AccountsProps> = ({
|
|||||||
setIsAccountCreating(false);
|
setIsAccountCreating(false);
|
||||||
if (newAccount) {
|
if (newAccount) {
|
||||||
updateAccounts(newAccount);
|
updateAccounts(newAccount);
|
||||||
updateIndex(newAccount.id);
|
updateId(newAccount.id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ const Accounts: React.FC<AccountsProps> = ({
|
|||||||
key={account.id}
|
key={account.id}
|
||||||
title={`Account ${account.id + 1}`}
|
title={`Account ${account.id + 1}`}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
updateIndex(account.id);
|
updateId(account.id);
|
||||||
setExpanded(false);
|
setExpanded(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
63
components/HDPath.tsx
Normal file
63
components/HDPath.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { ScrollView, View, Alert } from 'react-native';
|
||||||
|
import { Button, Text, TextInput } from 'react-native-paper';
|
||||||
|
|
||||||
|
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
||||||
|
|
||||||
|
import { StackParamsList } from '../types';
|
||||||
|
import { accountFromHDPath } from '../utils';
|
||||||
|
|
||||||
|
type HDPathProps = NativeStackScreenProps<StackParamsList, 'HDPath'>;
|
||||||
|
|
||||||
|
const HDPath: React.FC<HDPathProps> = ({}) => {
|
||||||
|
const [path, setPath] = useState<string>('');
|
||||||
|
const [account, setAccount] = useState<any>(null);
|
||||||
|
const [isAccountCreating, setIsAccountCreating] = useState(false);
|
||||||
|
|
||||||
|
const createFromHDPathHandler = async () => {
|
||||||
|
setIsAccountCreating(true);
|
||||||
|
const newAccount = await accountFromHDPath(path);
|
||||||
|
setIsAccountCreating(false);
|
||||||
|
setAccount(newAccount);
|
||||||
|
Alert.alert('Account Created');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={{ marginTop: 24, paddingHorizontal: 24 }}>
|
||||||
|
<View style={{ marginTop: 24, marginBottom: 30 }}>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={{ fontWeight: '700' }}>Enter the HD Path: </Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<TextInput
|
||||||
|
mode="outlined"
|
||||||
|
onChangeText={text => setPath(text)}
|
||||||
|
value={path}
|
||||||
|
/>
|
||||||
|
<View style={{ marginTop: 20, width: 200, alignSelf: 'center' }}>
|
||||||
|
<Button
|
||||||
|
mode="contained"
|
||||||
|
onPress={createFromHDPathHandler}
|
||||||
|
loading={isAccountCreating}>
|
||||||
|
{isAccountCreating ? 'Adding' : 'Add Account'}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View style={{ marginTop: 24 }}>
|
||||||
|
{account && (
|
||||||
|
<>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={{ fontWeight: '700' }}>Address: </Text>
|
||||||
|
{account.address}
|
||||||
|
</Text>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={{ fontWeight: '700' }}>Public Key: </Text>
|
||||||
|
{account.pubKey}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HDPath;
|
1
types.ts
1
types.ts
@ -1,6 +1,7 @@
|
|||||||
export type StackParamsList = {
|
export type StackParamsList = {
|
||||||
Laconic: undefined;
|
Laconic: undefined;
|
||||||
SignMessage: { selectedNetwork: string; accountInfo: Account } | undefined;
|
SignMessage: { selectedNetwork: string; accountInfo: Account } | undefined;
|
||||||
|
HDPath: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Account = {
|
export type Account = {
|
||||||
|
38
utils.ts
38
utils.ts
@ -130,6 +130,36 @@ const addAccount = async (network: string): Promise<Account | undefined> => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const accountFromHDPath = async (
|
||||||
|
hdPath: string,
|
||||||
|
): Promise<
|
||||||
|
| {
|
||||||
|
pubKey: string;
|
||||||
|
address: string;
|
||||||
|
}
|
||||||
|
| undefined
|
||||||
|
> => {
|
||||||
|
try {
|
||||||
|
const mnemonicStore = await getInternetCredentials('mnemonicServer');
|
||||||
|
if (!mnemonicStore) {
|
||||||
|
throw new Error('Mnemonic not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const mnemonic = mnemonicStore.password;
|
||||||
|
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||||
|
|
||||||
|
const node = hdNode.derivePath(hdPath);
|
||||||
|
|
||||||
|
const pubKey = node.publicKey;
|
||||||
|
const address = node.address;
|
||||||
|
|
||||||
|
return { pubKey, address };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating account:', error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const signMessage = async ({
|
const signMessage = async ({
|
||||||
message,
|
message,
|
||||||
network,
|
network,
|
||||||
@ -253,4 +283,10 @@ const resetWallet = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { createWallet, addAccount, signMessage, resetWallet };
|
export {
|
||||||
|
createWallet,
|
||||||
|
addAccount,
|
||||||
|
signMessage,
|
||||||
|
resetWallet,
|
||||||
|
accountFromHDPath,
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user