forked from cerc-io/laconic-wallet
Retrieve accounts on reload (#29)
* Display HD path on sign message page * Create component for displaying account details * Add retrieve accounts function * Load accounts after closing app * Fix the retrieve accounts function * Use hdpath instead of id * Check if keystore is empty while retrieving accounts * Add spinner when accounts are being fetched * Display complete hd paths after reloading the app * Remove any return type * Store public key and address * Modify sign message function to use path * Fix the add accounts functionality
This commit is contained in:
parent
01373697f4
commit
783758be39
31
components/AccountDetails.tsx
Normal file
31
components/AccountDetails.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import { Text } from 'react-native-paper';
|
||||||
|
|
||||||
|
import { Account } from '../types';
|
||||||
|
import styles from '../styles/stylesheet';
|
||||||
|
|
||||||
|
interface AccountDetailsProps {
|
||||||
|
account: Account | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AccountDetails: React.FC<AccountDetailsProps> = ({ account }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.accountContainer}>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={styles.highlight}>Address: </Text>
|
||||||
|
{account?.address}
|
||||||
|
</Text>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={styles.highlight}>Public Key: </Text>
|
||||||
|
{account?.pubKey}
|
||||||
|
</Text>
|
||||||
|
<Text variant="bodyLarge">
|
||||||
|
<Text style={{ fontWeight: '700' }}>HD Path: </Text>
|
||||||
|
{account?.hdPath}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AccountDetails;
|
@ -1,12 +1,15 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { TouchableOpacity, View } from 'react-native';
|
import { ScrollView, TouchableOpacity, View } from 'react-native';
|
||||||
import { Button, List, Text, useTheme } from 'react-native-paper';
|
import { Button, List, Text, useTheme } from 'react-native-paper';
|
||||||
|
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
|
|
||||||
import { AccountsProps, StackParamsList, Account } from '../types';
|
import { AccountsProps, StackParamsList, Account } from '../types';
|
||||||
import { addAccount } from '../utils/Accounts';
|
import { addAccount } from '../utils/accounts';
|
||||||
import styles from '../styles/stylesheet';
|
import styles from '../styles/stylesheet';
|
||||||
import HDPathDialog from './HDPathDialog';
|
import HDPathDialog from './HDPathDialog';
|
||||||
|
import AccountDetails from './AccountDetails';
|
||||||
|
|
||||||
const Accounts = ({
|
const Accounts = ({
|
||||||
network,
|
network,
|
||||||
@ -59,6 +62,7 @@ const Accounts = ({
|
|||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ScrollView>
|
||||||
<View>
|
<View>
|
||||||
<HDPathDialog
|
<HDPathDialog
|
||||||
visible={hdDialog}
|
visible={hdDialog}
|
||||||
@ -94,20 +98,7 @@ const Accounts = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.accountContainer}>
|
<AccountDetails account={selectedAccounts[currentIndex]} />
|
||||||
<Text variant="bodyLarge">
|
|
||||||
<Text style={styles.highlight}>Address: </Text>
|
|
||||||
{selectedAccounts[currentIndex]?.address}
|
|
||||||
</Text>
|
|
||||||
<Text variant="bodyLarge">
|
|
||||||
<Text style={styles.highlight}>Public Key: </Text>
|
|
||||||
{selectedAccounts[currentIndex]?.pubKey}
|
|
||||||
</Text>
|
|
||||||
<Text variant="bodyLarge">
|
|
||||||
<Text style={{ fontWeight: '700' }}>HD Path: </Text>
|
|
||||||
{selectedAccounts[currentIndex]?.hdPath}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.signLink}>
|
<View style={styles.signLink}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
@ -125,6 +116,7 @@ const Accounts = ({
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
</ScrollView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,13 +4,7 @@ import { Button, Dialog, Portal, Text } from 'react-native-paper';
|
|||||||
|
|
||||||
import styles from '../styles/stylesheet';
|
import styles from '../styles/stylesheet';
|
||||||
import GridView from './Grid';
|
import GridView from './Grid';
|
||||||
|
import { CustomDialogProps } from '../types';
|
||||||
type CustomDialogProps = {
|
|
||||||
visible: boolean;
|
|
||||||
hideDialog: () => void;
|
|
||||||
contentText: string;
|
|
||||||
titleText?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DialogComponent = ({
|
const DialogComponent = ({
|
||||||
visible,
|
visible,
|
||||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import { ScrollView, View, Text } from 'react-native';
|
import { ScrollView, View, Text } from 'react-native';
|
||||||
import { Button, TextInput } from 'react-native-paper';
|
import { Button, TextInput } from 'react-native-paper';
|
||||||
|
|
||||||
import { addAccountFromHDPath } from '../utils/Accounts';
|
import { addAccountFromHDPath } from '../utils/accounts';
|
||||||
import { Account, PathState } from '../types';
|
import { Account, PathState } from '../types';
|
||||||
import styles from '../styles/stylesheet';
|
import styles from '../styles/stylesheet';
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { View } from 'react-native';
|
import { View, ActivityIndicator } from 'react-native';
|
||||||
import { Button } from 'react-native-paper';
|
import { Button, Text } from 'react-native-paper';
|
||||||
|
|
||||||
import { createWallet, resetWallet } from '../utils/Accounts';
|
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
|
||||||
import { DialogComponent } from './Dialog';
|
import { DialogComponent } from './Dialog';
|
||||||
import { NetworkDropdown } from './NetworkDropdown';
|
import { NetworkDropdown } from './NetworkDropdown';
|
||||||
import { Account, AccountsState } from '../types';
|
import { Account, AccountsState } from '../types';
|
||||||
@ -18,6 +18,7 @@ const HomeScreen = () => {
|
|||||||
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
|
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
|
||||||
const [network, setNetwork] = useState<string>('eth');
|
const [network, setNetwork] = useState<string>('eth');
|
||||||
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
||||||
|
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(false);
|
||||||
const [phrase, setPhrase] = useState('');
|
const [phrase, setPhrase] = useState('');
|
||||||
const [accounts, setAccounts] = useState<AccountsState>({
|
const [accounts, setAccounts] = useState<AccountsState>({
|
||||||
ethAccounts: [],
|
ethAccounts: [],
|
||||||
@ -82,20 +83,39 @@ const HomeScreen = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchAccounts = async () => {
|
||||||
|
if (isAccountsFetched) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { ethLoadedAccounts, cosmosLoadedAccounts } =
|
||||||
|
await retrieveAccounts();
|
||||||
|
|
||||||
|
if (ethLoadedAccounts && cosmosLoadedAccounts) {
|
||||||
|
setAccounts({
|
||||||
|
ethAccounts: ethLoadedAccounts,
|
||||||
|
cosmosAccounts: cosmosLoadedAccounts,
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsWalletCreated(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsAccountsFetched(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchAccounts();
|
||||||
|
}, [isAccountsFetched]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.appContainer}>
|
<View style={styles.appContainer}>
|
||||||
<DialogComponent
|
{!isAccountsFetched ? (
|
||||||
visible={walletDialog}
|
<View style={styles.spinnerContainer}>
|
||||||
hideDialog={hideWalletDialog}
|
<Text style={{ color: 'black', fontSize: 18, padding: 10 }}>
|
||||||
contentText={phrase}
|
Loading...
|
||||||
/>
|
</Text>
|
||||||
<ResetWalletDialog
|
<ActivityIndicator size="large" color="#0000ff" />
|
||||||
visible={resetWalletDialog}
|
</View>
|
||||||
hideDialog={hideResetDialog}
|
) : isWalletCreated ? (
|
||||||
onConfirm={confirmResetWallet}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isWalletCreated ? (
|
|
||||||
<>
|
<>
|
||||||
<NetworkDropdown
|
<NetworkDropdown
|
||||||
selectedNetwork={network}
|
selectedNetwork={network}
|
||||||
@ -128,6 +148,16 @@ const HomeScreen = () => {
|
|||||||
createWalletHandler={createWalletHandler}
|
createWalletHandler={createWalletHandler}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<DialogComponent
|
||||||
|
visible={walletDialog}
|
||||||
|
hideDialog={hideWalletDialog}
|
||||||
|
contentText={phrase}
|
||||||
|
/>
|
||||||
|
<ResetWalletDialog
|
||||||
|
visible={resetWalletDialog}
|
||||||
|
hideDialog={hideResetDialog}
|
||||||
|
onConfirm={confirmResetWallet}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,8 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
|||||||
|
|
||||||
import { StackParamsList } from '../types';
|
import { StackParamsList } from '../types';
|
||||||
import styles from '../styles/stylesheet';
|
import styles from '../styles/stylesheet';
|
||||||
import { signMessage } from '../utils/SignMessage';
|
import { signMessage } from '../utils/sign-message';
|
||||||
|
import AccountDetails from './AccountDetails';
|
||||||
|
|
||||||
type SignProps = NativeStackScreenProps<StackParamsList, 'SignMessage'>;
|
type SignProps = NativeStackScreenProps<StackParamsList, 'SignMessage'>;
|
||||||
|
|
||||||
@ -39,14 +40,7 @@ const SignMessage = ({ route }: SignProps) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.accountContainer}>
|
<View style={styles.accountContainer}>
|
||||||
<Text variant="bodyLarge">
|
<AccountDetails account={account} />
|
||||||
<Text style={styles.highlight}>Address: </Text>
|
|
||||||
{account?.address}
|
|
||||||
</Text>
|
|
||||||
<Text variant="bodyLarge">
|
|
||||||
<Text style={styles.highlight}>Public Key: </Text>
|
|
||||||
{account?.pubKey}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
@ -101,6 +101,11 @@ const styles = StyleSheet.create({
|
|||||||
marginTop: 20,
|
marginTop: 20,
|
||||||
width: 200,
|
width: 200,
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
|
spinnerContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
13
types.ts
13
types.ts
@ -1,12 +1,6 @@
|
|||||||
export type StackParamsList = {
|
export type StackParamsList = {
|
||||||
Laconic: undefined;
|
Laconic: undefined;
|
||||||
SignMessage: { selectedNetwork: string; accountInfo: Account } | undefined;
|
SignMessage: { selectedNetwork: string; accountInfo: Account } | undefined;
|
||||||
HDPath:
|
|
||||||
| {
|
|
||||||
updateIndex: (index: number) => void;
|
|
||||||
updateAccounts: (account: Account) => void;
|
|
||||||
}
|
|
||||||
| undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Account = {
|
export type Account = {
|
||||||
@ -68,6 +62,13 @@ export type HDPathDialogProps = {
|
|||||||
updateAccounts: (account: Account) => void;
|
updateAccounts: (account: Account) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CustomDialogProps = {
|
||||||
|
visible: boolean;
|
||||||
|
hideDialog: () => void;
|
||||||
|
contentText: string;
|
||||||
|
titleText?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type GridViewProps = {
|
export type GridViewProps = {
|
||||||
words: string[];
|
words: string[];
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ import { HDNode } from 'ethers/lib/utils';
|
|||||||
import {
|
import {
|
||||||
setInternetCredentials,
|
setInternetCredentials,
|
||||||
resetInternetCredentials,
|
resetInternetCredentials,
|
||||||
|
getInternetCredentials,
|
||||||
} from 'react-native-keychain';
|
} from 'react-native-keychain';
|
||||||
|
|
||||||
import { Account, WalletDetails } from '../types';
|
import { Account, WalletDetails } from '../types';
|
||||||
@ -18,6 +19,7 @@ import {
|
|||||||
getHDPath,
|
getHDPath,
|
||||||
getMnemonic,
|
getMnemonic,
|
||||||
getNextAccountId,
|
getNextAccountId,
|
||||||
|
getPathKey,
|
||||||
resetKeyServers,
|
resetKeyServers,
|
||||||
updateAccountIndices,
|
updateAccountIndices,
|
||||||
updateGlobalCounter,
|
updateGlobalCounter,
|
||||||
@ -33,11 +35,13 @@ const createWallet = async (): Promise<WalletDetails> => {
|
|||||||
const cosmosNode = hdNode.derivePath("m/44'/118'/0'/0/0");
|
const cosmosNode = hdNode.derivePath("m/44'/118'/0'/0/0");
|
||||||
|
|
||||||
const ethAddress = ethNode.address;
|
const ethAddress = ethNode.address;
|
||||||
const cosmosAddress = (await getCosmosAccounts(mnemonic, `0'/0/0`)).data
|
const cosmosAddress = (await getCosmosAccounts(mnemonic, "0'/0/0")).data
|
||||||
.address;
|
.address;
|
||||||
|
|
||||||
const ethAccountInfo = `${`0'/0/0`},${ethNode.privateKey}`;
|
const ethAccountInfo = `${"0'/0/0"},${ethNode.privateKey},${ethNode.publicKey
|
||||||
const cosmosAccountInfo = `${`0'/0/0`},${cosmosNode.privateKey}`;
|
},${ethAddress}`;
|
||||||
|
const cosmosAccountInfo = `${"0'/0/0"},${cosmosNode.privateKey},${cosmosNode.publicKey
|
||||||
|
},${cosmosAddress}`;
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
setInternetCredentials(
|
setInternetCredentials(
|
||||||
@ -82,26 +86,20 @@ const addAccount = async (network: string): Promise<Account | undefined> => {
|
|||||||
const mnemonic = await getMnemonic();
|
const mnemonic = await getMnemonic();
|
||||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||||
const id = await getNextAccountId(network);
|
const id = await getNextAccountId(network);
|
||||||
const hdPath = getHDPath(network, id);
|
const hdPath = getHDPath(network, `0'/0/${id}`);
|
||||||
|
|
||||||
const node = hdNode.derivePath(hdPath);
|
const node = hdNode.derivePath(hdPath);
|
||||||
const pubKey = node.publicKey;
|
const pubKey = node.publicKey;
|
||||||
const address = await getAddress(network, mnemonic, id);
|
const address = await getAddress(network, mnemonic, `0'/0/${id}`);
|
||||||
|
|
||||||
await updateAccountIndices(network, id);
|
await updateAccountIndices(network, id);
|
||||||
const { accountCounter, counterId } = await updateGlobalCounter(network);
|
const { counterId } = await updateGlobalCounter(network);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
resetInternetCredentials(`${network}:globalCounter`),
|
|
||||||
setInternetCredentials(
|
|
||||||
`${network}:globalCounter`,
|
|
||||||
`${network}Global`,
|
|
||||||
accountCounter,
|
|
||||||
),
|
|
||||||
setInternetCredentials(
|
setInternetCredentials(
|
||||||
`${network}:keyServer:${counterId}`,
|
`${network}:keyServer:${counterId}`,
|
||||||
`${network}:pathKey:${counterId}`,
|
`${network}:pathKey:${counterId}`,
|
||||||
`0'/0/${id},${node.privateKey}`,
|
`0'/0/${id},${node.privateKey},${node.publicKey},${address}`,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -125,20 +123,13 @@ const addAccountFromHDPath = async (
|
|||||||
|
|
||||||
const { privKey, pubKey, address, network } = account;
|
const { privKey, pubKey, address, network } = account;
|
||||||
|
|
||||||
const { accountCounter, counterId } = await updateGlobalCounter(network);
|
const counterId = (await updateGlobalCounter(network)).counterId;
|
||||||
const updatedAccountCounter = `${accountCounter},${counterId.toString()}`;
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
resetInternetCredentials(`${network}:globalCounter`),
|
|
||||||
setInternetCredentials(
|
|
||||||
`${network}:globalCounter`,
|
|
||||||
`${network}Global`,
|
|
||||||
updatedAccountCounter,
|
|
||||||
),
|
|
||||||
setInternetCredentials(
|
setInternetCredentials(
|
||||||
`${network}:keyServer:${counterId}`,
|
`${network}:keyServer:${counterId}`,
|
||||||
`${network}:pathKey:${counterId}`,
|
`${network}:pathKey:${counterId}`,
|
||||||
`${path},${privKey}`,
|
`${path},${privKey},${pubKey},${address}`,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -148,6 +139,51 @@ const addAccountFromHDPath = async (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const retrieveAccountsForNetwork = async (
|
||||||
|
network: string,
|
||||||
|
count: string,
|
||||||
|
): Promise<Account[]> => {
|
||||||
|
const elementsArray = count.split(',');
|
||||||
|
|
||||||
|
const loadedAccounts = await Promise.all(
|
||||||
|
elementsArray.map(async i => {
|
||||||
|
const pubKey = (await getPathKey(network, Number(i))).pubKey;
|
||||||
|
const address = (await getPathKey(network, Number(i))).address;
|
||||||
|
const path = (await getPathKey(network, Number(i))).path;
|
||||||
|
const hdPath = getHDPath(network, path);
|
||||||
|
|
||||||
|
const account: Account = {
|
||||||
|
counterId: Number(i),
|
||||||
|
pubKey: pubKey,
|
||||||
|
address: address,
|
||||||
|
hdPath: hdPath,
|
||||||
|
};
|
||||||
|
return account;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return loadedAccounts;
|
||||||
|
};
|
||||||
|
|
||||||
|
const retrieveAccounts = async (): Promise<{
|
||||||
|
ethLoadedAccounts?: Account[];
|
||||||
|
cosmosLoadedAccounts?: Account[];
|
||||||
|
}> => {
|
||||||
|
const ethServer = await getInternetCredentials('eth:globalCounter');
|
||||||
|
const ethCounter = ethServer && ethServer.password;
|
||||||
|
const cosmosServer = await getInternetCredentials('cosmos:globalCounter');
|
||||||
|
const cosmosCounter = cosmosServer && cosmosServer.password;
|
||||||
|
|
||||||
|
const ethLoadedAccounts = ethCounter
|
||||||
|
? await retrieveAccountsForNetwork('eth', ethCounter)
|
||||||
|
: undefined;
|
||||||
|
const cosmosLoadedAccounts = cosmosCounter
|
||||||
|
? await retrieveAccountsForNetwork('cosmos', cosmosCounter)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return { ethLoadedAccounts, cosmosLoadedAccounts };
|
||||||
|
};
|
||||||
|
|
||||||
const resetWallet = async () => {
|
const resetWallet = async () => {
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -165,4 +201,10 @@ const resetWallet = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { createWallet, addAccount, addAccountFromHDPath, resetWallet };
|
export {
|
||||||
|
createWallet,
|
||||||
|
addAccount,
|
||||||
|
addAccountFromHDPath,
|
||||||
|
retrieveAccounts,
|
||||||
|
resetWallet,
|
||||||
|
};
|
@ -13,13 +13,13 @@ const signMessage = async ({
|
|||||||
network,
|
network,
|
||||||
accountId,
|
accountId,
|
||||||
}: SignMessageParams): Promise<string | undefined> => {
|
}: SignMessageParams): Promise<string | undefined> => {
|
||||||
const hdPath = (await getPathKey(network, accountId)).hdPath;
|
const path = (await getPathKey(network, accountId)).path;
|
||||||
|
|
||||||
switch (network) {
|
switch (network) {
|
||||||
case 'eth':
|
case 'eth':
|
||||||
return await signEthMessage(message, accountId);
|
return await signEthMessage(message, accountId);
|
||||||
case 'cosmos':
|
case 'cosmos':
|
||||||
return await signCosmosMessage(message, hdPath);
|
return await signCosmosMessage(message, path);
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid wallet type');
|
throw new Error('Invalid wallet type');
|
||||||
}
|
}
|
||||||
@ -43,11 +43,11 @@ const signEthMessage = async (
|
|||||||
|
|
||||||
const signCosmosMessage = async (
|
const signCosmosMessage = async (
|
||||||
message: string,
|
message: string,
|
||||||
hdPath: string,
|
path: string,
|
||||||
): Promise<string | undefined> => {
|
): Promise<string | undefined> => {
|
||||||
try {
|
try {
|
||||||
const mnemonic = await getMnemonic();
|
const mnemonic = await getMnemonic();
|
||||||
const cosmosAccount = await getCosmosAccounts(mnemonic, hdPath);
|
const cosmosAccount = await getCosmosAccounts(mnemonic, path);
|
||||||
const address = cosmosAccount.data.address;
|
const address = cosmosAccount.data.address;
|
||||||
const cosmosSignature = await cosmosAccount.cosmosWallet.signAmino(
|
const cosmosSignature = await cosmosAccount.cosmosWallet.signAmino(
|
||||||
address,
|
address,
|
@ -23,21 +23,21 @@ const getMnemonic = async (): Promise<string> => {
|
|||||||
return mnemonic;
|
return mnemonic;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getHDPath = (network: string, id: number): string => {
|
const getHDPath = (network: string, path: string): string => {
|
||||||
return network === 'eth' ? `m/44'/60'/0'/0/${id}` : `m/44'/118'/0'/0/${id}`;
|
return network === 'eth' ? `m/44'/60'/${path}` : `m/44'/118'/${path}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAddress = async (
|
const getAddress = async (
|
||||||
network: string,
|
network: string,
|
||||||
mnemonic: string,
|
mnemonic: string,
|
||||||
id: number,
|
path: string,
|
||||||
): Promise<string> => {
|
): Promise<string> => {
|
||||||
switch (network) {
|
switch (network) {
|
||||||
case 'eth':
|
case 'eth':
|
||||||
return HDNode.fromMnemonic(mnemonic).derivePath(`m/44'/60'/0'/0/${id}`)
|
return HDNode.fromMnemonic(mnemonic).derivePath(`m/44'/60'/${path}`)
|
||||||
.address;
|
.address;
|
||||||
case 'cosmos':
|
case 'cosmos':
|
||||||
return (await getCosmosAccounts(mnemonic, `0'/0/${id}`)).data.address;
|
return (await getCosmosAccounts(mnemonic, `${path}`)).data.address;
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid wallet type');
|
throw new Error('Invalid wallet type');
|
||||||
}
|
}
|
||||||
@ -45,10 +45,10 @@ const getAddress = async (
|
|||||||
|
|
||||||
const getCosmosAccounts = async (
|
const getCosmosAccounts = async (
|
||||||
mnemonic: string,
|
mnemonic: string,
|
||||||
hdPath: string,
|
path: string,
|
||||||
): Promise<{ cosmosWallet: Secp256k1HdWallet; data: AccountData }> => {
|
): Promise<{ cosmosWallet: Secp256k1HdWallet; data: AccountData }> => {
|
||||||
const cosmosWallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, {
|
const cosmosWallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, {
|
||||||
hdPaths: [stringToPath(`m/44'/118'/${hdPath}`)],
|
hdPaths: [stringToPath(`m/44'/118'/${path}`)],
|
||||||
});
|
});
|
||||||
|
|
||||||
const accountsData = await cosmosWallet.getAccounts();
|
const accountsData = await cosmosWallet.getAccounts();
|
||||||
@ -100,7 +100,12 @@ const accountInfoFromHDPath = async (
|
|||||||
const getPathKey = async (
|
const getPathKey = async (
|
||||||
network: string,
|
network: string,
|
||||||
accountId: number,
|
accountId: number,
|
||||||
): Promise<{ hdPath: string; privKey: string }> => {
|
): Promise<{
|
||||||
|
path: string;
|
||||||
|
privKey: string;
|
||||||
|
pubKey: string;
|
||||||
|
address: string;
|
||||||
|
}> => {
|
||||||
const pathKeyStore = await getInternetCredentials(
|
const pathKeyStore = await getInternetCredentials(
|
||||||
`${network}:keyServer:${accountId}`,
|
`${network}:keyServer:${accountId}`,
|
||||||
);
|
);
|
||||||
@ -111,10 +116,12 @@ const getPathKey = async (
|
|||||||
|
|
||||||
const pathKeyVal = pathKeyStore.password;
|
const pathKeyVal = pathKeyStore.password;
|
||||||
const pathkey = pathKeyVal.split(',');
|
const pathkey = pathKeyVal.split(',');
|
||||||
const hdPath = pathkey[0];
|
const path = pathkey[0];
|
||||||
const privKey = pathkey[1];
|
const privKey = pathkey[1];
|
||||||
|
const pubKey = pathkey[2];
|
||||||
|
const address = pathkey[3];
|
||||||
|
|
||||||
return { hdPath, privKey };
|
return { path, privKey, pubKey, address };
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGlobalCounter = async (
|
const getGlobalCounter = async (
|
||||||
|
Loading…
Reference in New Issue
Block a user