diff --git a/BlueComponents.js b/BlueComponents.js
index 1b3e8d21e..dbf36db71 100644
--- a/BlueComponents.js
+++ b/BlueComponents.js
@@ -92,6 +92,43 @@ export class BlueButton extends Component {
}
}
+export const BlueButtonHook = props => {
+ const { colors } = useTheme();
+ let backgroundColor = props.backgroundColor ? props.backgroundColor : colors.mainColor;
+ let fontColor = colors.buttonTextColor;
+ if (props.disabled === true) {
+ backgroundColor = colors.buttonDisabledBackgroundColor;
+ fontColor = colors.buttonDisabledTextColor;
+ }
+ let buttonWidth = props.width ? props.width : width / 1.5;
+ if ('noMinWidth' in props) {
+ buttonWidth = 0;
+ }
+ return (
+
+
+ {props.icon && }
+ {props.title && {props.title}}
+
+
+ );
+};
+
export class SecondButton extends Component {
render() {
let backgroundColor = this.props.backgroundColor ? this.props.backgroundColor : BlueCurrentTheme.colors.buttonBlueBackgroundColor;
@@ -130,72 +167,61 @@ export class SecondButton extends Component {
}
}
-export class BitcoinButton extends Component {
- render() {
- return (
- {
- if (this.props.onPress) this.props.onPress();
+export const BitcoinButton = props => {
+ const { colors } = useTheme();
+ return (
+
+
-
-
- {loc.wallets.add_bitcoin}
-
-
+
+ {loc.wallets.add_bitcoin}
-
- );
- }
-}
+
+
+
+ );
+};
-export class LightningButton extends Component {
- render() {
- return (
- {
- if (this.props.onPress) this.props.onPress();
+export const LightningButton = props => {
+ const { colors } = useTheme();
+ return (
+
+
-
-
- {loc.wallets.add_lightning}
-
-
+
+ {loc.wallets.add_lightning}
-
- );
- }
-}
+
+
+
+ );
+};
export class BlueWalletNavigationHeader extends Component {
static propTypes = {
@@ -398,7 +424,7 @@ export class BlueWalletNavigationHeader extends Component {
}
}
-export const BlueButtonLinkHook = ({ title, onPress }) => {
+export const BlueButtonLinkHook = props => {
const { colors } = useTheme();
return (
{
height: 60,
justifyContent: 'center',
}}
- onPress={onPress}
+ onPress={props.onPress}
+ {...props}
>
- {title}
+ {props.title}
);
};
@@ -656,6 +683,11 @@ export class BlueTextCentered extends Component {
}
}
+export const BlueTextCenteredHooks = props => {
+ const { colors } = useTheme();
+ return ;
+};
+
export const BlueListItem = React.memo(props => (
{
);
};
-export class BlueFormLabel extends Component {
- render() {
- return ;
- }
-}
+export const BlueFormLabel = props => {
+ const { colors } = useTheme();
+
+ return ;
+};
export class BlueFormInput extends Component {
render() {
@@ -1785,7 +1817,6 @@ const WalletCarouselItem = ({ item, index, onPress, handleLongPress }) => {
onPress={() => {
onPressedOut();
onPress(index);
- onPressedOut();
}}
/>
);
diff --git a/screen/wallets/add.js b/screen/wallets/add.js
index 4486b1636..bd54c10e3 100644
--- a/screen/wallets/add.js
+++ b/screen/wallets/add.js
@@ -1,9 +1,8 @@
/* global alert */
-import React, { Component } from 'react';
+import React, { useState, useEffect } from 'react';
import {
Text,
ScrollView,
- LayoutAnimation,
ActivityIndicator,
Keyboard,
KeyboardAvoidingView,
@@ -15,40 +14,35 @@ import {
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {
- BlueTextCentered,
- BlueText,
- BlueListItem,
+ BlueTextCenteredHooks,
+ BlueTextHooks,
+ BlueListItemHooks,
LightningButton,
BitcoinButton,
BlueFormLabel,
- BlueButton,
+ BlueButtonHook,
BlueNavigationStyle,
- BlueButtonLink,
+ BlueButtonLinkHook,
BlueSpacing20,
} from '../../BlueComponents';
-import PropTypes from 'prop-types';
import { HDSegwitBech32Wallet, SegwitP2SHWallet, HDSegwitP2SHWallet, LightningCustodianWallet, AppStorage } from '../../class';
-import { BlueCurrentTheme } from '../../components/themes';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
+import { useTheme, useNavigation } from '@react-navigation/native';
+import { Chain } from '../../models/bitcoinUnits';
import loc from '../../loc';
const EV = require('../../blue_modules/events');
const A = require('../../blue_modules/analytics');
const BlueApp: AppStorage = require('../../BlueApp');
-
const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
- backgroundColor: BlueCurrentTheme.colors.elevated,
},
label: {
flexDirection: 'row',
- borderColor: BlueCurrentTheme.colors.formBorder,
- borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
- backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
marginHorizontal: 20,
@@ -86,16 +80,12 @@ const styles = StyleSheet.create({
marginHorizontal: 20,
},
advancedText: {
- color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
},
lndUri: {
flexDirection: 'row',
- borderColor: BlueCurrentTheme.colors.formBorder,
- borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
- backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
@@ -113,334 +103,305 @@ const styles = StyleSheet.create({
},
noPadding: {
paddingHorizontal: 0,
- backgroundColor: BlueCurrentTheme.colors.elevated,
- },
- root: {
- backgroundColor: BlueCurrentTheme.colors.elevated,
},
});
-export default class WalletsAdd extends Component {
- constructor(props) {
- super(props);
- this.state = {
- isLoading: true,
- walletBaseURI: '',
- selectedIndex: 0,
- };
- }
+const WalletsAdd = () => {
+ const { colors } = useTheme();
- async componentDidMount() {
- let walletBaseURI = await AsyncStorage.getItem(AppStorage.LNDHUB);
- const isAdvancedOptionsEnabled = await BlueApp.isAdancedModeEnabled();
- walletBaseURI = walletBaseURI || '';
- this.setState({
- isLoading: false,
- activeBitcoin: undefined,
- label: '',
- isAdvancedOptionsEnabled,
- walletBaseURI,
- });
- }
-
- setLabel(text) {
- this.setState({
- label: text,
- }); /* also, a hack to make screen update new typed text */
- }
-
- onSelect(index) {
- this.setState({
- selectedIndex: index,
- });
- }
-
- showAdvancedOptions = () => {
- Keyboard.dismiss();
- LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
- this.setState({ isAdvancedOptionsEnabled: true });
+ const [isLoading, setIsLoading] = useState(true);
+ const [walletBaseURI, setWalletBaseURI] = useState();
+ const [selectedIndex, setSelectedIndex] = useState(0);
+ const [label, setLabel] = useState('');
+ const [isAdvancedOptionsEnabled, setIsAdvancedOptionsEnabled] = useState(false);
+ const [selectedWalletType, setSelectedWalletType] = useState(false);
+ const { navigate, goBack } = useNavigation();
+ const [entropy, setEntropy] = useState();
+ const [entropyButtonText, setEntropyButtonText] = useState(loc.wallets.add_entropy_provide);
+ const stylesHook = {
+ advancedText: {
+ color: colors.feeText,
+ },
+ label: {
+ borderColor: colors.formBorder,
+ borderBottomColor: colors.formBorder,
+ backgroundColor: colors.inputBackgroundColor,
+ },
+ noPadding: {
+ backgroundColor: colors.elevated,
+ },
+ root: {
+ backgroundColor: colors.elevated,
+ },
+ lndUri: {
+ borderColor: colors.formBorder,
+ borderBottomColor: colors.formBorder,
+ backgroundColor: colors.inputBackgroundColor,
+ },
};
- render() {
- if (this.state.isLoading) {
- return (
-
-
-
- );
- }
+ useEffect(() => {
+ AsyncStorage.getItem(AppStorage.LNDHUB)
+ .then(setWalletBaseURI)
+ .catch(() => setWalletBaseURI(''));
+ BlueApp.isAdancedModeEnabled()
+ .then(setIsAdvancedOptionsEnabled)
+ .finally(() => setIsLoading(false));
+ }, [isAdvancedOptionsEnabled]);
+ const entropyGenerated = newEntropy => {
let entropyTitle;
- if (!this.state.entropy) {
+ if (!newEntropy) {
entropyTitle = loc.wallets.add_entropy_provide;
- } else if (this.state.entropy.length < 32) {
+ } else if (newEntropy.length < 32) {
entropyTitle = loc.formatString(loc.wallets.add_entropy_remain, {
- gen: this.state.entropy.length,
- rem: 32 - this.state.entropy.length,
+ gen: newEntropy.length,
+ rem: 32 - newEntropy.length,
});
} else {
entropyTitle = loc.formatString(loc.wallets.add_entropy_generated, {
- gen: this.state.entropy.length,
+ gen: newEntropy.length,
});
}
+ setEntropy(newEntropy);
+ setEntropyButtonText(entropyTitle);
+ };
- return (
-
-
-
-
- {loc.wallets.add_wallet_name}
-
- {
- this.setLabel(text);
- }}
- style={styles.textInputCommon}
- editable={!this.state.isLoading}
- underlineColorAndroid="transparent"
- />
+ const createWallet = async () => {
+ setIsLoading(true);
+
+ let w;
+
+ if (selectedWalletType === Chain.OFFCHAIN) {
+ createLightningWallet(w);
+ } else if (selectedWalletType === Chain.ONCHAIN) {
+ if (selectedIndex === 2) {
+ // zero index radio - HD segwit
+ w = new HDSegwitP2SHWallet();
+ w.setLabel(label || loc.wallets.details.title);
+ } else if (selectedIndex === 1) {
+ // btc was selected
+ // index 1 radio - segwit single address
+ w = new SegwitP2SHWallet();
+ w.setLabel(label || loc.wallets.details.title);
+ } else {
+ // btc was selected
+ // index 2 radio - hd bip84
+ w = new HDSegwitBech32Wallet();
+ w.setLabel(label || loc.wallets.details.title);
+ }
+ if (selectedWalletType === Chain.ONCHAIN) {
+ if (entropy) {
+ try {
+ await w.generateFromEntropy(entropy);
+ } catch (e) {
+ console.log(e.toString());
+ alert(e.toString());
+ goBack();
+ return;
+ }
+ } else {
+ await w.generate();
+ }
+ BlueApp.wallets.push(w);
+ await BlueApp.saveToDisk();
+ EV(EV.enum.WALLETS_COUNT_CHANGED);
+ A(A.ENUM.CREATED_WALLET);
+ ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
+ if (w.type === HDSegwitP2SHWallet.type || w.type === HDSegwitBech32Wallet.type) {
+ navigate('PleaseBackup', {
+ secret: w.getSecret(),
+ });
+ } else {
+ goBack();
+ }
+ }
+ }
+ };
+
+ const createLightningWallet = async wallet => {
+ wallet = new LightningCustodianWallet();
+ wallet.setLabel(label || loc.wallets.details.title);
+
+ try {
+ const lndhub = walletBaseURI && walletBaseURI.trim().length > 0 ? walletBaseURI : LightningCustodianWallet.defaultBaseUri;
+ if (lndhub) {
+ const isValidNodeAddress = await LightningCustodianWallet.isValidNodeAddress(lndhub);
+ if (isValidNodeAddress) {
+ wallet.setBaseURI(lndhub);
+ wallet.init();
+ } else {
+ throw new Error('The provided node address is not valid LNDHub node.');
+ }
+ }
+ await wallet.createAccount();
+ await wallet.authorize();
+ } catch (Err) {
+ setIsLoading(false);
+ console.warn('lnd create failure', Err);
+ return alert(Err);
+ // giving app, not adding anything
+ }
+ A(A.ENUM.CREATED_LIGHTNING_WALLET);
+ await wallet.generate();
+ BlueApp.wallets.push(wallet);
+ await BlueApp.saveToDisk();
+ EV(EV.enum.WALLETS_COUNT_CHANGED);
+ A(A.ENUM.CREATED_WALLET);
+ ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
+ navigate('PleaseBackupLNDHub', {
+ wallet,
+ });
+ };
+
+ const navigateToEntropy = () => {
+ navigate('ProvideEntropy', { onGenerated: entropyGenerated });
+ };
+
+ const navigateToImportWallet = () => {
+ navigate('ImportWallet');
+ };
+
+ const handleOnBitcoinButtonPressed = () => {
+ Keyboard.dismiss();
+ setSelectedWalletType(Chain.ONCHAIN);
+ };
+
+ const handleOnLightningButtonPressed = () => {
+ Keyboard.dismiss();
+ setSelectedWalletType(Chain.OFFCHAIN);
+ };
+
+ return (
+
+
+
+
+ {loc.wallets.add_wallet_name}
+
+
+
+ {loc.wallets.add_wallet_type}
+
+
+
+
+ {loc.wallets.add_or}
- {loc.wallets.add_wallet_type}
+
+
-
- {
- Keyboard.dismiss();
- this.setState({
- activeBitcoin: true,
- activeLightning: false,
- });
- }}
- style={styles.button}
- />
-
- {loc.wallets.add_or}
-
- {
- Keyboard.dismiss();
- this.setState({
- activeBitcoin: false,
- activeLightning: true,
- });
- }}
- style={styles.button}
- />
-
-
-
- {(() => {
- if (this.state.activeBitcoin && this.state.isAdvancedOptionsEnabled) {
- return (
-
-
- {loc.settings.advanced_options}
- {
- this.onSelect(0, HDSegwitBech32Wallet.type);
- }}
- title={HDSegwitBech32Wallet.typeReadable}
- {...(this.state.selectedIndex === 0
- ? {
- rightIcon: ,
- }
- : { hideChevron: true })}
- />
- {
- this.onSelect(1, SegwitP2SHWallet.type);
- }}
- title={SegwitP2SHWallet.typeReadable}
- {...(this.state.selectedIndex === 1
- ? {
- rightIcon: ,
- }
- : { hideChevron: true })}
- />
- {
- this.onSelect(2, HDSegwitP2SHWallet.typeReadable.type);
- }}
- title={HDSegwitP2SHWallet.typeReadable}
- {...(this.state.selectedIndex === 2
- ? {
- rightIcon: ,
- }
- : { hideChevron: true })}
+
+ {(() => {
+ if (selectedWalletType === Chain.ONCHAIN && isAdvancedOptionsEnabled) {
+ return (
+
+
+ {loc.settings.advanced_options}
+ setSelectedIndex(0)}
+ title={HDSegwitBech32Wallet.typeReadable}
+ {...(selectedIndex === 0
+ ? {
+ rightIcon: ,
+ }
+ : { hideChevron: true })}
+ />
+ setSelectedIndex(1)}
+ title={SegwitP2SHWallet.typeReadable}
+ {...(selectedIndex === 1
+ ? {
+ rightIcon: ,
+ }
+ : { hideChevron: true })}
+ />
+ setSelectedIndex(2)}
+ title={HDSegwitP2SHWallet.typeReadable}
+ {...(selectedIndex === 2
+ ? {
+ rightIcon: ,
+ }
+ : { hideChevron: true })}
+ />
+
+ );
+ } else if (selectedWalletType === Chain.OFFCHAIN && isAdvancedOptionsEnabled) {
+ return (
+ <>
+
+ {loc.settings.advanced_options}
+
+ Connect to your LNDHub
+
+
- );
- } else if (this.state.activeLightning && this.state.isAdvancedOptionsEnabled) {
- return (
- <>
-
- {loc.settings.advanced_options}
-
- {loc.wallets.add_lndhub}
-
- this.setState({ walletBaseURI: text })}
- onSubmitEditing={Keyboard.dismiss}
- placeholder={loc.wallets.add_lndhub_placeholder}
- clearButtonMode="while-editing"
- autoCapitalize="none"
- placeholderTextColor="#81868e"
- style={styles.textInputCommon}
- editable={!this.state.isLoading}
- underlineColorAndroid="transparent"
- />
-
- >
- );
- } else if (this.state.activeBitcoin === undefined && this.state.isAdvancedOptionsEnabled) {
- return ;
- }
- })()}
-
- {!this.state.isLoading ? (
- {
- this.setState({ isLoading: true }, async () => {
- let w;
-
- if (this.state.activeLightning) {
- this.createLightningWallet = async () => {
- w = new LightningCustodianWallet();
- w.setLabel(this.state.label || loc.wallets.details_title);
-
- try {
- const lndhub =
- this.state.walletBaseURI.trim().length > 0
- ? this.state.walletBaseURI
- : LightningCustodianWallet.defaultBaseUri;
- if (lndhub) {
- const isValidNodeAddress = await LightningCustodianWallet.isValidNodeAddress(lndhub);
- if (isValidNodeAddress) {
- w.setBaseURI(lndhub);
- w.init();
- } else {
- throw new Error(loc.wallets.add_lndhub_error);
- }
- }
-
- await w.createAccount();
- await w.authorize();
- } catch (Err) {
- this.setState({ isLoading: false });
- console.warn('lnd create failure', Err);
- return alert(Err);
- // giving app, not adding anything
- }
- A(A.ENUM.CREATED_LIGHTNING_WALLET);
- await w.generate();
- BlueApp.wallets.push(w);
- await BlueApp.saveToDisk();
- EV(EV.enum.WALLETS_COUNT_CHANGED);
- A(A.ENUM.CREATED_WALLET);
- ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
- this.props.navigation.navigate('PleaseBackupLNDHub', {
- wallet: w,
- });
- };
- this.createLightningWallet();
- } else if (this.state.selectedIndex === 2) {
- // zero index radio - HD segwit
- w = new HDSegwitP2SHWallet();
- w.setLabel(this.state.label || loc.wallets.details_title);
- } else if (this.state.selectedIndex === 1) {
- // btc was selected
- // index 1 radio - segwit single address
- w = new SegwitP2SHWallet();
- w.setLabel(this.state.label || loc.wallets.details_title);
- } else {
- // btc was selected
- // index 2 radio - hd bip84
- w = new HDSegwitBech32Wallet();
- w.setLabel(this.state.label || loc.wallets.details_title);
- }
- if (this.state.activeBitcoin) {
- if (this.state.entropy) {
- try {
- await w.generateFromEntropy(this.state.entropy);
- } catch (e) {
- console.log(e.toString());
- alert(e.toString());
- this.props.navigation.goBack();
- return;
- }
- } else {
- await w.generate();
- }
- BlueApp.wallets.push(w);
- await BlueApp.saveToDisk();
- EV(EV.enum.WALLETS_COUNT_CHANGED);
- A(A.ENUM.CREATED_WALLET);
- ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
- if (w.type === HDSegwitP2SHWallet.type || w.type === HDSegwitBech32Wallet.type) {
- this.props.navigation.navigate('PleaseBackup', {
- secret: w.getSecret(),
- });
- } else {
- this.props.navigation.goBack();
- }
- }
- });
- }}
- />
- ) : (
-
- )}
-
-
+ );
+ }
+ })()}
+
+ {!isLoading ? (
+
+ ) : (
+
+ )}
+
+ {!isLoading && (
+ {
- this.props.navigation.navigate('ImportWallet');
- }}
+ onPress={navigateToImportWallet}
/>
- {this.state.isAdvancedOptionsEnabled && (
- {
- this.props.navigation.navigate('ProvideEntropy', { onGenerated: entropy => this.setState({ entropy }) });
- }}
- />
- )}
-
-
-
- );
- }
-}
+ )}
+ {isAdvancedOptionsEnabled && !isLoading && (
+
+ )}
+
+
+
+ );
+};
WalletsAdd.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
- title: loc.wallets.add_title,
+ headerTitle: loc.wallets.add_title,
headerLeft: null,
});
-WalletsAdd.propTypes = {
- navigation: PropTypes.shape({
- navigate: PropTypes.func,
- goBack: PropTypes.func,
- }),
-};
+export default WalletsAdd;