ADD: Ask user if they have backed up their seed phrase

This commit is contained in:
Marcos Rodriguez 2019-12-24 21:35:47 -06:00 committed by Overtorment
parent 29d35c36b5
commit ec5bc4a3c6
8 changed files with 151 additions and 59 deletions

View file

@ -7,6 +7,7 @@ import {
TouchableOpacity,
TouchableWithoutFeedback,
Animated,
Alert,
ActivityIndicator,
View,
KeyboardAvoidingView,
@ -375,6 +376,21 @@ export class BlueButtonLink extends Component {
}
}
export const BlueAlertWalletExportReminder = ({ onSuccess = () => {}, onFailure }) => {
Alert.alert(
'Wallet',
`Have your saved your wallet's backup phrase? This backup phrase is required to access your funds in case you lose this device. Without the backup phrase, your funds will be permanently lost.`,
[
{ text: 'Yes, I have', onPress: onSuccess, style: 'cancel' },
{
text: 'No, I have not',
onPress: onFailure,
},
],
{ cancelable: false },
);
};
export const BlueNavigationStyle = (navigation, withNavigationCloseButton = false, customCloseButtonFunction = undefined) => ({
headerStyle: {
backgroundColor: BlueApp.settings.brandingColor,

View file

@ -29,6 +29,7 @@ export class AbstractWallet {
this.preferredBalanceUnit = BitcoinUnit.BTC;
this.chain = Chain.ONCHAIN;
this.hideBalance = false;
this.userHasSavedExport = false;
}
getID() {
@ -42,6 +43,14 @@ export class AbstractWallet {
return this.transactions;
}
getUserHasSavedExport() {
return this.userHasSavedExport;
}
setUserHasSavedExport(value) {
this.userHasSavedExport = value;
}
/**
*
* @returns {string}

View file

@ -18,7 +18,7 @@ module.exports = {
header: 'Un Monedero esta representado con secreto (clave privada) y una dirección' + 'que puedes compartir para recibir monedas.',
add: 'Añadir Carterqa',
create_a_wallet: 'Crear una billetera',
create_a_wallet1: 'Es gratis y puedes crear cuantas deseas',
create_a_wallet1: 'Es gratis y puedes crear',
create_a_wallet2: 'cuantas usted quiera',
latest_transaction: 'última transacción',
empty_txs1: 'Sus transacciones aparecerán aquí,',

View file

@ -10,7 +10,13 @@ import {
TouchableOpacity,
Text,
} from 'react-native';
import { BlueNavigationStyle, BlueButton, BlueBitcoinAmount, BlueDismissKeyboardInputAccessory } from '../../BlueComponents';
import {
BlueNavigationStyle,
BlueButton,
BlueBitcoinAmount,
BlueDismissKeyboardInputAccessory,
BlueAlertWalletExportReminder,
} from '../../BlueComponents';
import { LightningCustodianWallet } from '../../class/lightning-custodian-wallet';
import PropTypes from 'prop-types';
import bech32 from 'bech32';
@ -47,16 +53,36 @@ export default class LNDCreateInvoice extends Component {
fromWallet,
amount: '',
description: '',
isLoading: false,
lnurl: '',
lnurlParams: null,
isLoading: true,
};
}
componentDidMount() {
renderReceiveDetails = async () => {
this.state.fromWallet.setUserHasSavedExport(true);
await BlueApp.saveToDisk();
if (this.props.navigation.state.params.uri) {
this.processLnurl(this.props.navigation.getParam('uri'));
}
this.setState({ isLoading: false });
};
componentDidMount() {
if (this.state.fromWallet.getUserHasSavedExport()) {
this.renderReceiveDetails();
} else {
BlueAlertWalletExportReminder({
onSuccess: this.renderReceiveDetails,
onFailure: () => {
this.props.navigation.dismiss();
this.props.navigation.navigate('WalletExport', {
address: this.state.fromWallet.getAddress(),
secret: this.state.fromWallet.getSecret(),
});
},
});
}
}
async createInvoice() {
@ -266,6 +292,7 @@ export default class LNDCreateInvoice extends Component {
LNDCreateInvoice.propTypes = {
navigation: PropTypes.shape({
goBack: PropTypes.func,
dismiss: PropTypes.func,
navigate: PropTypes.func,
getParam: PropTypes.func,
state: PropTypes.shape({

View file

@ -13,6 +13,7 @@ import {
BlueBitcoinAmount,
BlueText,
BlueSpacing20,
BlueAlertWalletExportReminder,
} from '../../BlueComponents';
import PropTypes from 'prop-types';
import Privacy from '../../Privacy';
@ -45,64 +46,78 @@ export default class ReceiveDetails extends Component {
};
}
async componentDidMount() {
Privacy.enableBlur();
console.log('receive/details - componentDidMount');
{
let address;
let wallet;
for (let w of BlueApp.getWallets()) {
if (w.getSecret() === this.state.secret) {
// found our wallet
wallet = w;
}
}
if (wallet) {
if (wallet.getAddressAsync) {
if (wallet.chain === Chain.ONCHAIN) {
try {
address = await Promise.race([wallet.getAddressAsync(), BlueApp.sleep(1000)]);
} catch (_) {}
if (!address) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
address = wallet._getExternalAddressByIndex(wallet.next_free_address_index);
} else {
BlueApp.saveToDisk(); // caching whatever getAddressAsync() generated internally
}
this.setState({
address: address,
});
} else if (wallet.chain === Chain.OFFCHAIN) {
try {
await Promise.race([wallet.getAddressAsync(), BlueApp.sleep(1000)]);
address = wallet.getAddress();
} catch (_) {}
if (!address) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
address = wallet.getAddress();
} else {
BlueApp.saveToDisk(); // caching whatever getAddressAsync() generated internally
}
}
console.warn(address)
this.setState({
address: address,
});
} else if (wallet.getAddress) {
this.setState({
address: wallet.getAddress(),
});
renderReceiveDetails = async () => {
this.wallet.setUserHasSavedExport(true);
await BlueApp.saveToDisk();
let address;
if (this.wallet.getAddressAsync) {
if (this.wallet.chain === Chain.ONCHAIN) {
try {
address = await Promise.race([this.wallet.getAddressAsync(), BlueApp.sleep(1000)]);
} catch (_) {}
if (!address) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
address = this.wallet._getExternalAddressByIndex(this.wallet.next_free_address_index);
} else {
BlueApp.saveToDisk(); // caching whatever getAddressAsync() generated internally
}
this.setState({
address: address,
});
} else if (this.wallet.chain === Chain.OFFCHAIN) {
try {
await Promise.race([this.wallet.getAddressAsync(), BlueApp.sleep(1000)]);
address = this.wallet.getAddress();
} catch (_) {}
if (!address) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
address = this.wallet.getAddress();
} else {
BlueApp.saveToDisk(); // caching whatever getAddressAsync() generated internally
}
}
this.setState({
address: address,
});
} else if (this.wallet.getAddress) {
this.setState({
address: this.wallet.getAddress(),
});
}
InteractionManager.runAfterInteractions(async () => {
const bip21encoded = bip21.encode(this.state.address);
this.setState({ bip21encoded });
});
};
componentDidMount() {
Privacy.enableBlur();
console.log('receive/details - componentDidMount');
for (let w of BlueApp.getWallets()) {
if (w.getSecret() === this.state.secret) {
// found our wallet
this.wallet = w;
}
}
if (this.wallet) {
if (!this.wallet.getUserHasSavedExport()) {
BlueAlertWalletExportReminder({
onSuccess: this.renderReceiveDetails,
onFailure: () => {
this.props.navigation.goBack();
this.props.navigation.navigate('WalletExport', {
address: this.wallet.getAddress(),
secret: this.wallet.getSecret(),
});
},
});
} else {
this.renderReceiveDetails();
}
}
}
componentWillUnmount() {

View file

@ -48,9 +48,15 @@ export default class WalletExport extends Component {
}
}
this.setState({
isLoading: false,
});
this.setState(
{
isLoading: false,
},
() => {
this.state.wallet.setUserHasSavedExport(true);
BlueApp.saveToDisk();
},
);
}
async componentWillUnmount() {

View file

@ -65,6 +65,7 @@ export default class WalletsImport extends Component {
alert(loc.wallets.import.success);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
w.setLabel(loc.wallets.import.imported + ' ' + w.typeReadable);
w.setUserHasSavedExport(true);
BlueApp.wallets.push(w);
await BlueApp.saveToDisk();
EV(EV.enum.WALLETS_COUNT_CHANGED);

View file

@ -25,6 +25,7 @@ import {
BlueReceiveButtonIcon,
BlueTransactionListItem,
BlueWalletNavigationHeader,
BlueAlertWalletExportReminder,
} from '../../BlueComponents';
import WalletGradient from '../../class/walletGradient';
import { Icon } from 'react-native-elements';
@ -433,7 +434,24 @@ export default class WalletTransactions extends Component {
this.setState({ wallet }, () => InteractionManager.runAfterInteractions(() => BlueApp.saveToDisk()));
})
}
onManageFundsPressed={() => this.setState({ isManageFundsModalVisible: true })}
onManageFundsPressed={() => {
if (this.state.wallet.getUserHasSavedExport()) {
this.setState({ isManageFundsModalVisible: true });
} else {
BlueAlertWalletExportReminder({
onSuccess: async () => {
this.state.wallet.setUserHasSavedExport(true);
await BlueApp.saveToDisk();
this.setState({ isManageFundsModalVisible: true });
},
onFailure: () =>
this.props.navigation.navigate('WalletExport', {
address: this.state.wallet.getAddress(),
secret: this.state.wallet.getSecret(),
}),
});
}
}}
/>
<View style={{ backgroundColor: '#FFFFFF', flex: 1 }}>
<FlatList