diff --git a/navigation/AddWalletStack.tsx b/navigation/AddWalletStack.tsx
index ae47a7b7a..72aae3017 100644
--- a/navigation/AddWalletStack.tsx
+++ b/navigation/AddWalletStack.tsx
@@ -67,7 +67,11 @@ const AddWalletStack = () => {
title: loc.wallets.add_title,
})(theme)}
/>
-
+
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'));
diff --git a/screen/lnd/lnurlPay.tsx b/screen/lnd/lnurlPay.tsx
index 4254acaee..c22f36a3b 100644
--- a/screen/lnd/lnurlPay.tsx
+++ b/screen/lnd/lnurlPay.tsx
@@ -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);
diff --git a/screen/wallets/importCustomDerivationPath.js b/screen/wallets/ImportCustomDerivationPath.tsx
similarity index 62%
rename from screen/wallets/importCustomDerivationPath.js
rename to screen/wallets/ImportCustomDerivationPath.tsx
index 70120eddb..1c683a2c4 100644
--- a/screen/wallets/importCustomDerivationPath.js
+++ b/screen/wallets/ImportCustomDerivationPath.tsx
@@ -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;
+type NavigationProp = NativeStackNavigationProp;
+
+const ListEmptyComponent: React.FC = () => {loc.wallets.import_wrong_path};
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 = () => {loc.wallets.import_wrong_path};
+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();
const { colors } = useTheme();
- const route = useRoute();
- const importText = route.params.importText;
- const password = route.params.password;
+ const { importText, password } = useRoute().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("m/84'/0'/0'");
+ const [wallets, setWallets] = useState({});
+ const [used, setUsed] = useState({});
+ const [selected, setSelected] = useState('');
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 setSelected(type)} />;
};
+ const disabled = wallets[path] === WRONG_PATH || wallets[path]?.[selected] === undefined;
+
return (
@@ -141,12 +163,7 @@ const ImportCustomDerivationPath = () => {
-
@@ -183,10 +200,4 @@ const styles = StyleSheet.create({
},
});
-ImportCustomDerivationPath.navigationOptions = navigationStyle({}, opts => ({
- ...opts,
- title: loc.wallets.import_derivation_title,
- statusBarStyle: 'light',
-}));
-
export default ImportCustomDerivationPath;
diff --git a/screen/wallets/importSpeed.js b/screen/wallets/ImportSpeed.tsx
similarity index 76%
rename from screen/wallets/importSpeed.js
rename to screen/wallets/ImportSpeed.tsx
index cb054c51e..9115ba883 100644
--- a/screen/wallets/importSpeed.js
+++ b/screen/wallets/ImportSpeed.tsx
@@ -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;
const WalletsImportWallet = () => {
- const navigation = useNavigation();
+ const navigation = useNavigation();
const { colors } = useTheme();
- const [loading, setLoading] = useState(false);
- const [importText, setImportText] = useState();
- const [walletType, setWalletType] = useState();
- const [passphrase, setPassphrase] = useState();
+ const [loading, setLoading] = useState(false);
+ const [importText, setImportText] = useState('');
+ const [walletType, setWalletType] = useState('');
+ const [passphrase, setPassphrase] = useState('');
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);
diff --git a/screen/wallets/PleaseBackup.tsx b/screen/wallets/PleaseBackup.tsx
index 739a12e46..3dff6f4d5 100644
--- a/screen/wallets/PleaseBackup.tsx
+++ b/screen/wallets/PleaseBackup.tsx
@@ -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;
+type NavigationProp = NativeStackNavigationProp;
const PleaseBackup: React.FC = () => {
const { wallets } = useStorage();
- const { walletID } = useRoute().params as { walletID: string };
+ const { walletID } = useRoute().params;
const wallet = wallets.find(w => w.getID() === walletID);
- const navigation = useNavigation();
+ const navigation = useNavigation();
const { isPrivacyBlurEnabled } = useSettings();
const { colors } = useTheme();
diff --git a/screen/wallets/ProvideEntropy.tsx b/screen/wallets/ProvideEntropy.tsx
index dd3287a36..1f2db356c 100644
--- a/screen/wallets/ProvideEntropy.tsx
+++ b/screen/wallets/ProvideEntropy.tsx
@@ -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;
+type NavigationProp = NativeStackNavigationProp;
export enum EActionType {
push = 'push',
@@ -252,11 +257,10 @@ const D20Tab = ({ active }: { active: boolean }) => {
return ;
};
-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().params;
+ const navigation = useNavigation();
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;