Browse Source
sweep/import key: show error in Qt GUI to user as tooltip
regtest_lnd
SomberNight
6 years ago
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
7 changed files with
42 additions and
19 deletions
-
electrum/base_wizard.py
-
electrum/bitcoin.py
-
electrum/gui/kivy/uix/dialogs/installwizard.py
-
electrum/gui/qt/main_window.py
-
electrum/gui/qt/seed_dialog.py
-
electrum/keystore.py
-
electrum/wallet.py
|
|
@ -199,7 +199,7 @@ class BaseWizard(object): |
|
|
|
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.run) |
|
|
|
|
|
|
|
def import_addresses_or_keys(self): |
|
|
|
v = lambda x: keystore.is_address_list(x) or keystore.is_private_key_list(x) |
|
|
|
v = lambda x: keystore.is_address_list(x) or keystore.is_private_key_list(x, raise_on_error=True) |
|
|
|
title = _("Import Bitcoin Addresses") |
|
|
|
message = _("Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.") |
|
|
|
self.add_xpub_dialog(title=title, message=message, run_next=self.on_import, |
|
|
|
|
|
@ -615,11 +615,13 @@ def is_address(addr: str, *, net=None) -> bool: |
|
|
|
or is_b58_address(addr, net=net) |
|
|
|
|
|
|
|
|
|
|
|
def is_private_key(key: str) -> bool: |
|
|
|
def is_private_key(key: str, *, raise_on_error=False) -> bool: |
|
|
|
try: |
|
|
|
k = deserialize_privkey(key) |
|
|
|
return k is not False |
|
|
|
except: |
|
|
|
deserialize_privkey(key) |
|
|
|
return True |
|
|
|
except BaseException as e: |
|
|
|
if raise_on_error: |
|
|
|
raise |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -899,7 +899,12 @@ class AddXpubDialog(WizardDialog): |
|
|
|
|
|
|
|
def __init__(self, wizard, **kwargs): |
|
|
|
WizardDialog.__init__(self, wizard, **kwargs) |
|
|
|
self.is_valid = kwargs['is_valid'] |
|
|
|
def is_valid(x): |
|
|
|
try: |
|
|
|
return kwargs['is_valid'](x) |
|
|
|
except: |
|
|
|
return False |
|
|
|
self.is_valid = is_valid |
|
|
|
self.title = kwargs['title'] |
|
|
|
self.message = kwargs['message'] |
|
|
|
self.allow_multi = kwargs.get('allow_multi', False) |
|
|
|
|
|
@ -2669,14 +2669,22 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): |
|
|
|
if bitcoin.is_address(addr): |
|
|
|
return addr |
|
|
|
|
|
|
|
def get_pk(): |
|
|
|
def get_pk(*, raise_on_error=False): |
|
|
|
text = str(keys_e.toPlainText()) |
|
|
|
return keystore.get_private_keys(text) |
|
|
|
return keystore.get_private_keys(text, raise_on_error=raise_on_error) |
|
|
|
|
|
|
|
f = lambda: button.setEnabled(get_address() is not None and get_pk() is not None) |
|
|
|
def on_edit(): |
|
|
|
valid_privkeys = False |
|
|
|
try: |
|
|
|
valid_privkeys = get_pk(raise_on_error=True) is not None |
|
|
|
except Exception as e: |
|
|
|
button.setToolTip(f'{_("Error")}: {str(e)}') |
|
|
|
else: |
|
|
|
button.setToolTip('') |
|
|
|
button.setEnabled(get_address() is not None and valid_privkeys) |
|
|
|
on_address = lambda text: address_e.setStyleSheet((ColorScheme.DEFAULT if get_address() else ColorScheme.RED).as_stylesheet()) |
|
|
|
keys_e.textChanged.connect(f) |
|
|
|
address_e.textChanged.connect(f) |
|
|
|
keys_e.textChanged.connect(on_edit) |
|
|
|
address_e.textChanged.connect(on_edit) |
|
|
|
address_e.textChanged.connect(on_address) |
|
|
|
on_address(str(address_e.text())) |
|
|
|
if not d.exec_(): |
|
|
|
|
|
@ -198,8 +198,14 @@ class KeysLayout(QVBoxLayout): |
|
|
|
return self.text_e.text() |
|
|
|
|
|
|
|
def on_edit(self): |
|
|
|
b = self.is_valid(self.get_text()) |
|
|
|
self.parent.next_button.setEnabled(b) |
|
|
|
valid = False |
|
|
|
try: |
|
|
|
valid = self.is_valid(self.get_text()) |
|
|
|
except Exception as e: |
|
|
|
self.parent.next_button.setToolTip(f'{_("Error")}: {str(e)}') |
|
|
|
else: |
|
|
|
self.parent.next_button.setToolTip('') |
|
|
|
self.parent.next_button.setEnabled(valid) |
|
|
|
|
|
|
|
|
|
|
|
class SeedDialog(WindowModalDialog): |
|
|
|
|
|
@ -752,19 +752,21 @@ def is_address_list(text): |
|
|
|
return bool(parts) and all(bitcoin.is_address(x) for x in parts) |
|
|
|
|
|
|
|
|
|
|
|
def get_private_keys(text, *, allow_spaces_inside_key=True): |
|
|
|
def get_private_keys(text, *, allow_spaces_inside_key=True, raise_on_error=False): |
|
|
|
if allow_spaces_inside_key: # see #1612 |
|
|
|
parts = text.split('\n') |
|
|
|
parts = map(lambda x: ''.join(x.split()), parts) |
|
|
|
parts = list(filter(bool, parts)) |
|
|
|
else: |
|
|
|
parts = text.split() |
|
|
|
if bool(parts) and all(bitcoin.is_private_key(x) for x in parts): |
|
|
|
if bool(parts) and all(bitcoin.is_private_key(x, raise_on_error=raise_on_error) for x in parts): |
|
|
|
return parts |
|
|
|
|
|
|
|
|
|
|
|
def is_private_key_list(text, *, allow_spaces_inside_key=True): |
|
|
|
return bool(get_private_keys(text, allow_spaces_inside_key=allow_spaces_inside_key)) |
|
|
|
def is_private_key_list(text, *, allow_spaces_inside_key=True, raise_on_error=False): |
|
|
|
return bool(get_private_keys(text, |
|
|
|
allow_spaces_inside_key=allow_spaces_inside_key, |
|
|
|
raise_on_error=raise_on_error)) |
|
|
|
|
|
|
|
|
|
|
|
is_mpk = lambda x: is_old_mpk(x) or is_xpub(x) |
|
|
|
|
|
@ -1472,8 +1472,8 @@ class Imported_Wallet(Simple_Wallet): |
|
|
|
for key in keys: |
|
|
|
try: |
|
|
|
txin_type, pubkey = self.keystore.import_privkey(key, password) |
|
|
|
except Exception: |
|
|
|
bad_keys.append((key, _('invalid private key'))) |
|
|
|
except Exception as e: |
|
|
|
bad_keys.append((key, _('invalid private key') + f': {e}')) |
|
|
|
continue |
|
|
|
if txin_type not in ('p2pkh', 'p2wpkh', 'p2wpkh-p2sh'): |
|
|
|
bad_keys.append((key, _('not implemented type') + f': {txin_type}')) |
|
|
|