On Android, if channels are not recoverable, display channel backup when a new channel is created.
Remove the 'android_backups' setting, which was unpractical.
This commit is contained in:
@@ -193,10 +193,6 @@ class ElectrumWindow(App, Logger):
|
||||
self.network.run_from_another_thread(
|
||||
self.network.stop_gossip())
|
||||
|
||||
android_backups = BooleanProperty(False)
|
||||
def on_android_backups(self, instance, x):
|
||||
self.electrum_config.set_key('android_backups', self.android_backups, True)
|
||||
|
||||
use_change = BooleanProperty(False)
|
||||
def on_use_change(self, instance, x):
|
||||
if self.wallet:
|
||||
@@ -407,7 +403,6 @@ class ElectrumWindow(App, Logger):
|
||||
self.daemon = self.gui_object.daemon
|
||||
self.fx = self.daemon.fx
|
||||
self.use_rbf = config.get('use_rbf', True)
|
||||
self.android_backups = config.get('android_backups', False)
|
||||
self.use_gossip = config.get('use_gossip', False)
|
||||
self.use_unconfirmed = not config.get('confirmed_only', False)
|
||||
|
||||
@@ -1300,9 +1295,14 @@ class ElectrumWindow(App, Logger):
|
||||
|
||||
def save_backup(self):
|
||||
if platform != 'android':
|
||||
self._save_backup()
|
||||
backup_dir = util.get_backup_dir(self.electrum_config)
|
||||
if backup_dir:
|
||||
self._save_backup(backup_dir)
|
||||
else:
|
||||
self.show_error(_("Backup NOT saved. Backup directory not configured."))
|
||||
return
|
||||
|
||||
backup_dir = util.android_backup_dir()
|
||||
from android.permissions import request_permissions, Permission
|
||||
def cb(permissions, grant_results: Sequence[bool]):
|
||||
if not grant_results or not grant_results[0]:
|
||||
@@ -1313,17 +1313,14 @@ class ElectrumWindow(App, Logger):
|
||||
Clock.schedule_once(lambda dt: self._save_backup())
|
||||
request_permissions([Permission.WRITE_EXTERNAL_STORAGE], cb)
|
||||
|
||||
def _save_backup(self):
|
||||
def _save_backup(self, backup_dir):
|
||||
try:
|
||||
new_path = self.wallet.save_backup()
|
||||
new_path = self.wallet.save_backup(backup_dir)
|
||||
except Exception as e:
|
||||
self.logger.exception("Failed to save wallet backup")
|
||||
self.show_error("Failed to save wallet backup" + '\n' + str(e))
|
||||
return
|
||||
if new_path:
|
||||
self.show_info(_("Backup saved:") + f"\n{new_path}")
|
||||
else:
|
||||
self.show_error(_("Backup NOT saved. Backup directory not configured."))
|
||||
self.show_info(_("Backup saved:") + f"\n{new_path}")
|
||||
|
||||
def export_private_keys(self, pk_label, addr):
|
||||
if self.wallet.is_watching_only():
|
||||
|
||||
@@ -13,6 +13,7 @@ from electrum.lnutil import ln_dummy_address, extract_nodeid
|
||||
|
||||
from .label_dialog import LabelDialog
|
||||
from .confirm_tx_dialog import ConfirmTxDialog
|
||||
from .qr_dialog import QRDialog
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...main_window import ElectrumWindow
|
||||
@@ -208,6 +209,27 @@ class LightningOpenChannelDialog(Factory.Popup, Logger):
|
||||
self.app.logger.exception("Problem opening channel")
|
||||
self.app.show_error(_('Problem opening channel: ') + '\n' + repr(e))
|
||||
return
|
||||
# TODO: it would be nice to show this before broadcasting
|
||||
if lnworker.has_recoverable_channels():
|
||||
self.maybe_show_funding_tx(chan, funding_tx)
|
||||
else:
|
||||
title = _('Save backup')
|
||||
help_text = ' '.join([
|
||||
_('Your wallet does not have recoverable channels.'),
|
||||
_('Please save this channel backup on another device.'),
|
||||
_('It may be imported in another Electrum wallet with the same seed.')
|
||||
])
|
||||
data = lnworker.export_channel_backup(chan.channel_id)
|
||||
popup = QRDialog(
|
||||
title, data,
|
||||
show_text=False,
|
||||
text_for_clipboard=data,
|
||||
help_text=help_text,
|
||||
close_button_text=_('OK'),
|
||||
on_close=lambda: self.maybe_show_funding_tx(chan, funding_tx))
|
||||
popup.open()
|
||||
|
||||
def maybe_show_funding_tx(self, chan, funding_tx):
|
||||
n = chan.constraints.funding_txn_minimum_depth
|
||||
message = '\n'.join([
|
||||
_('Channel established.'),
|
||||
@@ -217,5 +239,6 @@ class LightningOpenChannelDialog(Factory.Popup, Logger):
|
||||
if not funding_tx.is_complete():
|
||||
message += '\n\n' + _('Please sign and broadcast the funding transaction')
|
||||
self.app.show_info(message)
|
||||
|
||||
if not funding_tx.is_complete():
|
||||
self.app.tx_dialog(funding_tx)
|
||||
|
||||
@@ -93,13 +93,6 @@ Builder.load_string('''
|
||||
title: _('Lightning Routing') + ': ' + self.status
|
||||
description: _("Use trampoline routing or gossip.")
|
||||
action: partial(root.routing_dialog, self)
|
||||
CardSeparator
|
||||
SettingsItem:
|
||||
status: _('Yes') if app.android_backups else _('No')
|
||||
title: _('Backups') + ': ' + self.status
|
||||
description: _("Backup wallet to external storage.")
|
||||
message: _("If this option is checked, a backup of your wallet will be written to external storage everytime you create a new channel. Make sure your wallet is protected with a strong password before you enable this option.")
|
||||
action: partial(root.boolean_dialog, 'android_backups', _('Backups'), self.message)
|
||||
|
||||
# disabled: there is currently only one coin selection policy
|
||||
#CardSeparator
|
||||
|
||||
@@ -81,7 +81,6 @@ Popup:
|
||||
size_hint: 0.5, None
|
||||
height: '48dp'
|
||||
text: _('Export Backup')
|
||||
disabled: not app.android_backups
|
||||
on_release:
|
||||
root.dismiss()
|
||||
app.save_backup()
|
||||
|
||||
@@ -627,18 +627,18 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
|
||||
if not d.exec_():
|
||||
return False
|
||||
backup_dir = get_backup_dir(self.config)
|
||||
if backup_dir is not None:
|
||||
self.show_message(_("You need to configure a backup directory in your preferences"), title=_("Backup not configured"))
|
||||
return
|
||||
try:
|
||||
new_path = self.wallet.save_backup()
|
||||
new_path = self.wallet.save_backup(backup_dir)
|
||||
except BaseException as reason:
|
||||
self.show_critical(_("Electrum was unable to copy your wallet file to the specified location.") + "\n" + str(reason), title=_("Unable to create backup"))
|
||||
return
|
||||
if new_path:
|
||||
msg = _("A copy of your wallet file was created in")+" '%s'" % str(new_path)
|
||||
self.show_message(msg, title=_("Wallet backup created"))
|
||||
return True
|
||||
else:
|
||||
self.show_message(_("You need to configure a backup directory in your preferences"), title=_("Backup not created"))
|
||||
return False
|
||||
msg = _("A copy of your wallet file was created in")+" '%s'" % str(new_path)
|
||||
self.show_message(msg, title=_("Wallet backup created"))
|
||||
return True
|
||||
|
||||
def update_recently_visited(self, filename):
|
||||
recent = self.config.get('recently_open', [])
|
||||
|
||||
@@ -26,7 +26,7 @@ from aiorpcx import run_in_thread, TaskGroup, NetAddress, ignore_after
|
||||
|
||||
from . import constants, util
|
||||
from . import keystore
|
||||
from .util import profiler, chunks
|
||||
from .util import profiler, chunks, get_backup_dir
|
||||
from .invoices import PR_TYPE_LN, PR_UNPAID, PR_EXPIRED, PR_PAID, PR_INFLIGHT, PR_FAILED, PR_ROUTING, LNInvoice, LN_EXPIRY_NEVER
|
||||
from .util import NetworkRetryManager, JsonRPCClient
|
||||
from .lnutil import LN_MAX_FUNDING_SAT
|
||||
@@ -1003,7 +1003,9 @@ class LNWallet(LNWorker):
|
||||
self.wallet.set_reserved_state_of_address(addr, reserved=True)
|
||||
try:
|
||||
self.save_channel(chan)
|
||||
self.wallet.save_backup()
|
||||
backup_dir = get_backup_dir(self.config)
|
||||
if backup_dir is not None:
|
||||
self.wallet.save_backup(backup_dir)
|
||||
except:
|
||||
chan.set_state(ChannelState.REDEEMED)
|
||||
self.remove_channel(chan.channel_id)
|
||||
|
||||
@@ -428,8 +428,10 @@ def android_data_dir():
|
||||
return PythonActivity.mActivity.getFilesDir().getPath() + '/data'
|
||||
|
||||
def get_backup_dir(config):
|
||||
# this is used to save a backup everytime a channel is created
|
||||
# on Android, the export backup button uses android_backup_dir()
|
||||
if 'ANDROID_DATA' in os.environ:
|
||||
return android_backup_dir() if config.get('android_backups') else None
|
||||
return None
|
||||
else:
|
||||
return config.get('backup_dir')
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ from .util import (NotEnoughFunds, UserCancelled, profiler,
|
||||
WalletFileException, BitcoinException, MultipleSpendMaxTxOutputs,
|
||||
InvalidPassword, format_time, timestamp_to_datetime, Satoshis,
|
||||
Fiat, bfh, bh2u, TxMinedInfo, quantize_feerate, create_bip21_uri, OrderedDictWithIndex)
|
||||
from .util import get_backup_dir
|
||||
from .simple_config import SimpleConfig, FEE_RATIO_HIGH_WARNING, FEERATE_WARNING_HIGH_FEE
|
||||
from .bitcoin import COIN, TYPE_ADDRESS
|
||||
from .bitcoin import is_address, address_to_script, is_minikey, relayfee, dust_threshold
|
||||
@@ -315,10 +314,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
||||
if self.storage:
|
||||
self.db.write(self.storage)
|
||||
|
||||
def save_backup(self):
|
||||
backup_dir = get_backup_dir(self.config)
|
||||
if backup_dir is None:
|
||||
return
|
||||
def save_backup(self, backup_dir):
|
||||
new_db = WalletDB(self.db.dump(), manual_upgrades=False)
|
||||
|
||||
if self.lnworker:
|
||||
|
||||
Reference in New Issue
Block a user