forked from cerc-io/laconic-wallet
Generate wallet and sign message (#4)
* Store mnemonic and private key seperately * Change variable names * Refactor code in seperate components * Display wallet details * Remove unnecessary imports * Make review changes * Add method to reset wallet * Make component self closing * separate imports --------- Co-authored-by: Adw8 <adwait@deepstacksoft.com>
This commit is contained in:
parent
5dd97e3860
commit
3d40de966d
125
App.tsx
125
App.tsx
@ -12,48 +12,24 @@ import {
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Colors } from 'react-native/Libraries/NewAppScreen';
|
||||
import { HDNode } from 'ethers/lib/utils';
|
||||
|
||||
import { generateWallet, resetWallet, signMessage } from './utils';
|
||||
import styles from './styles/stylesheet';
|
||||
import { generateWallet, signMessage } from './utils';
|
||||
|
||||
type SectionProps = PropsWithChildren<{
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
const Section = ({children, title}: SectionProps): React.JSX.Element => {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
return (
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.sectionTitle,
|
||||
{
|
||||
color: isDarkMode ? Colors.white : Colors.black,
|
||||
},
|
||||
]}>
|
||||
{title}
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.sectionDescription,
|
||||
{
|
||||
color: isDarkMode ? Colors.light : Colors.dark,
|
||||
},
|
||||
]}>
|
||||
{children}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import { Section } from './components/Section';
|
||||
|
||||
const App = (): React.JSX.Element => {
|
||||
const [message, setMessage] = useState('');
|
||||
const [isWalletCreated, setIsWalletCreated] = useState(false);
|
||||
const [isWalletCreated, setIsWalletCreated] = useState<boolean>(false);
|
||||
const [wallet, setWallet] = useState<HDNode | null>();
|
||||
|
||||
const createWallet = async () => {
|
||||
Alert.alert('Creating Wallet...');
|
||||
await generateWallet();
|
||||
setIsWalletCreated(true);
|
||||
const wallet = await generateWallet();
|
||||
if (wallet) {
|
||||
setWallet(wallet);
|
||||
setIsWalletCreated(true);
|
||||
}
|
||||
};
|
||||
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
@ -81,16 +57,62 @@ const App = (): React.JSX.Element => {
|
||||
<View>
|
||||
{isWalletCreated ? (
|
||||
<View>
|
||||
<Section title="Generate Wallet">Wallet Created! </Section>
|
||||
<Section title="Wallet Details" />
|
||||
<View style={{ marginTop: 32, paddingHorizontal: 24 }}>
|
||||
<Text style={{ fontSize: 16, color: 'black' }}>
|
||||
Address: {wallet && wallet.address.toString()}
|
||||
</Text>
|
||||
<Text style={{ fontSize: 16, color: 'black' }}>
|
||||
Public Key: {wallet && wallet.publicKey.toString()}
|
||||
</Text>
|
||||
</View>
|
||||
<Section title="Sign a message" />
|
||||
<View>
|
||||
<TextInput
|
||||
style={{
|
||||
height: 40,
|
||||
borderColor: 'gray',
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
padding: 5,
|
||||
}}
|
||||
placeholder="Enter your message"
|
||||
onChangeText={text => setMessage(text)}
|
||||
value={message}
|
||||
/>
|
||||
<View
|
||||
style={{ marginTop: 20, width: 150, alignSelf: 'center' }}>
|
||||
<Button
|
||||
title="Sign Message"
|
||||
color="#841584"
|
||||
onPress={() => {
|
||||
signMessage(message);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Section title="" />
|
||||
<View>
|
||||
<View
|
||||
style={{ marginTop: 20, width: 150, alignSelf: 'center' }}>
|
||||
<Button
|
||||
title="Reset Wallet"
|
||||
color="#D30000"
|
||||
onPress={async () => {
|
||||
await resetWallet();
|
||||
setIsWalletCreated(false);
|
||||
setWallet(null);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<View>
|
||||
<Section title="Generate Wallet">
|
||||
Click the button to generate the wallet
|
||||
</Section>
|
||||
<View style={{marginTop: 20, width: 150, alignSelf: 'center'}}>
|
||||
<Section title="Create Wallet" />
|
||||
<View style={{ marginTop: 20, width: 150, alignSelf: 'center' }}>
|
||||
<Button
|
||||
title="Initialise Wallet"
|
||||
title="Create"
|
||||
color="#841584"
|
||||
onPress={createWallet}
|
||||
/>
|
||||
@ -98,29 +120,6 @@ const App = (): React.JSX.Element => {
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View>
|
||||
<TextInput
|
||||
style={{
|
||||
height: 40,
|
||||
borderColor: 'gray',
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
padding: 5,
|
||||
}}
|
||||
placeholder="Enter your message"
|
||||
onChangeText={text => setMessage(text)}
|
||||
value={message}
|
||||
/>
|
||||
<View style={{marginTop: 20, width: 150, alignSelf: 'center'}}>
|
||||
<Button
|
||||
title="Sign Message"
|
||||
color="#841584"
|
||||
onPress={() => {
|
||||
signMessage(message);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
|
23
components/Header.tsx
Normal file
23
components/Header.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { View, Text, useColorScheme } from 'react-native';
|
||||
import { Colors } from 'react-native/Libraries/NewAppScreen';
|
||||
|
||||
import styles from '../styles/stylesheet';
|
||||
|
||||
const Header = () => {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
return (
|
||||
<View style={styles.headerContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.headerText,
|
||||
{color: isDarkMode ? Colors.light : Colors.dark},
|
||||
]}>
|
||||
Laconic Wallet
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export { Header };
|
29
components/Section.tsx
Normal file
29
components/Section.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { PropsWithChildren } from "react";
|
||||
import { Text, View, useColorScheme } from "react-native";
|
||||
import { Colors } from "react-native/Libraries/NewAppScreen";
|
||||
|
||||
import styles from "../styles/stylesheet";
|
||||
|
||||
type SectionProps = PropsWithChildren<{
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
const Section = ({ children, title }: SectionProps): React.JSX.Element => {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
return (
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.sectionTitle,
|
||||
{
|
||||
color: isDarkMode ? Colors.white : Colors.black,
|
||||
},
|
||||
]}>
|
||||
{title}
|
||||
<Text style={styles.sectionDescription} />
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export { Section };
|
@ -8,7 +8,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
headerText: {
|
||||
color: 'black',
|
||||
fontSize: 22,
|
||||
fontSize: 26,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
sectionContainer: {
|
||||
@ -16,7 +16,7 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 24,
|
||||
fontSize: 22,
|
||||
fontWeight: '600',
|
||||
},
|
||||
sectionDescription: {
|
||||
|
29
utils.ts
29
utils.ts
@ -3,14 +3,22 @@ import '@ethersproject/shims';
|
||||
import { Wallet, utils } from 'ethers';
|
||||
import { HDNode } from 'ethers/lib/utils';
|
||||
import { Alert } from 'react-native';
|
||||
import { getGenericPassword, setGenericPassword } from 'react-native-keychain';
|
||||
import {
|
||||
setInternetCredentials,
|
||||
getInternetCredentials,
|
||||
resetInternetCredentials,
|
||||
} from 'react-native-keychain';
|
||||
|
||||
const generateWallet = async () => {
|
||||
const generateWallet = async (): Promise<HDNode | undefined> => {
|
||||
try {
|
||||
const mnemonic = utils.entropyToMnemonic(utils.randomBytes(32));
|
||||
const hdNode = HDNode.fromMnemonic(mnemonic);
|
||||
await setGenericPassword(mnemonic, hdNode.privateKey);
|
||||
Alert.alert('Wallet stored successfully with address:', hdNode.address);
|
||||
|
||||
await setInternetCredentials('keyServer', 'key', hdNode.privateKey);
|
||||
await setInternetCredentials('mnemonicServer', 'mnemonic', mnemonic);
|
||||
|
||||
Alert.alert('Wallet created successfully ');
|
||||
return hdNode;
|
||||
} catch (error) {
|
||||
console.error('Error creating wallet ', error);
|
||||
}
|
||||
@ -18,11 +26,11 @@ const generateWallet = async () => {
|
||||
|
||||
const signMessage = async (message: string) => {
|
||||
try {
|
||||
const creds = await getGenericPassword();
|
||||
const wallet = creds && new Wallet(creds.password);
|
||||
const keyCred = await getInternetCredentials('keyServer');
|
||||
const wallet = keyCred && new Wallet(keyCred.password);
|
||||
const signature = wallet && (await wallet.signMessage(message));
|
||||
if (typeof signature === 'string') {
|
||||
Alert.alert('Message signed successfully with signature', signature);
|
||||
Alert.alert('Message signature: ', signature);
|
||||
} else {
|
||||
Alert.alert('Message signing failed. Please try again.');
|
||||
}
|
||||
@ -31,4 +39,9 @@ const signMessage = async (message: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export { generateWallet, signMessage };
|
||||
const resetWallet = async () => {
|
||||
await resetInternetCredentials('keyServer');
|
||||
await resetInternetCredentials('mnemonicServer');
|
||||
};
|
||||
|
||||
export { generateWallet, signMessage, resetWallet };
|
||||
|
Loading…
Reference in New Issue
Block a user