Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create master key & import master key #29

Merged
merged 12 commits into from
Oct 25, 2021
52 changes: 18 additions & 34 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useEffect, useState } from 'react'
import React, { useContext } from 'react'
import { StyleSheet, View, ScrollView } from 'react-native'
import { NavigationProp, ParamListBase } from '@react-navigation/native'

Expand All @@ -15,34 +15,7 @@ interface Interface {
}

const WalletApp: React.FC<Interface> = ({ navigation }) => {
// Temporary component state:
interface componentStateI {
confirmResponse?: string
wallet?: RIFWallet
}

const [wallet, setWallet] = useState<RIFWallet[]>([])
const [mnemonic, setMnemonic] = useState<string>('')

const context = useContext(WalletProviderContext)
useEffect(() => {
context.wallets && setWallet(context.wallets)
}, [context.wallets])

useEffect(() => {
console.log('setting Mnemonic', context.getMnemonic())
setMnemonic(context.getMnemonic())
}, [context.wallets])

/*
const addAccount = () => {
if (wallet) {
wallet
?.getAccount(accounts.length)
.then(account => setAccounts(accounts.concat(account)))
}
}
*/
const { wallets } = useContext(WalletProviderContext)

const seeSmartWallet = (account: RIFWallet) =>
// @ts-ignore
Expand All @@ -52,13 +25,23 @@ const WalletApp: React.FC<Interface> = ({ navigation }) => {
<ScrollView>
<Header1>sWallet</Header1>
<View style={styles.section}>
<Header2>KMS:</Header2>
<CopyComponent value={mnemonic} />
<Header2>Welcome</Header2>
{wallets.length > 0 ? (
<Button
onPress={() => navigation.navigate('RevealMasterKey')}
title="Reveal master key"
/>
) : (
<Button
onPress={() => navigation.navigate('CreateWalletStack')}
title="Create master key"
/>
)}
</View>

<View style={styles.section}>
<Header2>RIF Wallets:</Header2>
{wallet.map((account: RIFWallet, index: number) => {
{wallets.map((account: RIFWallet, index: number) => {
return (
<View key={index}>
<Paragraph>EOA Address</Paragraph>
Expand Down Expand Up @@ -96,13 +79,14 @@ const WalletApp: React.FC<Interface> = ({ navigation }) => {
</View>
)
})}
{/*<Button onPress={addAccount} title="Add account" />*/}
</View>

<View style={styles.section}>
<Header2>Settings</Header2>
<Button
onPress={() => removeStorage(StorageKeys.KMS)}
onPress={() => {
removeStorage(StorageKeys.KMS)
}}
title="Clear RN Storage"
/>
<Paragraph>
Expand Down
12 changes: 12 additions & 0 deletions src/RootNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import ReceiveScreen from './screens/receive/ReceiveScreen'

import SmartWallet from './tempScreens/SmartWallet'
import { WalletProviderContext } from './state/AppContext'
import CreateWalletNavigationScreen from './screens/createWallet'
import RevealMasterKeyScreen from './screens/createWallet/RevealMasterKeyScreen'
import ModalComponent from './modal/ModalComponent'
import SignMessageScreen from './tempScreens/SignMessageScreen'
import BalancesScreen from './screens/balances/BalancesScreen'
Expand Down Expand Up @@ -59,6 +61,16 @@ const RootNavigation: React.FC<Interface> = () => {
options={sharedOptions}
/>
<RootStack.Screen name="Balances" component={BalancesScreen} />
<RootStack.Screen
name="CreateWalletStack"
component={CreateWalletNavigationScreen}
options={sharedOptions}
/>
<RootStack.Screen
name="RevealMasterKey"
component={RevealMasterKeyScreen}
options={{ ...sharedOptions, headerShown: true }}
/>
</RootStack.Group>
</RootStack.Navigator>
</NavigationContainer>
Expand Down
5 changes: 3 additions & 2 deletions src/components/copy/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import { Paragraph } from '../typography'

interface Interface {
value: string
testID?: string
}

const CopyComponent: React.FC<Interface> = ({ value }) => {
const CopyComponent: React.FC<Interface> = ({ value, testID }) => {
return (
<TouchableOpacity onPress={() => Clipboard.setString(value)}>
<View style={styles.row}>
<View style={styles.textColumn}>
<Paragraph>{value}</Paragraph>
<Paragraph testID={testID}>{value}</Paragraph>
</View>
<View style={styles.iconColumn}>
<Text>copy</Text>
Expand Down
19 changes: 13 additions & 6 deletions src/components/typography/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ import { StyleSheet, Text } from 'react-native'

interface Interface {
children: React.ReactNode
testID?: string
}

export const Header1: React.FC<Interface> = ({ children }) => (
<Text style={styles.header1}>{children}</Text>
export const Header1: React.FC<Interface> = ({ children, testID }) => (
<Text style={styles.header1} testID={testID}>
{children}
</Text>
)

export const Header2: React.FC<Interface> = ({ children }) => (
<Text style={styles.header2}>{children}</Text>
export const Header2: React.FC<Interface> = ({ children, testID }) => (
<Text style={styles.header2} testID={testID}>
{children}
</Text>
)

export const Paragraph: React.FC<Interface> = ({ children }) => (
<Text style={styles.paragraph}>{children}</Text>
export const Paragraph: React.FC<Interface> = ({ children, testID }) => (
<Text style={styles.paragraph} testID={testID}>
{children}
</Text>
)

const styles = StyleSheet.create({
Expand Down
31 changes: 0 additions & 31 deletions src/lib/token/types/factories/ERC677__factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,37 +64,6 @@ const _abi = [
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
{
indexed: false,
internalType: "bytes",
name: "data",
type: "bytes",
},
],
name: "Transfer",
type: "event",
},
{
anonymous: false,
inputs: [
Expand Down
23 changes: 14 additions & 9 deletions src/screens/balances/BalancesScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import React from 'react'
import { render, fireEvent, waitFor } from '@testing-library/react-native'
import BalancesScreen from './BalancesScreen'
import mockedTokens from './tokens-mock.json'
import { act } from 'react-test-renderer'

//TODO: integration tests pending
jest.mock('../../lib/rifWalletServices/RifWalletServicesFetcher', () => {
return {
RifWalletServicesFetcher: jest.fn().mockImplementation(() => {
return {
fetchTokensByAddress: () => {
fetchTokensByAddress: async () => {
return mockedTokens
},
}
Expand Down Expand Up @@ -41,12 +42,14 @@ describe('Load balances', () => {
<BalancesScreen route={route} navigation={navigation as any} />,
)

await waitFor(() => expect(getByTestId('cUSDT.View')).toBeDefined())
await waitFor(() => expect(getByTestId('rUSDT.View')).toBeDefined())
await waitFor(() => expect(getByTestId('DOC.View')).toBeDefined())
await waitFor(() => expect(getByTestId('cRBTC.View')).toBeDefined())
await waitFor(() => expect(getByTestId('cRIF.View')).toBeDefined())
await waitFor(() => expect(getByTestId('tRIF.View')).toBeDefined())
await waitFor(() => getByTestId('cUSDT.View'))

expect(getByTestId('cUSDT.View')).toBeDefined()
expect(getByTestId('rUSDT.View')).toBeDefined()
expect(getByTestId('DOC.View')).toBeDefined()
expect(getByTestId('cRBTC.View')).toBeDefined()
expect(getByTestId('cRIF.View')).toBeDefined()
expect(getByTestId('tRIF.View')).toBeDefined()
})

it('select token to send', async () => {
Expand All @@ -56,8 +59,10 @@ describe('Load balances', () => {

await waitFor(() => expect(getByTestId('tRIF.Button')).toBeDefined())

fireEvent.press(getByTestId('tRIF.Button'))
act(() => {
fireEvent.press(getByTestId('tRIF.Button'))

expect(navigation.navigate).toBeCalled()
expect(navigation.navigate).toBeCalled()
})
})
})
6 changes: 2 additions & 4 deletions src/screens/balances/BalancesScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ const BalancesRow = ({
token: ITokenWithBalance
navigation: NavigationProp<ParamListBase>
}) => (
<View
key={token.symbol}
style={styles.tokenRow}
testID={`${token.symbol}.View`}>
<View style={styles.tokenRow} testID={`${token.symbol}.View`}>
<View style={styles.tokenBalance}>
<Text>
{token.symbol}{' '}
Expand Down Expand Up @@ -107,6 +104,7 @@ const BalancesScreen: React.FC<IReceiveScreenProps> = ({
{tokens &&
tokens.map(token => (
<BalancesRow
key={token.contractAddress}
account={account}
token={token}
navigation={navigation}
Expand Down
102 changes: 102 additions & 0 deletions src/screens/createWallet/ConfirmMasterKeyScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { NavigationProp, ParamListBase } from '@react-navigation/core'
import React, { useState, useContext } from 'react'
import { StyleSheet, View, ScrollView, TextInput } from 'react-native'

import { Header2, Paragraph } from '../../components/typography'

import Button from '../../components/button'
import { WalletProviderContext } from '../../state/AppContext'

interface Interface {
navigation: NavigationProp<ParamListBase>
route: any
}

const ConfirmMasterKeyScreen: React.FC<Interface> = ({ route, navigation }) => {
const { saveMnemonic } = useContext(WalletProviderContext)
const mnemonic = route.params.mnemonic as string

const [mnemonicToConfirm, setMnemonicToConfirm] = useState<
string | undefined
>()

const [error, setError] = useState<string | null>(null)

const saveAndNavigate = async () => {
await saveMnemonic(mnemonic)
navigation.navigate('WalletCreated', { mnemonic })
}

const handleConfirmMnemonic = async () => {
const isValid = mnemonic === mnemonicToConfirm

if (!isValid) {
setError('entered words does not match you your master key')
return
}

await saveAndNavigate()
}

return (
<ScrollView>
<View style={styles.sectionCentered}>
<Paragraph>
With your master key (seed phrase) you are able to create as many
wallets as you need.
</Paragraph>
</View>
<View style={styles.sectionCentered}>
<Paragraph>validate your master key</Paragraph>
</View>
<View style={styles.section}>
<Header2>Master key</Header2>
<TextInput
onChangeText={text => setMnemonicToConfirm(text)}
value={mnemonicToConfirm}
placeholder="Enter your 12 words master key"
multiline
style={styles.input}
testID="Input.Confirm"
/>
{error && <Paragraph>{error}</Paragraph>}
</View>
<View style={styles.section}>
<Button onPress={saveAndNavigate} title={'Skip'} />
</View>
<View style={styles.section}>
<Button
onPress={handleConfirmMnemonic}
title={'Confirm'}
testID="Button.Confirm"
/>
</View>
</ScrollView>
)
}

const styles = StyleSheet.create({
section: {
paddingTop: 15,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: '#CCCCCC',
},
sectionCentered: {
paddingTop: 15,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: '#CCCCCC',
alignItems: 'center',
},
input: {
height: 80,
margin: 12,
borderWidth: 1,
borderColor: '#000',
padding: 10,
textAlignVertical: 'top',
},
})

export default ConfirmMasterKeyScreen
Loading