Remote backup screen with seed phrase

This commit is contained in:
minibits-cash
2023-11-20 00:44:35 +01:00
parent ada2f36070
commit c019f63f48
5 changed files with 174 additions and 0 deletions
+2
View File
@@ -156,6 +156,8 @@ const en = {
backupScreen: {
localBackup: "Local backup",
localBackupDescription: "Local backup stores a copy of all your ecash in the local database. Ecash is never deleted unless you switch off the backup. Please note that this backup is not encrypted.",
remoteBackup: "Remote backup",
remoteBackupDescription: "Seed phrase allows you to recover your ecash balance in case of device loss.",
recoveryTool: "Recovery tool",
recoveryToolDescription: "Show ecash backed up in the local database and attempt to recover unspent ones into the wallet in case the wallet storage gets corrupted or a transaction fails due to an unexpected error.",
removeSpentCoins: "Remove spent ecash",
+3
View File
@@ -26,6 +26,7 @@ import {
PrivacyScreen,
UpdateScreen,
BackupScreen,
RemoteBackupScreen,
LocalRecoveryScreen,
RelaysScreen,
TranDetailScreen,
@@ -212,6 +213,7 @@ export type SettingsStackParamList = {
updateSize: string,
}
Backup: undefined
RemoteBackup: undefined
LocalRecovery: undefined
Developer: undefined
Relays: undefined
@@ -240,6 +242,7 @@ const SettingsNavigator = function SettingsNavigator() {
<SettingsStack.Screen name="Privacy" component={PrivacyScreen} />
<SettingsStack.Screen name="Update" component={UpdateScreen} />
<SettingsStack.Screen name="Backup" component={BackupScreen} />
<SettingsStack.Screen name="RemoteBackup" component={RemoteBackupScreen} />
<SettingsStack.Screen name="LocalRecovery" component={LocalRecoveryScreen} />
<SettingsStack.Screen name="Developer" component={DeveloperScreen} />
<SettingsStack.Screen name="Relays" component={RelaysScreen} />
+20
View File
@@ -75,6 +75,10 @@ export const BackupScreen: FC<SettingsStackScreenProps<'Backup'>> = observer(fun
navigation.navigate('LocalRecovery')
}
const gotoRemoteBackup = function () {
navigation.navigate('RemoteBackup')
}
const checkSpent = async function () {
setIsLoading(true)
const result = (await Wallet.checkSpent()) as {
@@ -144,6 +148,22 @@ export const BackupScreen: FC<SettingsStackScreenProps<'Backup'>> = observer(fun
</>
}
/>
<Card
style={$card}
HeadingComponent={
<>
<ListItem
tx="backupScreen.remoteBackup"
subTx="backupScreen.remoteBackupDescription"
leftIcon='faDownload'
leftIconColor={colors.palette.blue200}
leftIconInverse={true}
style={$item}
onPress={gotoRemoteBackup}
/>
</>
}
/>
<Card
style={$card}
HeadingComponent={
+148
View File
@@ -0,0 +1,148 @@
import {observer} from 'mobx-react-lite'
import React, {FC, useEffect, useState} from 'react'
import {FlatList, Linking, Platform, Switch, TextStyle, View, ViewStyle} from 'react-native'
import {colors, spacing, useThemeColor} from '../theme'
import {SettingsStackScreenProps} from '../navigation' // @demo remove-current-line
import {
Icon,
ListItem,
Screen,
Text,
Card,
Loading,
ErrorModal,
InfoModal,
BottomModal,
Button,
$sizeStyles,
} from '../components'
import {useHeader} from '../utils/useHeader'
import AppError from '../utils/AppError'
import { log, RestoreClient } from '../services'
import { scale } from '@gocodingnow/rn-size-matters'
export const RemoteBackupScreen: FC<SettingsStackScreenProps<'RemoteBackup'>> = observer(function RemoteBackupScreen(_props) {
const {navigation, route} = _props
useHeader({
leftIcon: 'faArrowLeft',
onLeftPress: () => {
navigation.goBack()
},
})
// const {userSettingsStore} = useStores()
const [info, setInfo] = useState('')
const [seed, setSeed] = useState<string[]>([])
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<AppError | undefined>()
useEffect(() => {
const getSeed = async () => {
try {
setIsLoading(true)
const seed = await RestoreClient.getOrCreateSeed()
setSeed(seed.split(/\s+/))
setIsLoading(false)
} catch (e: any) {
handleError(e)
}
}
getSeed()
}, [])
const handleError = function (e: AppError): void {
setIsLoading(false)
setError(e)
}
const headerBg = useThemeColor('header')
return (
<Screen style={$screen}>
<View style={[$headerContainer, {backgroundColor: headerBg}]}>
<Text preset="heading" text="Remote backup" style={{color: 'white'}} />
</View>
<View style={$contentContainer}>
<Card
style={$card}
ContentComponent={
<ListItem
text='Your seed phrase'
subText='These 12 words allow you to recover your ecash balance in case of device loss. Write them down and keep safe outside of the device.'
leftIcon='faInfoCircle'
leftIconColor={colors.palette.iconYellow300}
leftIconInverse={true}
style={$item}
/>
}
/>
<Card
style={$card}
ContentComponent={
<>
<FlatList
data={seed}
numColumns={2}
renderItem={({ item, index }) => {
return(
<Button
key={index}
preset={'secondary'}
onPress={() => false}
text={`${index + 1}. ${item}`}
style={{minWidth: scale(150), margin: spacing.tiny}}
textStyle={$sizeStyles.xs}
/>
)
}}
keyExtractor={(item) => item}
style={{ flexGrow: 0 }}
contentContainerStyle={{alignItems: 'center'}}
/>
</>
}
/>
{isLoading && <Loading />}
</View>
{error && <ErrorModal error={error} />}
{info && <InfoModal message={info} />}
</Screen>
)
})
const $screen: ViewStyle = {}
const $headerContainer: TextStyle = {
alignItems: 'center',
padding: spacing.medium,
height: spacing.screenHeight * 0.18,
}
const $contentContainer: TextStyle = {
marginTop: -spacing.extraLarge * 2,
padding: spacing.extraSmall,
}
const $card: ViewStyle = {
marginBottom: spacing.small,
}
const $bottomModal: ViewStyle = {
flex: 1,
alignItems: 'center',
paddingVertical: spacing.large,
paddingHorizontal: spacing.small,
}
const $item: ViewStyle = {
paddingHorizontal: spacing.small,
paddingLeft: 0,
}
const $rightContainer: ViewStyle = {
// padding: spacing.extraSmall,
alignSelf: 'center',
//marginLeft: spacing.small,
}
+1
View File
@@ -28,6 +28,7 @@ export * from './SecurityScreen'
export * from './PrivacyScreen'
export * from './UpdateScreen'
export * from './BackupScreen'
export * from './RemoteBackupScreen'
export * from './LocalRecoveryScreen'
export * from './DeveloperScreen'
export * from './RelaysScreen'