Browse Source

wizard: display seed type. restore 2fa if needed

master
ThomasV 9 years ago
parent
commit
c32f75a313
  1. 4
      gui/qt/installwizard.py
  2. 10
      gui/qt/seed_dialog.py
  3. 49
      lib/base_wizard.py
  4. 13
      lib/bitcoin.py
  5. 4
      lib/keystore.py
  6. 5
      plugins/trustedcoin/qt.py
  7. 16
      plugins/trustedcoin/trustedcoin.py

4
gui/qt/installwizard.py

@ -256,9 +256,9 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
vbox.addStretch(1)
vbox.addWidget(QLabel(_('Options') + ':'))
def f(b):
slayout.is_seed = (lambda x: bool(x)) if b else is_valid
slayout.is_seed = (lambda x: bool(x)) if b else is_seed
slayout.on_edit()
cb_bip39 = QCheckBox(_('BIP39/BIP44 seed'))
cb_bip39 = QCheckBox(_('BIP39 seed'))
cb_bip39.toggled.connect(f)
vbox.addWidget(cb_bip39)
self.set_main_layout(vbox, title, next_enabled=False)

10
gui/qt/seed_dialog.py

@ -122,6 +122,8 @@ class SeedInputLayout(SeedLayoutBase):
def __init__(self, parent, title, is_seed):
vbox = QVBoxLayout()
vbox.addLayout(self._seed_layout(title=title))
self.seed_type_label = QLabel('')
vbox.addWidget(self.seed_type_label)
self.layout_ = vbox
self.parent = parent
self.is_seed = is_seed
@ -131,7 +133,13 @@ class SeedInputLayout(SeedLayoutBase):
return clean_text(self.seed_edit())
def on_edit(self):
self.parent.next_button.setEnabled(self.is_seed(self.get_seed()))
from electrum.bitcoin import seed_type
s = self.get_seed()
b = self.is_seed(s)
t = seed_type(s)
label = _('Seed Type') + ': ' + t if t else ''
self.seed_type_label.setText(label)
self.parent.next_button.setEnabled(b)

49
lib/base_wizard.py

@ -24,6 +24,7 @@
# SOFTWARE.
import os
import bitcoin
import keystore
from wallet import Wallet, Imported_Wallet, Standard_Wallet, Multisig_Wallet, WalletStorage, wallet_types
from i18n import _
@ -85,6 +86,11 @@ class BaseWizard(object):
choices = [pair for pair in wallet_kinds if pair[0] in wallet_types]
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.on_wallet_type)
def load_2fa(self):
self.storage.put('wallet_type', '2fa')
self.storage.put('use_trustedcoin', True)
self.plugin = self.plugins.load_plugin('trustedcoin')
def on_wallet_type(self, choice):
self.wallet_type = choice
if choice == 'standard':
@ -92,9 +98,7 @@ class BaseWizard(object):
elif choice == 'multisig':
action = 'choose_multisig'
elif choice == '2fa':
self.storage.put('wallet_type', '2fa')
self.storage.put('use_trustedcoin', True)
self.plugin = self.plugins.load_plugin('trustedcoin')
self.load_2fa()
action = self.storage.get_action()
elif choice == 'imported':
action = 'import_addresses'
@ -243,12 +247,7 @@ class BaseWizard(object):
k = hardware_keystore(d)
self.on_keystore(k)
def restore_from_seed(self):
self.opt_bip39 = True
self.restore_seed_dialog(run_next=self.on_restore_seed, test=keystore.is_seed)
def on_restore_seed(self, seed, is_bip39):
if keystore.is_new_seed(seed) or is_bip39:
def passphrase_dialog(self, run_next):
message = '\n'.join([
_('Your seed may be extended with a passphrase.'),
_('If that is the case, enter it here.'),
@ -257,17 +256,37 @@ class BaseWizard(object):
_('Note that this is NOT your encryption password.'),
_('If you do not know what this is, leave this field empty.'),
])
f = lambda x: self.on_restore_passphrase(seed, x, is_bip39)
self.line_dialog(title=_('Passphrase'), message=message, warning=warning, default='', test=lambda x:True, run_next=f)
self.line_dialog(title=_('Passphrase'), message=message, warning=warning, default='', test=lambda x:True, run_next=run_next)
def restore_from_seed(self):
if self.wallet_type == 'standard':
self.opt_bip39 = True
test = bitcoin.is_seed
else:
self.on_restore_passphrase(seed, '', False)
self.opt_bip39 = False
test = bitcoin.is_new_seed
self.restore_seed_dialog(run_next=self.on_restore_seed, test=test)
def on_restore_passphrase(self, seed, passphrase, is_bip39):
def on_restore_seed(self, seed, is_bip39):
if is_bip39:
f = lambda x: self.run('on_bip44', seed, passphrase, int(x))
self.account_id_dialog(f)
f = lambda x: self.on_restore_bip39(seed, x)
self.passphrase_dialog(run_next=f)
else:
seed_type = bitcoin.seed_type(seed)
if seed_type == 'standard':
f = lambda x: self.run('create_keystore', seed, x)
self.passphrase_dialog(run_next=f)
elif seed_type == 'old':
self.run('create_keystore', seed, passphrase)
elif seed_type == '2fa':
self.load_2fa()
self.run('on_restore_seed', seed)
else:
raise
def on_restore_bip39(self, seed, passphrase):
f = lambda x: self.run('on_bip44', seed, passphrase, int(x))
self.account_id_dialog(f)
def create_keystore(self, seed, passphrase):
k = keystore.from_seed(seed, passphrase)

13
lib/bitcoin.py

@ -173,16 +173,25 @@ def is_old_seed(seed):
uses_electrum_words = True
except Exception:
uses_electrum_words = False
try:
seed.decode('hex')
is_hex = (len(seed) == 32 or len(seed) == 64)
except Exception:
is_hex = False
return is_hex or (uses_electrum_words and (len(words) == 12 or len(words) == 24))
def seed_type(x):
if is_old_seed(x):
return 'old'
elif is_new_seed(x):
return 'standard'
elif is_new_seed(x, version.SEED_PREFIX_2FA):
return '2fa'
return ''
is_seed = lambda x: bool(seed_type(x))
# pywallet openssl private key implementation
def i2o_ECPublicKey(pubkey, compressed=False):

4
lib/keystore.py

@ -33,7 +33,7 @@ from bitcoin import pw_encode, pw_decode, bip32_root, bip32_private_derivation,
from bitcoin import public_key_from_private_key, public_key_to_bc_address
from bitcoin import *
from bitcoin import is_old_seed, is_new_seed
from bitcoin import is_old_seed, is_new_seed, is_seed
from util import PrintError, InvalidPassword
from mnemonic import Mnemonic
@ -665,7 +665,7 @@ def is_private_key_list(text):
parts = text.split()
return bool(parts) and all(bitcoin.is_private_key(x) for x in parts)
is_seed = lambda x: is_old_seed(x) or is_new_seed(x)
is_mpk = lambda x: is_old_mpk(x) or is_xpub(x)
is_private = lambda x: is_seed(x) or is_xprv(x) or is_private_key_list(x)
is_any_key = lambda x: is_old_mpk(x) or is_xprv(x) or is_xpub(x) or is_address_list(x) or is_private_key_list(x)

5
plugins/trustedcoin/qt.py

@ -252,7 +252,10 @@ class Plugin(TrustedCoinPlugin):
vbox.addWidget(qrw, 1)
msg = _('Then, enter your Google Authenticator code:')
else:
label = QLabel("This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration")
label = QLabel(
"This wallet is already registered with Trustedcoin. "
"To finalize wallet creation, please enter your Google Authenticator Code. "
"If you do not have this code, delete the wallet file and start a new registration")
label.setWordWrap(1)
vbox.addWidget(label)
msg = _('Google Authenticator code:')

16
plugins/trustedcoin/trustedcoin.py

@ -404,8 +404,24 @@ class TrustedCoinPlugin(BasePlugin):
wizard.restore_seed_dialog(run_next=f, test=self.is_valid_seed)
def on_restore_seed(self, wizard, seed):
wizard.set_icon(':icons/trustedcoin.png')
wizard.stack = []
title = _('Restore 2FA wallet')
msg = ' '.join([
'You are going to restore a wallet protected with two-factor authentication.',
'Do you want to keep using two-factor authentication with this wallet,',
'or do you want to disable it, and have two master private keys in your wallet?'
])
choices = [('keep', 'Keep'), ('disable', 'Disable')]
f = lambda x: self.on_choice(wizard, seed, x)
wizard.choice_dialog(choices=choices, message=msg, title=title, run_next=f)
def on_choice(self, wizard, seed, x):
if x == 'disable':
f = lambda pw: wizard.run('on_restore_pw', seed, pw)
wizard.request_password(run_next=f)
else:
self.create_keystore(wizard, seed, '')
def on_restore_pw(self, wizard, seed, password):
storage = wizard.storage

Loading…
Cancel
Save