kivy wizard: do not scan seed as qr code. separate screen for watching only wallets.
This commit is contained in:
parent
8c365fd681
commit
4e7f9c061b
|
@ -99,8 +99,8 @@ Builder.load_string('''
|
||||||
text_size: self.width, None
|
text_size: self.width, None
|
||||||
height: self.texture_size[1]
|
height: self.texture_size[1]
|
||||||
text:
|
text:
|
||||||
_("Wallet file not found")+"\\n\\n" +\
|
_("Creating a new wallet.")+" " +\
|
||||||
_("Do you want to create a new wallet ")+\
|
_("Do you want to create a wallet with a new seed")+\
|
||||||
_("or restore an existing one?")
|
_("or restore an existing one?")
|
||||||
Widget
|
Widget
|
||||||
size_hint: 1, 1
|
size_hint: 1, 1
|
||||||
|
@ -116,9 +116,13 @@ Builder.load_string('''
|
||||||
text: _('Create a new seed')
|
text: _('Create a new seed')
|
||||||
root: root
|
root: root
|
||||||
WizardButton:
|
WizardButton:
|
||||||
id: restore
|
id: restore_seed
|
||||||
text: _('I already have a seed')
|
text: _('I already have a seed')
|
||||||
root: root
|
root: root
|
||||||
|
WizardButton:
|
||||||
|
id: restore_xpub
|
||||||
|
text: _('Watching-only wallet')
|
||||||
|
root: root
|
||||||
|
|
||||||
|
|
||||||
<MButton@Button>:
|
<MButton@Button>:
|
||||||
|
@ -277,10 +281,65 @@ Builder.load_string('''
|
||||||
id: back
|
id: back
|
||||||
text: _('Back')
|
text: _('Back')
|
||||||
root: root
|
root: root
|
||||||
|
WizardButton:
|
||||||
|
id: next
|
||||||
|
text: _('Next')
|
||||||
|
root: root
|
||||||
|
disabled: True
|
||||||
|
|
||||||
|
|
||||||
|
<RestoreXpubDialog>
|
||||||
|
word: ''
|
||||||
|
Label:
|
||||||
|
color: root.text_color
|
||||||
|
size_hint: 1, None
|
||||||
|
text_size: self.width, None
|
||||||
|
height: self.texture_size[1]
|
||||||
|
text: "[b]MASTER PUBLIC KEY[/b]"
|
||||||
|
GridLayout
|
||||||
|
cols: 1
|
||||||
|
padding: 0, '12dp'
|
||||||
|
orientation: 'vertical'
|
||||||
|
spacing: '12dp'
|
||||||
|
size_hint: 1, None
|
||||||
|
height: self.minimum_height
|
||||||
|
SeedButton:
|
||||||
|
id: text_input_seed
|
||||||
|
text: ''
|
||||||
|
on_text: Clock.schedule_once(root.on_text)
|
||||||
|
SeedLabel:
|
||||||
|
text: root.message
|
||||||
|
|
||||||
|
GridLayout:
|
||||||
|
rows: 1
|
||||||
|
spacing: '12dp'
|
||||||
|
size_hint: 1, None
|
||||||
|
height: self.minimum_height
|
||||||
IconButton:
|
IconButton:
|
||||||
id: scan
|
id: scan
|
||||||
|
height: '48sp'
|
||||||
on_release: root.scan_seed()
|
on_release: root.scan_seed()
|
||||||
icon: 'atlas://gui/kivy/theming/light/camera'
|
icon: 'atlas://gui/kivy/theming/light/camera'
|
||||||
|
size_hint: 1, None
|
||||||
|
WizardButton:
|
||||||
|
text: _('Paste')
|
||||||
|
on_release: root.do_paste()
|
||||||
|
WizardButton:
|
||||||
|
text: _('Clear')
|
||||||
|
on_release: root.do_clear()
|
||||||
|
|
||||||
|
Widget:
|
||||||
|
size_hint: 1, 1
|
||||||
|
|
||||||
|
GridLayout:
|
||||||
|
rows: 1
|
||||||
|
spacing: '12dp'
|
||||||
|
size_hint: 1, None
|
||||||
|
height: self.minimum_height
|
||||||
|
WizardButton:
|
||||||
|
id: back
|
||||||
|
text: _('Back')
|
||||||
|
root: root
|
||||||
WizardButton:
|
WizardButton:
|
||||||
id: next
|
id: next
|
||||||
text: _('Next')
|
text: _('Next')
|
||||||
|
@ -397,7 +456,7 @@ class RestoreSeedDialog(WizardDialog):
|
||||||
self.mnemonic = Mnemonic('en')
|
self.mnemonic = Mnemonic('en')
|
||||||
|
|
||||||
def on_text(self, dt):
|
def on_text(self, dt):
|
||||||
self.ids.next.disabled = not bool(self._test(self.get_seed_text()))
|
self.ids.next.disabled = not bool(self._test(self.get_text()))
|
||||||
|
|
||||||
text = self.ids.text_input_seed.text
|
text = self.ids.text_input_seed.text
|
||||||
if not text:
|
if not text:
|
||||||
|
@ -432,14 +491,14 @@ class RestoreSeedDialog(WizardDialog):
|
||||||
c.disabled = not enable_space
|
c.disabled = not enable_space
|
||||||
|
|
||||||
def on_word(self, w):
|
def on_word(self, w):
|
||||||
text = self.get_seed_text()
|
text = self.get_text()
|
||||||
words = text.split(' ')
|
words = text.split(' ')
|
||||||
words[-1] = w
|
words[-1] = w
|
||||||
text = ' '.join(words)
|
text = ' '.join(words)
|
||||||
self.ids.text_input_seed.text = text + ' '
|
self.ids.text_input_seed.text = text + ' '
|
||||||
self.ids.suggestions.clear_widgets()
|
self.ids.suggestions.clear_widgets()
|
||||||
|
|
||||||
def get_seed_text(self):
|
def get_text(self):
|
||||||
ti = self.ids.text_input_seed
|
ti = self.ids.text_input_seed
|
||||||
text = unicode(ti.text).strip()
|
text = unicode(ti.text).strip()
|
||||||
text = ' '.join(text.split())
|
text = ' '.join(text.split())
|
||||||
|
@ -454,12 +513,6 @@ class RestoreSeedDialog(WizardDialog):
|
||||||
text += c
|
text += c
|
||||||
self.ids.text_input_seed.text = text
|
self.ids.text_input_seed.text = text
|
||||||
|
|
||||||
def scan_seed(self):
|
|
||||||
def on_complete(text):
|
|
||||||
self.ids.text_input_seed.text = text
|
|
||||||
app = App.get_running_app()
|
|
||||||
app.scan_qr(on_complete)
|
|
||||||
|
|
||||||
def on_parent(self, instance, value):
|
def on_parent(self, instance, value):
|
||||||
if value:
|
if value:
|
||||||
tis = self.ids.text_input_seed
|
tis = self.ids.text_input_seed
|
||||||
|
@ -487,10 +540,29 @@ class RestoreSeedDialog(WizardDialog):
|
||||||
tis._keyboard.unbind(on_key_down=self.on_key_down)
|
tis._keyboard.unbind(on_key_down=self.on_key_down)
|
||||||
tis.focus = False
|
tis.focus = False
|
||||||
|
|
||||||
def close(self):
|
class RestoreXpubDialog(WizardDialog):
|
||||||
#self._remove_keyboard()
|
|
||||||
app = App.get_running_app()
|
message = StringProperty('')
|
||||||
#if self._back in app.navigation_higherarchy:
|
|
||||||
# app.navigation_higherarchy.pop()
|
def __init__(self, **kwargs):
|
||||||
# self._back = None
|
super(RestoreXpubDialog, self).__init__(**kwargs)
|
||||||
super(RestoreSeedDialog, self).close()
|
self._test = kwargs['test']
|
||||||
|
self.app = App.get_running_app()
|
||||||
|
|
||||||
|
def get_text(self):
|
||||||
|
ti = self.ids.text_input_seed
|
||||||
|
return unicode(ti.text).strip()
|
||||||
|
|
||||||
|
def on_text(self, dt):
|
||||||
|
self.ids.next.disabled = not bool(self._test(self.get_text()))
|
||||||
|
|
||||||
|
def scan_seed(self):
|
||||||
|
def on_complete(text):
|
||||||
|
self.ids.text_input_seed.text = text
|
||||||
|
self.app.scan_qr(on_complete)
|
||||||
|
|
||||||
|
def do_paste(self):
|
||||||
|
self.ids.text_input_seed.text = unicode(self.app._clipboard.paste())
|
||||||
|
|
||||||
|
def do_clear(self):
|
||||||
|
self.ids.text_input_seed.text = ''
|
||||||
|
|
|
@ -12,7 +12,7 @@ import threading
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from create_restore import CreateRestoreDialog, ShowSeedDialog, RestoreSeedDialog
|
from create_restore import CreateRestoreDialog, ShowSeedDialog, RestoreSeedDialog, RestoreXpubDialog
|
||||||
from password_dialog import PasswordDialog
|
from password_dialog import PasswordDialog
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ class InstallWizard(Widget):
|
||||||
self.network = network
|
self.network = network
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.wallet = Wallet(self.storage)
|
self.wallet = Wallet(self.storage)
|
||||||
self.is_restore = False
|
|
||||||
|
|
||||||
def waiting_dialog(self, task, msg, on_complete=None):
|
def waiting_dialog(self, task, msg, on_complete=None):
|
||||||
'''Perform a blocking task in the background by running the passed
|
'''Perform a blocking task in the background by running the passed
|
||||||
|
@ -79,27 +78,36 @@ class InstallWizard(Widget):
|
||||||
action = dialog.action
|
action = dialog.action
|
||||||
if button == dialog.ids.create:
|
if button == dialog.ids.create:
|
||||||
self.run('create')
|
self.run('create')
|
||||||
elif button == dialog.ids.restore:
|
elif button == dialog.ids.restore_seed:
|
||||||
self.run('restore')
|
self.run('restore_seed')
|
||||||
|
elif button == dialog.ids.restore_xpub:
|
||||||
|
self.run('restore_xpub')
|
||||||
else:
|
else:
|
||||||
self.dispatch('on_wizard_complete', None)
|
self.dispatch('on_wizard_complete', None)
|
||||||
CreateRestoreDialog(on_release=on_release).open()
|
CreateRestoreDialog(on_release=on_release).open()
|
||||||
|
|
||||||
def restore(self):
|
def restore_seed(self):
|
||||||
self.is_restore = True
|
|
||||||
def on_seed(_dlg, btn):
|
def on_seed(_dlg, btn):
|
||||||
_dlg.close()
|
_dlg.close()
|
||||||
if btn is _dlg.ids.back:
|
if btn is _dlg.ids.back:
|
||||||
self.run('new')
|
self.run('new')
|
||||||
return
|
return
|
||||||
text = _dlg.get_seed_text()
|
text = _dlg.get_text()
|
||||||
if Wallet.should_encrypt(text):
|
self.run('enter_pin', (text,))
|
||||||
self.run('enter_pin', (text,))
|
msg = _('Please type your seed phrase using the virtual keyboard.')
|
||||||
else:
|
RestoreSeedDialog(test=Wallet.is_seed, message=msg, on_release=on_seed).open()
|
||||||
self.run('add_seed', (text, None))
|
|
||||||
# fixme: sync
|
def restore_xpub(self):
|
||||||
msg = _('You may use the camera to scan your seed. To create a watching-only wallet, scan your master public key.')
|
def on_xpub(_dlg, btn):
|
||||||
RestoreSeedDialog(test=Wallet.is_any, message=msg, on_release=on_seed).open()
|
_dlg.close()
|
||||||
|
if btn is _dlg.ids.back:
|
||||||
|
self.run('new')
|
||||||
|
return
|
||||||
|
text = _dlg.get_text()
|
||||||
|
self.run('add_seed', (text, None))
|
||||||
|
|
||||||
|
msg = _('To create a watching-only wallet, paste your master public key, or scan it using the camera button.')
|
||||||
|
RestoreXpubDialog(test=Wallet.is_xpub, message=msg, on_release=on_xpub).open()
|
||||||
|
|
||||||
def add_seed(self, text, password):
|
def add_seed(self, text, password):
|
||||||
def task():
|
def task():
|
||||||
|
@ -114,7 +122,6 @@ class InstallWizard(Widget):
|
||||||
self.waiting_dialog(task, msg, self.terminate)
|
self.waiting_dialog(task, msg, self.terminate)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self.is_restore = False
|
|
||||||
seed = self.wallet.make_seed()
|
seed = self.wallet.make_seed()
|
||||||
msg = _("If you forget your PIN or lose your device, your seed phrase will be the "
|
msg = _("If you forget your PIN or lose your device, your seed phrase will be the "
|
||||||
"only way to recover your funds.")
|
"only way to recover your funds.")
|
||||||
|
@ -156,11 +163,6 @@ class InstallWizard(Widget):
|
||||||
|
|
||||||
def terminate(self):
|
def terminate(self):
|
||||||
self.wallet.start_threads(self.network)
|
self.wallet.start_threads(self.network)
|
||||||
#if self.is_restore:
|
|
||||||
# if self.wallet.is_found():
|
|
||||||
# app.show_info(_("Recovery successful"), duration=.5)
|
|
||||||
# else:
|
|
||||||
# app.show_info(_("No transactions found for this seed"), duration=.5)
|
|
||||||
self.dispatch('on_wizard_complete', self.wallet)
|
self.dispatch('on_wizard_complete', self.wallet)
|
||||||
|
|
||||||
def on_wizard_complete(self, wallet):
|
def on_wizard_complete(self, wallet):
|
||||||
|
|
Loading…
Reference in New Issue