bip39_recovery_dialog.py (2977B)
1 # Copyright (C) 2020 The Electrum developers 2 # Distributed under the MIT software license, see the accompanying 3 # file LICENCE or http://www.opensource.org/licenses/mit-license.php 4 5 from PyQt5.QtCore import Qt 6 from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGridLayout, QLabel, QListWidget, QListWidgetItem 7 8 from electrum.i18n import _ 9 from electrum.network import Network 10 from electrum.bip39_recovery import account_discovery 11 from electrum.logging import get_logger 12 13 from .util import WindowModalDialog, MessageBoxMixin, TaskThread, Buttons, CancelButton, OkButton 14 15 16 _logger = get_logger(__name__) 17 18 19 class Bip39RecoveryDialog(WindowModalDialog): 20 def __init__(self, parent: QWidget, get_account_xpub, on_account_select): 21 self.get_account_xpub = get_account_xpub 22 self.on_account_select = on_account_select 23 WindowModalDialog.__init__(self, parent, _('BIP39 Recovery')) 24 self.setMinimumWidth(400) 25 vbox = QVBoxLayout(self) 26 self.content = QVBoxLayout() 27 self.content.addWidget(QLabel(_('Scanning common paths for existing accounts...'))) 28 vbox.addLayout(self.content) 29 self.ok_button = OkButton(self) 30 self.ok_button.clicked.connect(self.on_ok_button_click) 31 self.ok_button.setEnabled(False) 32 vbox.addLayout(Buttons(CancelButton(self), self.ok_button)) 33 self.finished.connect(self.on_finished) 34 self.show() 35 self.thread = TaskThread(self) 36 self.thread.finished.connect(self.deleteLater) # see #3956 37 self.thread.add(self.recovery, self.on_recovery_success, None, self.on_recovery_error) 38 39 def on_finished(self): 40 self.thread.stop() 41 42 def on_ok_button_click(self): 43 item = self.list.currentItem() 44 account = item.data(Qt.UserRole) 45 self.on_account_select(account) 46 47 def recovery(self): 48 network = Network.get_instance() 49 coroutine = account_discovery(network, self.get_account_xpub) 50 return network.run_from_another_thread(coroutine) 51 52 def on_recovery_success(self, accounts): 53 self.clear_content() 54 if len(accounts) == 0: 55 self.content.addWidget(QLabel(_('No existing accounts found.'))) 56 return 57 self.content.addWidget(QLabel(_('Choose an account to restore.'))) 58 self.list = QListWidget() 59 for account in accounts: 60 item = QListWidgetItem(account['description']) 61 item.setData(Qt.UserRole, account) 62 self.list.addItem(item) 63 self.list.clicked.connect(lambda: self.ok_button.setEnabled(True)) 64 self.content.addWidget(self.list) 65 66 def on_recovery_error(self, exc_info): 67 self.clear_content() 68 self.content.addWidget(QLabel(_('Error: Account discovery failed.'))) 69 _logger.error(f"recovery error", exc_info=exc_info) 70 71 def clear_content(self): 72 for i in reversed(range(self.content.count())): 73 self.content.itemAt(i).widget().setParent(None)