mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 01:40:12 +01:00
Merge pull request #7284 from BlueWallet/import-ts2
feat: convert ImportCustomDerivationPath and ImportSpeed screens into Typescript
This commit is contained in:
commit
0211ff3140
@ -67,7 +67,11 @@ const AddWalletStack = () => {
|
||||
title: loc.wallets.add_title,
|
||||
})(theme)}
|
||||
/>
|
||||
<Stack.Screen name="ImportCustomDerivationPath" component={ImportCustomDerivationPathComponent} />
|
||||
<Stack.Screen
|
||||
name="ImportCustomDerivationPath"
|
||||
component={ImportCustomDerivationPathComponent}
|
||||
options={navigationStyle({ statusBarStyle: 'light', title: loc.wallets.import_derivation_title })(theme)}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="ImportWallet"
|
||||
component={ImportWalletComponent}
|
||||
|
@ -4,9 +4,9 @@ import { LazyLoadingIndicator } from './LazyLoadingIndicator';
|
||||
|
||||
// Define lazy imports
|
||||
const WalletsAdd = lazy(() => import('../screen/wallets/Add'));
|
||||
const ImportCustomDerivationPath = lazy(() => import('../screen/wallets/importCustomDerivationPath'));
|
||||
const ImportCustomDerivationPath = lazy(() => import('../screen/wallets/ImportCustomDerivationPath'));
|
||||
const ImportWalletDiscovery = lazy(() => import('../screen/wallets/ImportWalletDiscovery'));
|
||||
const ImportSpeed = lazy(() => import('../screen/wallets/importSpeed'));
|
||||
const ImportSpeed = lazy(() => import('../screen/wallets/ImportSpeed'));
|
||||
const ImportWallet = lazy(() => import('../screen/wallets/import'));
|
||||
const PleaseBackup = lazy(() => import('../screen/wallets/PleaseBackup'));
|
||||
const PleaseBackupLNDHub = lazy(() => import('../screen/wallets/pleaseBackupLNDHub'));
|
||||
|
@ -140,9 +140,7 @@ const LnurlPay: React.FC = () => {
|
||||
}
|
||||
|
||||
const bolt11payload = await _LN.requestBolt11FromLnurlPayService(amountSats, comment);
|
||||
// @ts-ignore fixme after lnurl.js converted to ts
|
||||
await wallet.payInvoice(bolt11payload.pr);
|
||||
// @ts-ignore fixme after lnurl.js converted to ts
|
||||
const decoded = wallet.decodeInvoice(bolt11payload.pr);
|
||||
setPayButtonDisabled(false);
|
||||
|
||||
|
@ -1,36 +1,48 @@
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { FlatList, StyleSheet, TextInput, View } from 'react-native';
|
||||
import debounce from '../../blue_modules/debounce';
|
||||
import { BlueFormLabel, BlueSpacing20, BlueTextCentered } from '../../BlueComponents';
|
||||
import { HDLegacyP2PKHWallet, HDSegwitBech32Wallet, HDSegwitP2SHWallet } from '../../class';
|
||||
import { validateBip32 } from '../../class/wallet-import';
|
||||
import { TWallet } from '../../class/wallets/types';
|
||||
import Button from '../../components/Button';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import WalletToImport from '../../components/WalletToImport';
|
||||
import loc from '../../loc';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import loc from '../../loc';
|
||||
import { AddWalletStackParamList } from '../../navigation/AddWalletStack';
|
||||
|
||||
type RouteProps = RouteProp<AddWalletStackParamList, 'ImportCustomDerivationPath'>;
|
||||
type NavigationProp = NativeStackNavigationProp<AddWalletStackParamList, 'ImportCustomDerivationPath'>;
|
||||
|
||||
const ListEmptyComponent: React.FC = () => <BlueTextCentered>{loc.wallets.import_wrong_path}</BlueTextCentered>;
|
||||
|
||||
const WRONG_PATH = 'WRONG_PATH';
|
||||
const WALLET_FOUND = 'WALLET_FOUND';
|
||||
const WALLET_NOTFOUND = 'WALLET_NOTFOUND';
|
||||
const WALLET_UNKNOWN = 'WALLET_UNKNOWN';
|
||||
enum STATUS {
|
||||
WALLET_FOUND = 'WALLET_FOUND',
|
||||
WALLET_NOTFOUND = 'WALLET_NOTFOUND',
|
||||
WALLET_UNKNOWN = 'WALLET_UNKNOWN',
|
||||
}
|
||||
type TWalletsByType = { [type: string]: TWallet };
|
||||
type TWalletsByPath = { [path: string]: TWalletsByType | 'WRONG_PATH' };
|
||||
|
||||
const ListEmptyComponent = () => <BlueTextCentered>{loc.wallets.import_wrong_path}</BlueTextCentered>;
|
||||
type TUsedByType = { [type: string]: STATUS };
|
||||
type TUsedByPath = { [path: string]: TUsedByType };
|
||||
|
||||
const ImportCustomDerivationPath = () => {
|
||||
const navigation = useNavigation();
|
||||
type TItem = [type: string, typeReadable: string, STATUS | undefined];
|
||||
|
||||
const ImportCustomDerivationPath: React.FC = () => {
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const { colors } = useTheme();
|
||||
const route = useRoute();
|
||||
const importText = route.params.importText;
|
||||
const password = route.params.password;
|
||||
const { importText, password } = useRoute<RouteProps>().params;
|
||||
const { addAndSaveWallet } = useStorage();
|
||||
const [path, setPath] = useState("m/84'/0'/0'");
|
||||
const [wallets, setWallets] = useState({});
|
||||
const [used, setUsed] = useState({});
|
||||
const [selected, setSelected] = useState();
|
||||
const [path, setPath] = useState<string>("m/84'/0'/0'");
|
||||
const [wallets, setWallets] = useState<TWalletsByPath>({});
|
||||
const [used, setUsed] = useState<TUsedByPath>({});
|
||||
const [selected, setSelected] = useState<string>('');
|
||||
const importing = useRef(false);
|
||||
|
||||
const debouncedSavePath = useRef(
|
||||
@ -41,25 +53,32 @@ const ImportCustomDerivationPath = () => {
|
||||
}
|
||||
|
||||
// create wallets
|
||||
const newWallets = {};
|
||||
const newWallets: { [type: string]: TWallet } = {};
|
||||
for (const Wallet of [HDLegacyP2PKHWallet, HDSegwitP2SHWallet, HDSegwitBech32Wallet]) {
|
||||
const wallet = new Wallet();
|
||||
wallet.setSecret(importText);
|
||||
wallet.setPassphrase(password);
|
||||
if (password) {
|
||||
wallet.setPassphrase(password);
|
||||
}
|
||||
wallet.setDerivationPath(newPath);
|
||||
newWallets[Wallet.type] = wallet;
|
||||
}
|
||||
setWallets(ws => ({ ...ws, [newPath]: newWallets }));
|
||||
|
||||
// discover was they ever used
|
||||
const res = {};
|
||||
const promises = Object.values(newWallets).map(w => w.wasEverUsed().then(v => (res[w.type] = v ? WALLET_FOUND : WALLET_NOTFOUND)));
|
||||
const promises = Object.values(newWallets).map(w => {
|
||||
return w.wasEverUsed().then(v => {
|
||||
const status = v ? STATUS.WALLET_FOUND : STATUS.WALLET_NOTFOUND;
|
||||
setUsed(u => ({ ...u, [newPath]: { ...u[newPath], [w.type]: status } }));
|
||||
});
|
||||
});
|
||||
try {
|
||||
await Promise.all(promises); // wait for all promises to be resolved
|
||||
await Promise.all(promises);
|
||||
} catch (e) {
|
||||
Object.values(newWallets).forEach(w => (res[w.type] = WALLET_UNKNOWN));
|
||||
Object.values(newWallets).forEach(w => {
|
||||
setUsed(u => ({ ...u, [newPath]: { ...u[newPath], [w.type]: STATUS.WALLET_UNKNOWN } }));
|
||||
});
|
||||
}
|
||||
setUsed(u => ({ ...u, [newPath]: res }));
|
||||
}, 500),
|
||||
);
|
||||
useEffect(() => {
|
||||
@ -67,7 +86,7 @@ const ImportCustomDerivationPath = () => {
|
||||
debouncedSavePath.current(path);
|
||||
}, [path, wallets]);
|
||||
|
||||
const items = useMemo(() => {
|
||||
const items: TItem[] = useMemo(() => {
|
||||
if (wallets[path] === WRONG_PATH) return [];
|
||||
return [
|
||||
[HDLegacyP2PKHWallet.type, HDLegacyP2PKHWallet.typeReadable, used[path]?.[HDLegacyP2PKHWallet.type]],
|
||||
@ -90,25 +109,26 @@ const ImportCustomDerivationPath = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const saveWallet = type => {
|
||||
const saveWallet = (type: string) => {
|
||||
if (importing.current) return;
|
||||
importing.current = true;
|
||||
const wallet = wallets[path][type];
|
||||
addAndSaveWallet(wallet);
|
||||
if (wallets[path] === WRONG_PATH) return;
|
||||
addAndSaveWallet(wallets[path][type]);
|
||||
// @ts-ignore: Navigation
|
||||
navigation.getParent().pop();
|
||||
};
|
||||
|
||||
const renderItem = ({ item }) => {
|
||||
const renderItem = ({ item }: { item: TItem }) => {
|
||||
const [type, title, found] = item;
|
||||
let subtitle;
|
||||
switch (found) {
|
||||
case WALLET_FOUND:
|
||||
case STATUS.WALLET_FOUND:
|
||||
subtitle = loc.wallets.import_derivation_found;
|
||||
break;
|
||||
case WALLET_NOTFOUND:
|
||||
case STATUS.WALLET_NOTFOUND:
|
||||
subtitle = loc.wallets.import_derivation_found_not;
|
||||
break;
|
||||
case WALLET_UNKNOWN:
|
||||
case STATUS.WALLET_UNKNOWN:
|
||||
subtitle = loc.wallets.import_derivation_unknown;
|
||||
break;
|
||||
default:
|
||||
@ -118,6 +138,8 @@ const ImportCustomDerivationPath = () => {
|
||||
return <WalletToImport key={type} title={title} subtitle={subtitle} active={selected === type} onPress={() => setSelected(type)} />;
|
||||
};
|
||||
|
||||
const disabled = wallets[path] === WRONG_PATH || wallets[path]?.[selected] === undefined;
|
||||
|
||||
return (
|
||||
<SafeArea style={[styles.root, stylesHook.root]}>
|
||||
<BlueSpacing20 />
|
||||
@ -141,12 +163,7 @@ const ImportCustomDerivationPath = () => {
|
||||
|
||||
<View style={[styles.center, stylesHook.center]}>
|
||||
<View style={styles.buttonContainer}>
|
||||
<Button
|
||||
disabled={wallets[path]?.[selected] === undefined}
|
||||
title={loc.wallets.import_do_import}
|
||||
testID="ImportButton"
|
||||
onPress={() => saveWallet(selected)}
|
||||
/>
|
||||
<Button disabled={disabled} title={loc.wallets.import_do_import} testID="ImportButton" onPress={() => saveWallet(selected)} />
|
||||
</View>
|
||||
</View>
|
||||
</SafeArea>
|
||||
@ -183,10 +200,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
ImportCustomDerivationPath.navigationOptions = navigationStyle({}, opts => ({
|
||||
...opts,
|
||||
title: loc.wallets.import_derivation_title,
|
||||
statusBarStyle: 'light',
|
||||
}));
|
||||
|
||||
export default ImportCustomDerivationPath;
|
@ -1,6 +1,7 @@
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import React, { useState } from 'react';
|
||||
import { ActivityIndicator, StyleSheet, TextInput, View } from 'react-native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { BlueFormLabel, BlueFormMultiInput, BlueSpacing20 } from '../../BlueComponents';
|
||||
import { HDSegwitBech32Wallet, WatchOnlyWallet } from '../../class';
|
||||
import presentAlert from '../../components/Alert';
|
||||
@ -8,14 +9,17 @@ import Button from '../../components/Button';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { AddWalletStackParamList } from '../../navigation/AddWalletStack';
|
||||
|
||||
type NavigationProp = NativeStackNavigationProp<AddWalletStackParamList, 'ImportSpeed'>;
|
||||
|
||||
const WalletsImportWallet = () => {
|
||||
const navigation = useNavigation();
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const { colors } = useTheme();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [importText, setImportText] = useState();
|
||||
const [walletType, setWalletType] = useState();
|
||||
const [passphrase, setPassphrase] = useState();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [importText, setImportText] = useState<string>('');
|
||||
const [walletType, setWalletType] = useState<string>('');
|
||||
const [passphrase, setPassphrase] = useState<string>('');
|
||||
const { addAndSaveWallet } = useStorage();
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@ -58,13 +62,21 @@ const WalletsImportWallet = () => {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!WalletClass) {
|
||||
throw new Error('Invalid wallet type');
|
||||
}
|
||||
|
||||
const wallet = new WalletClass();
|
||||
wallet.setSecret(importText);
|
||||
if (passphrase) wallet.setPassphrase(passphrase);
|
||||
// check wallet is type of HDSegwitBech32Wallet
|
||||
if (passphrase && wallet instanceof HDSegwitBech32Wallet) {
|
||||
wallet.setPassphrase(passphrase);
|
||||
}
|
||||
await wallet.fetchBalance();
|
||||
// @ts-ignore: navigation
|
||||
navigation.getParent().pop();
|
||||
addAndSaveWallet(wallet);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
presentAlert({ message: e.message });
|
||||
} finally {
|
||||
setLoading(false);
|
@ -1,18 +1,23 @@
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { BackHandler, I18nManager, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { disallowScreenshot } from 'react-native-screen-capture';
|
||||
import Button from '../../components/Button';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { disallowScreenshot } from 'react-native-screen-capture';
|
||||
import loc from '../../loc';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { useSettings } from '../../hooks/context/useSettings';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import loc from '../../loc';
|
||||
import { AddWalletStackParamList } from '../../navigation/AddWalletStack';
|
||||
|
||||
type RouteProps = RouteProp<AddWalletStackParamList, 'PleaseBackup'>;
|
||||
type NavigationProp = NativeStackNavigationProp<AddWalletStackParamList, 'PleaseBackup'>;
|
||||
|
||||
const PleaseBackup: React.FC = () => {
|
||||
const { wallets } = useStorage();
|
||||
const { walletID } = useRoute().params as { walletID: string };
|
||||
const { walletID } = useRoute<RouteProps>().params;
|
||||
const wallet = wallets.find(w => w.getID() === walletID);
|
||||
const navigation = useNavigation();
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const { isPrivacyBlurEnabled } = useSettings();
|
||||
const { colors } = useTheme();
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import BN from 'bignumber.js';
|
||||
import React, { useEffect, useReducer, useState } from 'react';
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { Icon } from '@rneui/themed';
|
||||
import BN from 'bignumber.js';
|
||||
import {
|
||||
Alert,
|
||||
Dimensions,
|
||||
@ -13,15 +15,18 @@ import {
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import { Icon } from '@rneui/themed';
|
||||
|
||||
import { BlueSpacing20 } from '../../BlueComponents';
|
||||
import { randomBytes } from '../../class/rng';
|
||||
import { FButton, FContainer } from '../../components/FloatButtons';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
import { Tabs } from '../../components/Tabs';
|
||||
import { BlueCurrentTheme, useTheme } from '../../components/themes';
|
||||
import loc from '../../loc';
|
||||
import { randomBytes } from '../../class/rng';
|
||||
import { AddWalletStackParamList } from '../../navigation/AddWalletStack';
|
||||
|
||||
type RouteProps = RouteProp<AddWalletStackParamList, 'ProvideEntropy'>;
|
||||
type NavigationProp = NativeStackNavigationProp<AddWalletStackParamList, 'ProvideEntropy'>;
|
||||
|
||||
export enum EActionType {
|
||||
push = 'push',
|
||||
@ -252,11 +257,10 @@ const D20Tab = ({ active }: { active: boolean }) => {
|
||||
return <Icon name="dice-d20" type="font-awesome-5" color={active ? colors.buttonAlternativeTextColor : colors.buttonBackgroundColor} />;
|
||||
};
|
||||
|
||||
const Entropy = () => {
|
||||
const ProvideEntropy = () => {
|
||||
const [entropy, dispatch] = useReducer(eReducer, initialState);
|
||||
// @ts-ignore: navigation is not typed yet
|
||||
const { onGenerated, words } = useRoute().params;
|
||||
const navigation = useNavigation();
|
||||
const { onGenerated, words } = useRoute<RouteProps>().params;
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const [tab, setTab] = useState(1);
|
||||
const [show, setShow] = useState(false);
|
||||
const { colors } = useTheme();
|
||||
@ -319,7 +323,6 @@ const Entropy = () => {
|
||||
buf = Buffer.concat([buf, random], bufLength);
|
||||
}
|
||||
|
||||
// @ts-ignore: navigation is not typed yet
|
||||
navigation.pop();
|
||||
onGenerated(buf);
|
||||
},
|
||||
@ -432,4 +435,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
export default Entropy;
|
||||
export default ProvideEntropy;
|
||||
|
Loading…
Reference in New Issue
Block a user