mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-21 14:34:55 +01:00
ADD: Ask user if they have backed up their seed phrase
This commit is contained in:
parent
29d35c36b5
commit
ec5bc4a3c6
8 changed files with 151 additions and 59 deletions
|
@ -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,
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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í,',
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue