/* global alert */ import React, { Component } from 'react'; import { Alert, Text, LayoutAnimation, ActivityIndicator, Keyboard, KeyboardAvoidingView, Platform, View, TextInput } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import { BlueTextCentered, BlueText, LightningButton, BitcoinButton, BlueFormLabel, BlueButton, SafeBlueArea, BlueFormInput, BlueNavigationStyle, BlueButtonLink, BlueSpacing20, BlueSpacing10, } from '../../BlueComponents'; import { RadioGroup, RadioButton } from 'react-native-flexi-radio-button'; import PropTypes from 'prop-types'; import { HDSegwitP2SHWallet } from '../../class/hd-segwit-p2sh-wallet'; import { LightningCustodianWallet } from '../../class/lightning-custodian-wallet'; import { AppStorage, HDSegwitBech32Wallet, SegwitP2SHWallet } from '../../class'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; let EV = require('../../events'); let A = require('../../analytics'); /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); let loc = require('../../loc'); export default class WalletsAdd extends Component { static navigationOptions = ({ navigation }) => ({ ...BlueNavigationStyle(navigation, true), title: loc.wallets.add.title, headerLeft: null, }); constructor(props) { super(props); this.state = { isLoading: true, walletBaseURI: '', }; } async componentDidMount() { let walletBaseURI = await AsyncStorage.getItem(AppStorage.LNDHUB); let isAdvancedOptionsEnabled = !!(await AsyncStorage.getItem(AppStorage.ADVANCED_MODE_ENABLED)); 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, value) { this.setState({ selectedIndex: index, selectedValue: value, }); } showAdvancedOptions = () => { Keyboard.dismiss(); LayoutAnimation.configureNext(LayoutAnimation.Presets.spring); this.setState({ isAdvancedOptionsEnabled: true }); }; render() { if (this.state.isLoading) { return ( ); } return ( {loc.wallets.add.wallet_name} { this.setLabel(text); }} style={{ flex: 1, marginHorizontal: 8, color: '#81868e' }} editable={!this.state.isLoading} underlineColorAndroid="transparent" /> {loc.wallets.add.wallet_type} { Keyboard.dismiss(); this.setState({ activeBitcoin: true, activeLightning: false, }); }} style={{ width: 141, height: 88, }} /> {loc.wallets.add.or} { Keyboard.dismiss(); this.setState({ activeBitcoin: false, activeLightning: true, }); }} style={{ width: 141, height: 88, }} /> {(() => { if (this.state.activeBitcoin && this.state.isAdvancedOptionsEnabled) { return ( {loc.settings.advanced_options} this.onSelect(index, value)} selectedIndex={0}> {HDSegwitP2SHWallet.typeReadable} - Multiple addresses {SegwitP2SHWallet.typeReadable} - Single address {HDSegwitBech32Wallet.typeReadable} - Multiple addresses ); } else if (this.state.activeLightning && this.state.isAdvancedOptionsEnabled) { return ( {loc.settings.advanced_options} Connect to your LNDHub { this.setState({ walletBaseURI: text }); }} onSubmitEditing={Keyboard.dismiss} placeholder="your node address" clearButtonMode="while-editing" autoCapitalize="none" /> ); } else if (this.state.activeBitcoin === undefined && this.state.isAdvancedOptionsEnabled) { return ; } })()} {!this.state.isLoading ? ( { this.setState( { isLoading: true }, async () => { let w; if (this.state.activeLightning) { // eslint-disable-next-line this.createLightningWallet = async () => { w = new LightningCustodianWallet(); w.setLabel(this.state.label || loc.wallets.details.title); try { let 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('The provided node address is not valid LNDHub node.'); } } 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.dismiss(); }; if (!BlueApp.getWallets().some(wallet => wallet.type !== LightningCustodianWallet.type)) { Alert.alert( loc.wallets.add.lightning, loc.wallets.createBitcoinWallet, [ { text: loc.send.details.cancel, style: 'cancel', onPress: () => { this.setState({ isLoading: false }); }, }, { text: loc._.ok, style: 'default', onPress: () => { this.createLightningWallet(); }, }, ], { cancelable: false }, ); } else { this.createLightningWallet(); } } else if (this.state.selectedIndex === 2) { // btc was selected // index 2 radio - hd bip84 w = new HDSegwitBech32Wallet(); 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 { // zero index radio - HD segwit w = new HDSegwitP2SHWallet(); w.setLabel(this.state.label || loc.wallets.details.title); } if (this.state.activeBitcoin) { 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.dismiss(); } } }, 1, ); }} /> ) : ( )} { this.props.navigation.navigate('ImportWallet'); }} /> ); } } WalletsAdd.propTypes = { navigation: PropTypes.shape({ navigate: PropTypes.func, goBack: PropTypes.func, dismiss: PropTypes.func, }), };