Implement functionality to import wallet from mnemonic
This commit is contained in:
parent
6f174c6e0c
commit
01289678d4
@ -1,5 +1,5 @@
|
||||
import { View } from 'react-native';
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import { CreateWalletProps } from '../types';
|
||||
|
62
src/components/ImportWalletDialog.tsx
Normal file
62
src/components/ImportWalletDialog.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, Grid, Button, Typography } from "@mui/material";
|
||||
|
||||
const ImportWalletDialog = ({
|
||||
visible,
|
||||
hideDialog,
|
||||
importWalletHandler
|
||||
}: {
|
||||
visible: boolean;
|
||||
hideDialog: () => void;
|
||||
importWalletHandler: (recoveryPhrase: string) => Promise<void>;
|
||||
}) => {
|
||||
const [words, setWords] = useState(Array(12).fill(''));
|
||||
|
||||
const handleWordChange = (index: number, value: string) => {
|
||||
const newWords = [...words];
|
||||
newWords[index] = value;
|
||||
setWords(newWords);
|
||||
};
|
||||
|
||||
const handlePaste = (event: React.ClipboardEvent<HTMLDivElement>) => {
|
||||
const pastedText = event.clipboardData.getData('Text');
|
||||
const splitWords = pastedText.trim().split(/\s+/);
|
||||
|
||||
if (splitWords.length === 12) {
|
||||
setWords(splitWords);
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={visible} onClose={hideDialog}>
|
||||
<DialogTitle>Import your wallet from your mnemonic</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography>
|
||||
(You can paste your entire mnemonic into the first textbox)
|
||||
</Typography>
|
||||
<Grid container spacing={2}>
|
||||
{words.map((word, index) => (
|
||||
<Grid item xs={6} sm={4} key={index}>
|
||||
<TextField
|
||||
value={word}
|
||||
onChange={(e) => handleWordChange(index, e.target.value)}
|
||||
onPaste={index === 0 ? handlePaste : undefined}
|
||||
placeholder={`Word ${index + 1}`}
|
||||
fullWidth
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => importWalletHandler(words.join(' '))}>Import Wallet</Button>
|
||||
<Button onClick={hideDialog}>Cancel</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export default ImportWalletDialog;
|
@ -5,7 +5,7 @@ import styles from '../styles/stylesheet';
|
||||
import GridView from './Grid';
|
||||
import { CustomDialogProps } from '../types';
|
||||
|
||||
const DialogComponent = ({ visible, hideDialog, contentText }: CustomDialogProps) => {
|
||||
const MnemonicDialog = ({ visible, hideDialog, contentText }: CustomDialogProps) => {
|
||||
const words = contentText.split(' ');
|
||||
|
||||
const copyMnemonic = () => {
|
||||
@ -26,10 +26,10 @@ const DialogComponent = ({ visible, hideDialog, contentText }: CustomDialogProps
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={copyMnemonic}>Copy</Button>
|
||||
<Button onClick={hideDialog}>Done</Button>
|
||||
<Button onClick={hideDialog}>Cancel</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export { DialogComponent };
|
||||
export { MnemonicDialog };
|
@ -7,7 +7,8 @@ import { useNavigation } from '@react-navigation/native';
|
||||
import { getSdkError } from '@walletconnect/utils';
|
||||
|
||||
import { createWallet, resetWallet, retrieveAccounts } from '../utils/accounts';
|
||||
import { DialogComponent } from '../components/Dialog';
|
||||
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';
|
||||
@ -55,12 +56,13 @@ const HomeScreen = () => {
|
||||
|
||||
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
|
||||
const [isWalletCreating, setIsWalletCreating] = useState<boolean>(false);
|
||||
const [walletDialog, setWalletDialog] = useState<boolean>(false);
|
||||
const [importWalletDialog, setImportWalletDialog] = useState<boolean>(false);
|
||||
const [mnemonicDialog, setMnemonicDialog] = useState<boolean>(false);
|
||||
const [resetWalletDialog, setResetWalletDialog] = useState<boolean>(false);
|
||||
const [isAccountsFetched, setIsAccountsFetched] = useState<boolean>(true);
|
||||
const [phrase, setPhrase] = useState('');
|
||||
|
||||
const hideWalletDialog = () => setWalletDialog(false);
|
||||
const hideMnemonicDialog = () => setMnemonicDialog(false);
|
||||
const hideResetDialog = () => setResetWalletDialog(false);
|
||||
|
||||
const fetchAccounts = useCallback(async () => {
|
||||
@ -83,12 +85,22 @@ const HomeScreen = () => {
|
||||
const mnemonic = await createWallet(networksData);
|
||||
if (mnemonic) {
|
||||
fetchAccounts();
|
||||
setWalletDialog(true);
|
||||
setMnemonicDialog(true);
|
||||
setPhrase(mnemonic);
|
||||
setSelectedNetwork(networksData[0]);
|
||||
}
|
||||
};
|
||||
|
||||
const importWalletHandler = async (recoveryPhrase: string) => {
|
||||
const mnemonic = await createWallet(networksData, recoveryPhrase);
|
||||
if (mnemonic) {
|
||||
fetchAccounts();
|
||||
setPhrase(mnemonic);
|
||||
setSelectedNetwork(networksData[0]);
|
||||
setImportWalletDialog(false);
|
||||
}
|
||||
};
|
||||
|
||||
const confirmResetWallet = useCallback(async () => {
|
||||
setIsWalletCreated(false);
|
||||
setIsWalletCreating(false);
|
||||
@ -152,14 +164,28 @@ const HomeScreen = () => {
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<CreateWallet
|
||||
isWalletCreating={isWalletCreating}
|
||||
createWalletHandler={createWalletHandler}
|
||||
/>
|
||||
<>
|
||||
<CreateWallet
|
||||
isWalletCreating={isWalletCreating}
|
||||
createWalletHandler={createWalletHandler}
|
||||
/>
|
||||
<View style={styles.createWalletContainer}>
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={() => setImportWalletDialog(true)}>
|
||||
Import Wallet
|
||||
</Button>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
<DialogComponent
|
||||
visible={walletDialog}
|
||||
hideDialog={hideWalletDialog}
|
||||
<ImportWalletDialog
|
||||
visible={importWalletDialog}
|
||||
hideDialog={() => setImportWalletDialog(false)}
|
||||
importWalletHandler={importWalletHandler}
|
||||
/>
|
||||
<MnemonicDialog
|
||||
visible={mnemonicDialog}
|
||||
hideDialog={hideMnemonicDialog}
|
||||
contentText={phrase}
|
||||
/>
|
||||
<ConfirmDialog
|
||||
|
@ -5,7 +5,7 @@ const styles = StyleSheet.create({
|
||||
marginTop: 20,
|
||||
width: 150,
|
||||
alignSelf: 'center',
|
||||
marginBottom: 40
|
||||
marginBottom: 30,
|
||||
},
|
||||
signLink: {
|
||||
alignItems: 'flex-end',
|
||||
|
@ -27,12 +27,23 @@ import { COSMOS, EIP155 } from './constants';
|
||||
|
||||
const createWallet = async (
|
||||
networksData: NetworksDataState[],
|
||||
recoveryPhrase?: string,
|
||||
): Promise<string> => {
|
||||
const mnemonic = utils.entropyToMnemonic(utils.randomBytes(16));
|
||||
const mnemonic = recoveryPhrase ? recoveryPhrase : utils.entropyToMnemonic(utils.randomBytes(16));
|
||||
await setInternetCredentials('mnemonicServer', 'mnemonic', mnemonic);
|
||||
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
|
||||
await createWalletFromMnemonic(networksData, hdNode, mnemonic);
|
||||
|
||||
return mnemonic;
|
||||
};
|
||||
|
||||
const createWalletFromMnemonic = async (
|
||||
networksData: NetworksDataState[],
|
||||
hdNode: HDNode,
|
||||
mnemonic: string
|
||||
): Promise<void> => {
|
||||
for (const network of networksData) {
|
||||
const hdPath = `m/44'/${network.coinType}'/0'/0/0`;
|
||||
const node = hdNode.derivePath(hdPath);
|
||||
@ -73,8 +84,6 @@ const createWallet = async (
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return mnemonic;
|
||||
};
|
||||
|
||||
const addAccount = async (
|
||||
|
Loading…
Reference in New Issue
Block a user