URI: 
       twizard: show passphrase in the same window as the seed - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 99a3250b3ff94075f32c8fa9c57ca321b4ba48c3
   DIR parent 5e90b3a42d53c55515b7e62bf8568aeb35582e90
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Mon, 29 Aug 2016 15:33:16 +0200
       
       wizard: show passphrase in the same window as the seed
       
       Diffstat:
         M gui/kivy/uix/dialogs/installwizard… |      54 +++++++++++++++++++++++++------
         M gui/qt/installwizard.py             |      71 +++++++++----------------------
         M gui/qt/main_window.py               |       6 ++++--
         M gui/qt/password_dialog.py           |      57 +++++++++++++------------------
         M gui/qt/seed_dialog.py               |     139 ++++++++++++++++++++++++-------
         M gui/qt/util.py                      |       6 ++++++
         M lib/base_wizard.py                  |      18 +++++++++---------
         M lib/keystore.py                     |       2 +-
       
       8 files changed, 218 insertions(+), 135 deletions(-)
       ---
   DIR diff --git a/gui/kivy/uix/dialogs/installwizard.py b/gui/kivy/uix/dialogs/installwizard.py
       t@@ -385,7 +385,6 @@ Builder.load_string('''
        
        
        <ShowSeedDialog>
       -    message: ''
            spacing: '12dp'
            value: 'next'
            BigLabel:
       t@@ -398,10 +397,29 @@ Builder.load_string('''
                height: self.minimum_height
                orientation: 'vertical'
                spacing: '12dp'
       -        SeedButton:
       -            text: root.seed_text
                SeedLabel:
                    text: root.message
       +        SeedButton:
       +            text: root.seed_text
       +
       +<PassphraseDialog>
       +
       +    BigLabel:
       +        text: "SEED PASSPHRASE"
       +    SeedLabel:
       +        text: root.passphrase_message
       +    GridLayout:
       +        cols: 2
       +        size_hint: 1, None
       +        height: '27dp'
       +        BigLabel:
       +            text: _('Passphrase')
       +        TextInput:
       +            id: passphrase_input
       +            multiline: False
       +            size_hint: 1, None
       +            height: '27dp'
       +
        ''')
        
        
       t@@ -492,11 +510,27 @@ class WizardChoiceDialog(WizardDialog):
            def get_params(self, button):
                return (button.action,)
        
       -class ShowSeedDialog(WizardDialog):
        
       +
       +class PassphraseDialog(WizardDialog):
       +    passphrase = StringProperty('')
       +    passphrase_message = ' '.join([
       +        _("You may extend your seed with a derivation passphrase."),
       +        '\n\n',
       +        _("Note: This is NOT your encryption password."),
       +        _("Leave this field empty if you are not sure about what it is."),
       +    ])
       +
       +    def __init__(self, wizard, **kwargs):
       +        WizardDialog.__init__(self, wizard, **kwargs)
       +        self.ids.next.disabled = False
       +
       +    def get_params(self, b):
       +        return (self.ids.passphrase_input.text,)
       +
       +class ShowSeedDialog(WizardDialog):
            seed_text = StringProperty('')
       -    message = _("If you forget your PIN or lose your device, your seed phrase will be the "
       -                "only way to recover your funds.")
       +    message = _("If you forget your PIN or lose your device, your seed phrase will be the only way to recover your funds.")
        
            def on_parent(self, instance, value):
                if value:
       t@@ -504,7 +538,7 @@ class ShowSeedDialog(WizardDialog):
                    self._back = _back = partial(self.ids.back.dispatch, 'on_release')
        
            def get_params(self, b):
       -        return(self.seed_text,)
       +        return(self.seed_text, '')
        
        
        class WordButton(Button):
       t@@ -518,7 +552,7 @@ class RestoreSeedDialog(WizardDialog):
        
            def __init__(self, wizard, **kwargs):
                super(RestoreSeedDialog, self).__init__(wizard, **kwargs)
       -        self._test = kwargs['is_valid']
       +        self._test = kwargs['is_seed']
                from electrum.mnemonic import Mnemonic
                from electrum.old_mnemonic import words as old_wordlist
                self.words = set(Mnemonic('en').wordlist).union(set(old_wordlist))
       t@@ -581,7 +615,7 @@ class RestoreSeedDialog(WizardDialog):
                return text
        
            def get_params(self, b):
       -        return (self.get_text(), False, False)
       +        return (self.get_text(), '', False)
        
            def update_text(self, c):
                c = c.lower()
       t@@ -671,7 +705,6 @@ class AddXpubDialog(WizardDialog):
        
        
        
       -
        class InstallWizard(BaseWizard, Widget):
            '''
            events::
       t@@ -711,6 +744,7 @@ class InstallWizard(BaseWizard, Widget):
            def choice_dialog(self, **kwargs): WizardChoiceDialog(self, **kwargs).open()
            def multisig_dialog(self, **kwargs): WizardMultisigDialog(self, **kwargs).open()
            def show_seed_dialog(self, **kwargs): ShowSeedDialog(self, **kwargs).open()
       +    def passphrase_dialog(self, **kwargs): PassphraseDialog(self, **kwargs).open()
        
            def confirm_seed_dialog(self, **kwargs):
                kwargs['title'] = _('Confirm Seed')
   DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
       t@@ -12,10 +12,10 @@ from electrum.util import UserCancelled
        from electrum.base_wizard import BaseWizard
        from electrum.i18n import _
        
       -from seed_dialog import SeedDisplayLayout, SeedWarningLayout, SeedInputLayout
       +from seed_dialog import SeedDisplayLayout, CreateSeedLayout, SeedInputLayout, TextInputLayout
        from network_dialog import NetworkChoiceLayout
        from util import *
       -from password_dialog import PasswordLayout, PW_NEW, PW_PASSPHRASE
       +from password_dialog import PasswordLayout, PW_NEW
        
        
        class GoBack(Exception):
       t@@ -28,15 +28,11 @@ MSG_ENTER_SEED_OR_MPK = _("Please enter a seed phrase or a master key (xpub or x
        MSG_COSIGNER = _("Please enter the master public key of cosigner #%d:")
        MSG_ENTER_PASSWORD = _("Choose a password to encrypt your wallet keys.") + '\n'\
                             + _("Leave this field empty if you want to disable encryption.")
       -MSG_PASSPHRASE = \
       +MSG_RESTORE_PASSPHRASE = \
            _("Please enter your seed derivation passphrase. "
              "Note: this is NOT your encryption password. "
              "Leave this field empty if you did not use one or are unsure.")
        
       -def clean_text(seed_e):
       -    text = unicode(seed_e.toPlainText()).strip()
       -    text = ' '.join(text.split())
       -    return text
        
        class CosignWidget(QWidget):
            size = 120
       t@@ -248,31 +244,18 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
            def remove_from_recently_open(self, filename):
                self.config.remove_from_recently_open(filename)
        
       -    def text_input_layout(self, title, message, is_valid):
       -        slayout = SeedInputLayout(title=message)
       -        slayout.is_valid = is_valid
       -        slayout.sanitized_text = lambda: clean_text(slayout.seed_edit())
       -        slayout.set_enabled = lambda: self.next_button.setEnabled(slayout.is_valid(slayout.sanitized_text()))
       -        slayout.seed_edit().textChanged.connect(slayout.set_enabled)
       -        return slayout
       -
            def text_input(self, title, message, is_valid):
       -        slayout = self.text_input_layout(title, message, is_valid)
       +        slayout = TextInputLayout(self, message, is_valid)
                self.set_main_layout(slayout.layout(), title, next_enabled=False)
       -        seed = slayout.sanitized_text()
       -        return seed
       +        return slayout.get_text()
        
       -    def seed_input(self, title, message, is_valid):
       -        slayout = self.text_input_layout(title, message, is_valid)
       +    def seed_input(self, title, message, is_seed, is_passphrase):
       +        slayout = SeedInputLayout(self, message, is_seed, is_passphrase)
                vbox = QVBoxLayout()
                vbox.addLayout(slayout.layout())
       -        if self.opt_ext or self.opt_bip39:
       -            vbox.addStretch(1)
       -            vbox.addWidget(QLabel(_('Options')+ ':'))
       -        if self.opt_ext:
       -            cb_ext = QCheckBox(_('Extend this seed with a passphrase'))
       -            vbox.addWidget(cb_ext)
                if self.opt_bip39:
       +            vbox.addStretch(1)
       +            vbox.addWidget(QLabel(_('Options') + ':'))
                    def f(b):
                        slayout.is_valid = (lambda x: bool(x)) if b else is_valid
                        slayout.set_enabled()
       t@@ -280,10 +263,10 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                    cb_bip39.toggled.connect(f)
                    vbox.addWidget(cb_bip39)
                self.set_main_layout(vbox, title, next_enabled=False)
       -        seed = slayout.sanitized_text()
       -        is_ext = cb_ext.isChecked() if self.opt_ext else False
       +        seed = slayout.get_seed()
       +        passphrase = slayout.get_passphrase()
                is_bip39 = cb_bip39.isChecked() if self.opt_bip39 else False
       -        return seed, is_ext, is_bip39
       +        return seed, passphrase, is_bip39
        
            @wizard_dialog
            def restore_keys_dialog(self, title, message, is_valid, run_next):
       t@@ -299,13 +282,14 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                return self.text_input(title, message, is_valid)
        
            @wizard_dialog
       -    def restore_seed_dialog(self, run_next, is_valid):
       +    def restore_seed_dialog(self, run_next, is_seed):
                title = _('Enter Seed')
                message = _('Please enter your seed phrase in order to restore your wallet.')
       -        return self.seed_input(title, message, is_valid)
       +        is_passphrase = lambda x: True
       +        return self.seed_input(title, message, is_seed, is_passphrase)
        
            @wizard_dialog
       -    def confirm_seed_dialog(self, run_next, is_valid):
       +    def confirm_seed_dialog(self, run_next, is_seed, is_passphrase):
                self.app.clipboard().clear()
                title = _('Confirm Seed')
                message = ' '.join([
       t@@ -313,13 +297,13 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                    _('If you lose your seed, your money will be permanently lost.'),
                    _('To make sure that you have properly saved your seed, please retype it here.')
                ])
       -        return self.seed_input(title, message, is_valid)
       +        return self.seed_input(title, message, is_seed, is_passphrase)
        
            @wizard_dialog
            def show_seed_dialog(self, run_next, seed_text):
       -        slayout = SeedWarningLayout(seed_text)
       +        slayout = CreateSeedLayout(seed_text)
                self.set_main_layout(slayout.layout())
       -        return seed_text
       +        return seed_text, slayout.passphrase()
        
            def pw_layout(self, msg, kind):
                playout = PasswordLayout(None, msg, kind, self.next_button)
       t@@ -327,16 +311,6 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                return playout.new_password()
        
            @wizard_dialog
       -    def request_passphrase(self, run_next):
       -        """When restoring a wallet, request the passphrase that was used for
       -        the wallet on the given device and confirm it.  Should return
       -        a unicode string."""
       -        phrase = self.pw_layout(MSG_PASSPHRASE, PW_PASSPHRASE)
       -        if phrase is None:
       -            raise UserCancelled
       -        return phrase
       -
       -    @wizard_dialog
            def request_password(self, run_next):
                """Request the user enter a new password and confirm it.  Return
                the password or None for no password."""
       t@@ -405,13 +379,6 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                self.set_main_layout(vbox, '')
                return clayout.selected_index()
        
       -    def get_passphrase(self, msg, confirm):
       -        phrase = self.pw_layout(msg, PW_PASSPHRASE)
       -        if phrase is None:
       -            raise UserCancelled
       -        return phrase
       -
       -
            @wizard_dialog
            def account_id_dialog(self, run_next):
                message = '\n'.join([
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -1696,13 +1696,15 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
                if not self.wallet.has_seed():
                    self.show_message(_('This wallet has no seed'))
                    return
       +        keystore = self.wallet.get_keystore()
                try:
       -            mnemonic = self.wallet.get_mnemonic(password)
       +            mnemonic = keystore.get_mnemonic(password)
       +            passphrase = keystore.get_passphrase(password)
                except BaseException as e:
                    self.show_error(str(e))
                    return
                from seed_dialog import SeedDialog
       -        d = SeedDialog(self, mnemonic)
       +        d = SeedDialog(self, mnemonic, passphrase)
                d.exec_()
        
        
   DIR diff --git a/gui/qt/password_dialog.py b/gui/qt/password_dialog.py
       t@@ -47,12 +47,12 @@ def check_password_strength(password):
            return password_strength[min(3, int(score))]
        
        
       -PW_NEW, PW_CHANGE, PW_PASSPHRASE = range(0, 3)
       +PW_NEW, PW_CHANGE = range(0, 2)
        
        
        class PasswordLayout(object):
        
       -    titles = [_("Enter Password"), _("Change Password"), _("Enter Passphrase")]
       +    titles = [_("Enter Password"), _("Change Password")]
        
            def __init__(self, wallet, msg, kind, OK_button):
                self.wallet = wallet
       t@@ -60,8 +60,8 @@ class PasswordLayout(object):
                self.pw = QLineEdit()
                self.pw.setEchoMode(2)
                self.new_pw = QLineEdit()
       -        self.new_pw.setEchoMode(2)
                self.conf_pw = QLineEdit()
       +        self.new_pw.setEchoMode(2)
                self.conf_pw.setEchoMode(2)
                self.kind = kind
                self.OK_button = OK_button
       t@@ -76,31 +76,24 @@ class PasswordLayout(object):
                grid.setColumnMinimumWidth(1, 100)
                grid.setColumnStretch(1,1)
        
       -        if kind == PW_PASSPHRASE:
       -            vbox.addWidget(label)
       -            msgs = [_('Passphrase:'), _('Confirm Passphrase:')]
       +        logo_grid = QGridLayout()
       +        logo_grid.setSpacing(8)
       +        logo_grid.setColumnMinimumWidth(0, 70)
       +        logo_grid.setColumnStretch(1,1)
       +        logo = QLabel()
       +        logo.setAlignment(Qt.AlignCenter)
       +        logo_grid.addWidget(logo,  0, 0)
       +        logo_grid.addWidget(label, 0, 1, 1, 2)
       +        vbox.addLayout(logo_grid)
       +        m1 = _('New Password:') if kind == PW_NEW else _('Password:')
       +        msgs = [m1, _('Confirm Password:')]
       +        if wallet and wallet.has_password():
       +            grid.addWidget(QLabel(_('Current Password:')), 0, 0)
       +            grid.addWidget(self.pw, 0, 1)
       +            lockfile = ":icons/lock.png"
                else:
       -            logo_grid = QGridLayout()
       -            logo_grid.setSpacing(8)
       -            logo_grid.setColumnMinimumWidth(0, 70)
       -            logo_grid.setColumnStretch(1,1)
       -
       -            logo = QLabel()
       -            logo.setAlignment(Qt.AlignCenter)
       -
       -            logo_grid.addWidget(logo,  0, 0)
       -            logo_grid.addWidget(label, 0, 1, 1, 2)
       -            vbox.addLayout(logo_grid)
       -
       -            m1 = _('New Password:') if kind == PW_NEW else _('Password:')
       -            msgs = [m1, _('Confirm Password:')]
       -            if wallet and wallet.has_password():
       -                grid.addWidget(QLabel(_('Current Password:')), 0, 0)
       -                grid.addWidget(self.pw, 0, 1)
       -                lockfile = ":icons/lock.png"
       -            else:
       -                lockfile = ":icons/unlock.png"
       -            logo.setPixmap(QPixmap(lockfile).scaledToWidth(36))
       +            lockfile = ":icons/unlock.png"
       +        logo.setPixmap(QPixmap(lockfile).scaledToWidth(36))
        
                grid.addWidget(QLabel(msgs[0]), 1, 0)
                grid.addWidget(self.new_pw, 1, 1)
       t@@ -110,10 +103,9 @@ class PasswordLayout(object):
                vbox.addLayout(grid)
        
                # Password Strength Label
       -        if kind != PW_PASSPHRASE:
       -            self.pw_strength = QLabel()
       -            grid.addWidget(self.pw_strength, 3, 0, 1, 2)
       -            self.new_pw.textChanged.connect(self.pw_changed)
       +        self.pw_strength = QLabel()
       +        grid.addWidget(self.pw_strength, 3, 0, 1, 2)
       +        self.new_pw.textChanged.connect(self.pw_changed)
        
                def enable_OK():
                    OK_button.setEnabled(self.new_pw.text() == self.conf_pw.text())
       t@@ -147,8 +139,7 @@ class PasswordLayout(object):
        
            def new_password(self):
                pw = unicode(self.new_pw.text())
       -        # Empty passphrases are fine and returned empty.
       -        if pw == "" and self.kind != PW_PASSPHRASE:
       +        if pw == "":
                    pw = None
                return pw
        
   DIR diff --git a/gui/qt/seed_dialog.py b/gui/qt/seed_dialog.py
       t@@ -38,13 +38,6 @@ def icon_filename(sid):
            else:
                return ":icons/seed.png"
        
       -class SeedDialog(WindowModalDialog):
       -    def __init__(self, parent, seed):
       -        WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
       -        self.setMinimumWidth(400)
       -        vbox = QVBoxLayout(self)
       -        vbox.addLayout(SeedWarningLayout(seed).layout())
       -        vbox.addLayout(Buttons(CloseButton(self)))
        
        class SeedLayoutBase(object):
            def _seed_layout(self, seed=None, title=None, sid=None):
       t@@ -75,34 +68,124 @@ class SeedLayoutBase(object):
                return self.seed_e
        
        
       -class SeedInputLayout(SeedLayoutBase):
       -    def __init__(self, title=None, sid=None):
       -        self.layout_ = self._seed_layout(title=title, sid=sid)
       -
        
        class SeedDisplayLayout(SeedLayoutBase):
            def __init__(self, seed, title=None, sid=None):
                self.layout_ = self._seed_layout(seed=seed, title=title, sid=sid)
        
        
       -class SeedWarningLayout(SeedLayoutBase):
       -    def __init__(self, seed, title=None):
       -        if title is None:
       -            title =  _("Your wallet generation seed is:")
       -        msg = ''.join([
       -            "<p>",
       -            _("Please save these %d words on paper (order is important). "),
       -            _("This seed will allow you to recover your wallet in case "
       -              "of computer failure."),
       -            "</p>",
       -            "<b>" + _("WARNING") + ":</b> ",
       -            "<ul>",
       -            "<li>" + _("Never disclose your seed.") + "</li>",
       -            "<li>" + _("Never type it on a website.") + "</li>",
       -            "<li>" + _("Do not send your seed to a printer.") + "</li>",
       -            "</ul>"
       -        ]) % len(seed.split())
       +
       +def seed_warning_msg(seed):
       +    return ''.join([
       +        "<p>",
       +        _("Please save these %d words on paper (order is important). "),
       +        _("This seed will allow you to recover your wallet in case "
       +          "of computer failure."),
       +        "</p>",
       +        "<b>" + _("WARNING") + ":</b> ",
       +        "<ul>",
       +        "<li>" + _("Never disclose your seed.") + "</li>",
       +        "<li>" + _("Never type it on a website.") + "</li>",
       +        "<li>" + _("Do not send your seed to a printer.") + "</li>",
       +        "</ul>"
       +    ]) % len(seed.split())
       +
       +
       +class CreateSeedLayout(SeedLayoutBase):
       +
       +    def __init__(self, seed):
       +        title =  _("Your wallet generation seed is:")
       +        tooltip = '\n'.join([
       +            _('You may extend your seed with a passphrase.'),
       +            _('Note tha this is NOT your encryption password.'),
       +            _('If you do not know what it is, leave it empty.'),
       +        ])
                vbox = QVBoxLayout()
                vbox.addLayout(self._seed_layout(seed=seed, title=title))
       +        self.passphrase_e = QLineEdit()
       +        self.passphrase_e.setToolTip(tooltip)
       +        hbox = QHBoxLayout()
       +        hbox.addStretch()
       +        label = QLabel(_('Passphrase') + ':')
       +        label.setToolTip(tooltip)
       +        hbox.addWidget(label)
       +        hbox.addWidget(self.passphrase_e)
       +        vbox.addLayout(hbox)
       +        msg = seed_warning_msg(seed)
                vbox.addWidget(WWLabel(msg))
                self.layout_ = vbox
       +
       +    def passphrase(self):
       +        return unicode(self.passphrase_e.text()).strip()
       +
       +
       +class TextInputLayout(SeedLayoutBase):
       +
       +    def __init__(self, parent, title, is_valid):
       +        self.is_valid = is_valid
       +        self.parent = parent
       +        self.layout_ = self._seed_layout(title=title)
       +        self.seed_e.textChanged.connect(self.on_edit)
       +
       +    def get_text(self):
       +        return clean_text(self.seed_edit())
       +
       +    def on_edit(self):
       +        self.parent.next_button.setEnabled(self.is_valid(self.get_text()))
       +
       +
       +class SeedInputLayout(SeedLayoutBase):
       +
       +    def __init__(self, parent, title, is_seed, is_passphrase):
       +        vbox = QVBoxLayout()
       +        vbox.addLayout(self._seed_layout(title=title))
       +        self.passphrase_e = QLineEdit()
       +        hbox = QHBoxLayout()
       +        hbox.addStretch()
       +        hbox.addWidget(QLabel(_('Passphrase') + ':'))
       +        hbox.addWidget(self.passphrase_e)
       +        vbox.addLayout(hbox)
       +        self.layout_ = vbox
       +        self.parent = parent
       +        self.is_seed = is_seed
       +        self.is_passphrase = is_passphrase
       +        self.seed_e.textChanged.connect(self.on_edit)
       +        self.passphrase_e.textChanged.connect(self.on_edit)
       +
       +    def get_passphrase(self):
       +        return unicode(self.passphrase_e.text()).strip()
       +
       +    def get_seed(self):
       +        return clean_text(self.seed_edit())
       +
       +    def on_edit(self):
       +        self.parent.next_button.setEnabled(self.is_seed(self.get_seed()) and self.is_passphrase(self.get_passphrase()))
       +
       +
       +
       +class ShowSeedLayout(SeedLayoutBase):
       +
       +    def __init__(self, seed, passphrase):
       +        title =  _("Your wallet generation seed is:")
       +        vbox = QVBoxLayout()
       +        vbox.addLayout(self._seed_layout(seed=seed, title=title))
       +        if passphrase:
       +            hbox = QHBoxLayout()
       +            passphrase_e = QLineEdit()
       +            passphrase_e.setText(passphrase)
       +            passphrase_e.setReadOnly(True)
       +            hbox.addWidget(QLabel('Your seed passphrase is'))
       +            hbox.addWidget(passphrase_e)
       +            vbox.addLayout(hbox)
       +        msg = seed_warning_msg(seed)
       +        vbox.addWidget(WWLabel(msg))
       +        self.layout_ = vbox
       +
       +
       +class SeedDialog(WindowModalDialog):
       +    def __init__(self, parent, seed, passphrase):
       +        WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
       +        self.setMinimumWidth(400)
       +        vbox = QVBoxLayout(self)
       +        vbox.addLayout(ShowSeedLayout(seed, passphrase).layout())
       +        vbox.addLayout(Buttons(CloseButton(self)))
   DIR diff --git a/gui/qt/util.py b/gui/qt/util.py
       t@@ -49,6 +49,12 @@ expiration_values = [
        ]
        
        
       +def clean_text(seed_e):
       +    text = unicode(seed_e.toPlainText()).strip()
       +    text = ' '.join(text.split())
       +    return text
       +
       +
        class Timer(QThread):
            stopped = False
        
   DIR diff --git a/lib/base_wizard.py b/lib/base_wizard.py
       t@@ -40,6 +40,7 @@ class BaseWizard(object):
                self.stack = []
                self.plugin = None
                self.keystores = []
       +        self.is_kivy = config.get('gui') == 'kivy'
        
            def run(self, *args):
                action = args[0]
       t@@ -229,15 +230,15 @@ class BaseWizard(object):
            def restore_from_seed(self):
                self.opt_bip39 = True
                self.opt_ext = True
       -        self.restore_seed_dialog(run_next=self.on_seed, is_valid=keystore.is_seed)
       +        self.restore_seed_dialog(run_next=self.on_seed, is_seed=keystore.is_seed)
        
       -    def on_seed(self, seed, add_passphrase, is_bip39):
       +    def on_seed(self, seed, passphrase, is_bip39):
                self.is_bip39 = is_bip39
       -        f = lambda x: self.run('create_keystore', seed, x)
       -        if add_passphrase:
       -            self.request_passphrase(run_next=f)
       +        if self.is_kivy:
       +            f = lambda x: self.run('create_keystore', seed, x)
       +            self.passphrase_dialog(run_next=f)
                else:
       -            f('')
       +            self.run('create_keystore', seed, passphrase)
        
            def create_keystore(self, seed, passphrase):
                if self.is_bip39:
       t@@ -248,7 +249,6 @@ class BaseWizard(object):
                    self.on_keystore(k)
        
            def on_bip44(self, seed, passphrase, account_id):
       -        import keystore
                k = keystore.BIP32_KeyStore({})
                bip32_seed = keystore.bip39_to_seed(seed, passphrase)
                derivation = "m/44'/0'/%d'"%account_id
       t@@ -311,8 +311,8 @@ class BaseWizard(object):
                self.opt_ext = True
                self.show_seed_dialog(run_next=self.confirm_seed, seed_text=seed)
        
       -    def confirm_seed(self, seed):
       -        self.confirm_seed_dialog(run_next=self.on_seed, is_valid=lambda x: x==seed)
       +    def confirm_seed(self, seed, passphrase):
       +        self.confirm_seed_dialog(run_next=self.on_seed, is_seed = lambda x: x==seed, is_passphrase=lambda x: x==passphrase)
        
            def create_addresses(self):
                def task():
   DIR diff --git a/lib/keystore.py b/lib/keystore.py
       t@@ -209,7 +209,7 @@ class Deterministic_KeyStore(Software_KeyStore):
                return pw_decode(self.seed, password).encode('utf8')
        
            def get_passphrase(self, password):
       -        return pw_decode(self.passphrase, password).encode('utf8')
       +        return pw_decode(self.passphrase, password).encode('utf8') if self.passphrase else ''