|
|
|
@ -20,6 +20,13 @@ app = App.get_running_app() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class InstallWizard(Widget): |
|
|
|
class InstallWizard(Widget): |
|
|
|
|
|
|
|
'''Instalation Wizzard. Responsible for instantiating the |
|
|
|
|
|
|
|
creation/restoration of wallets. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
events:: |
|
|
|
|
|
|
|
`on_wizard_complete` Fired when the wizard is done creating/ restoring |
|
|
|
|
|
|
|
wallet/s. |
|
|
|
|
|
|
|
''' |
|
|
|
|
|
|
|
|
|
|
|
__events__ = ('on_wizard_complete', ) |
|
|
|
__events__ = ('on_wizard_complete', ) |
|
|
|
|
|
|
|
|
|
|
|
@ -33,13 +40,15 @@ class InstallWizard(Widget): |
|
|
|
msg= _("Electrum is generating your addresses," |
|
|
|
msg= _("Electrum is generating your addresses," |
|
|
|
" please wait."), |
|
|
|
" please wait."), |
|
|
|
on_complete=None): |
|
|
|
on_complete=None): |
|
|
|
|
|
|
|
'''Perform a blocking task in the background by running the passed |
|
|
|
|
|
|
|
method in a thread. |
|
|
|
|
|
|
|
''' |
|
|
|
|
|
|
|
|
|
|
|
def target(): |
|
|
|
def target(): |
|
|
|
# run your threaded function |
|
|
|
# run your threaded function |
|
|
|
task() |
|
|
|
task() |
|
|
|
# on completion hide message |
|
|
|
# on completion hide message |
|
|
|
Clock.schedule_once(lambda dt: |
|
|
|
Clock.schedule_once(lambda dt: app.info_bubble.hide()) |
|
|
|
app.show_info_bubble(text="Complete", arrow_pos=None)) |
|
|
|
|
|
|
|
# call completion routine |
|
|
|
# call completion routine |
|
|
|
if on_complete: |
|
|
|
if on_complete: |
|
|
|
Clock.schedule_once(lambda dt: on_complete()) |
|
|
|
Clock.schedule_once(lambda dt: on_complete()) |
|
|
|
@ -51,12 +60,14 @@ class InstallWizard(Widget): |
|
|
|
t.start() |
|
|
|
t.start() |
|
|
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
def run(self): |
|
|
|
|
|
|
|
'''Entry point of our Installation wizard |
|
|
|
|
|
|
|
''' |
|
|
|
CreateRestoreDialog(on_release=self.on_creatrestore_complete).open() |
|
|
|
CreateRestoreDialog(on_release=self.on_creatrestore_complete).open() |
|
|
|
|
|
|
|
|
|
|
|
def on_creatrestore_complete(self, dialog, button): |
|
|
|
def on_creatrestore_complete(self, dialog, button): |
|
|
|
if not button: |
|
|
|
if not button: |
|
|
|
self.dispatch('on_wizard_complete', None) |
|
|
|
return self.dispatch('on_wizard_complete', None) |
|
|
|
return |
|
|
|
|
|
|
|
wallet = Wallet(self.storage) |
|
|
|
wallet = Wallet(self.storage) |
|
|
|
gap = self.config.get('gap_limit', 5) |
|
|
|
gap = self.config.get('gap_limit', 5) |
|
|
|
if gap !=5: |
|
|
|
if gap !=5: |
|
|
|
@ -70,7 +81,7 @@ class InstallWizard(Widget): |
|
|
|
elif button == dialog.ids.restore: |
|
|
|
elif button == dialog.ids.restore: |
|
|
|
# restore |
|
|
|
# restore |
|
|
|
self.restore_seed_dialog(wallet) |
|
|
|
self.restore_seed_dialog(wallet) |
|
|
|
#elif button == dialog.ids.watching: |
|
|
|
#if button == dialog.ids.watching: |
|
|
|
#TODO: not available in the new design |
|
|
|
#TODO: not available in the new design |
|
|
|
# self.action = 'watching' |
|
|
|
# self.action = 'watching' |
|
|
|
else: |
|
|
|
else: |
|
|
|
@ -99,30 +110,15 @@ class InstallWizard(Widget): |
|
|
|
except Exception: |
|
|
|
except Exception: |
|
|
|
import traceback |
|
|
|
import traceback |
|
|
|
traceback.print_exc(file=sys.stdout) |
|
|
|
traceback.print_exc(file=sys.stdout) |
|
|
|
app.show_error(_('No account tied to this seedphrase'), exit=True) |
|
|
|
app.show_error(_('No account tied to this seedphrase'))#, exit=True) |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
_dlg.close() |
|
|
|
_dlg.close() |
|
|
|
self.change_password_dialog(wallet=wallet, mode='restore') |
|
|
|
self.change_password_dialog(wallet=wallet, mode='restore') |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
from pudb import set_trace; set_trace() |
|
|
|
|
|
|
|
wallet = self.wallet |
|
|
|
|
|
|
|
#is_restore = bool(_dlg.__class__ == RestoreSeedDialog) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Restore |
|
|
|
|
|
|
|
if len(seed) == 128: |
|
|
|
|
|
|
|
wallet.seed = '' |
|
|
|
|
|
|
|
wallet.init_sequence(str(seed)) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
wallet.seed = '' |
|
|
|
|
|
|
|
wallet.init_seed(str(seed)) |
|
|
|
|
|
|
|
wallet.save_seed() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return self.change_network_dialog() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def init_seed_dialog(self, wallet=None, instance=None, password=None, |
|
|
|
def init_seed_dialog(self, wallet=None, instance=None, password=None, |
|
|
|
wallet_name=None): |
|
|
|
wallet_name=None, mode='create'): |
|
|
|
# renamed from show_seed() |
|
|
|
# renamed from show_seed() |
|
|
|
'''Can be called directly (password is None) |
|
|
|
'''Can be called directly (password is None) |
|
|
|
or from a password-protected callback (password is not None)''' |
|
|
|
or from a password-protected callback (password is not None)''' |
|
|
|
@ -131,7 +127,7 @@ class InstallWizard(Widget): |
|
|
|
if instance == None: |
|
|
|
if instance == None: |
|
|
|
wallet.init_seed(None) |
|
|
|
wallet.init_seed(None) |
|
|
|
else: |
|
|
|
else: |
|
|
|
return MessageBoxError(message=_('No seed')).open() |
|
|
|
return app.show_error(_('No seed')) |
|
|
|
|
|
|
|
|
|
|
|
if password is None or not instance: |
|
|
|
if password is None or not instance: |
|
|
|
seed = wallet.get_mnemonic(None) |
|
|
|
seed = wallet.get_mnemonic(None) |
|
|
|
@ -139,7 +135,7 @@ class InstallWizard(Widget): |
|
|
|
try: |
|
|
|
try: |
|
|
|
seed = self.wallet.get_seed(password) |
|
|
|
seed = self.wallet.get_seed(password) |
|
|
|
except Exception: |
|
|
|
except Exception: |
|
|
|
return MessageBoxError(message=_('Incorrect Password')) |
|
|
|
return app.show_error(_('Incorrect Password')) |
|
|
|
|
|
|
|
|
|
|
|
brainwallet = seed |
|
|
|
brainwallet = seed |
|
|
|
|
|
|
|
|
|
|
|
@ -160,8 +156,10 @@ class InstallWizard(Widget): |
|
|
|
def on_ok_press(_dlg, _btn): |
|
|
|
def on_ok_press(_dlg, _btn): |
|
|
|
_dlg.close() |
|
|
|
_dlg.close() |
|
|
|
if _btn != _dlg.ids.confirm: |
|
|
|
if _btn != _dlg.ids.confirm: |
|
|
|
self.change_password_dialog(wallet) |
|
|
|
if not instance: |
|
|
|
|
|
|
|
self.change_password_dialog(wallet) |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
# confirm |
|
|
|
if instance is None: |
|
|
|
if instance is None: |
|
|
|
# in initial phase |
|
|
|
# in initial phase |
|
|
|
def create(password): |
|
|
|
def create(password): |
|
|
|
@ -173,21 +171,20 @@ class InstallWizard(Widget): |
|
|
|
Clock.schedule_once(lambda dt: |
|
|
|
Clock.schedule_once(lambda dt: |
|
|
|
app.show_error(err)) |
|
|
|
app.show_error(err)) |
|
|
|
wallet.synchronize() # generate first addresses offline |
|
|
|
wallet.synchronize() # generate first addresses offline |
|
|
|
self.waiting_dialog(partial(create, password), |
|
|
|
self.waiting_dialog( |
|
|
|
on_complete=self.load_network) |
|
|
|
partial(create, password), |
|
|
|
|
|
|
|
on_complete=partial(self.load_network, wallet, mode=mode)) |
|
|
|
|
|
|
|
|
|
|
|
from electrum_gui.kivy.dialog import InitSeedDialog |
|
|
|
from electrum_gui.kivy.dialog import InitSeedDialog |
|
|
|
InitSeedDialog(message=msg2, |
|
|
|
InitSeedDialog(message=msg2, |
|
|
|
seed_msg=brainwallet, |
|
|
|
seed_msg=brainwallet, seed=seed, on_release=on_ok_press).open() |
|
|
|
seed=seed, |
|
|
|
|
|
|
|
on_release=on_ok_press).open() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def change_password_dialog(self, wallet=None, instance=None, mode='create'): |
|
|
|
def change_password_dialog(self, wallet=None, instance=None, mode='create'): |
|
|
|
"""Can be called directly (instance is None) |
|
|
|
"""Can be called directly (instance is None) |
|
|
|
or from a callback (instance is not None)""" |
|
|
|
or from a callback (instance is not None)""" |
|
|
|
|
|
|
|
|
|
|
|
if instance and not wallet.seed: |
|
|
|
if instance and not wallet.seed: |
|
|
|
return MessageBoxExit(message=_('No seed !!')).open() |
|
|
|
return ShowError(_('No seed !!'), exit=True, modal=True) |
|
|
|
|
|
|
|
|
|
|
|
if instance is not None: |
|
|
|
if instance is not None: |
|
|
|
if wallet.use_encryption: |
|
|
|
if wallet.use_encryption: |
|
|
|
@ -210,9 +207,11 @@ class InstallWizard(Widget): |
|
|
|
ti_confirm_password = _dlg.ids.ti_confirm_password |
|
|
|
ti_confirm_password = _dlg.ids.ti_confirm_password |
|
|
|
if _btn != _dlg.ids.next: |
|
|
|
if _btn != _dlg.ids.next: |
|
|
|
if mode == 'restore': |
|
|
|
if mode == 'restore': |
|
|
|
|
|
|
|
# back is disabled cause seed is already set |
|
|
|
return |
|
|
|
return |
|
|
|
_dlg.close() |
|
|
|
_dlg.close() |
|
|
|
if not instance: |
|
|
|
if not instance: |
|
|
|
|
|
|
|
# back on create |
|
|
|
CreateRestoreDialog( |
|
|
|
CreateRestoreDialog( |
|
|
|
on_release=self.on_creatrestore_complete).open() |
|
|
|
on_release=self.on_creatrestore_complete).open() |
|
|
|
return |
|
|
|
return |
|
|
|
@ -236,17 +235,20 @@ class InstallWizard(Widget): |
|
|
|
return app.show_error(_('Passwords do not match')) |
|
|
|
return app.show_error(_('Passwords do not match')) |
|
|
|
|
|
|
|
|
|
|
|
if mode == 'restore': |
|
|
|
if mode == 'restore': |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
wallet.save_seed(new_password) |
|
|
|
|
|
|
|
except Exception as err: |
|
|
|
|
|
|
|
app.show_error(str(err)) |
|
|
|
|
|
|
|
return |
|
|
|
_dlg.close() |
|
|
|
_dlg.close() |
|
|
|
wallet.save_seed(new_password) |
|
|
|
|
|
|
|
self.load_network(wallet, mode='restore') |
|
|
|
self.load_network(wallet, mode='restore') |
|
|
|
return |
|
|
|
return |
|
|
|
if not instance: |
|
|
|
if not instance: |
|
|
|
# create |
|
|
|
# create |
|
|
|
_dlg.close() |
|
|
|
_dlg.close() |
|
|
|
self.load_network(wallet, mode='create') |
|
|
|
#self.load_network(wallet, mode='create') |
|
|
|
return self.init_seed_dialog(password=new_password, |
|
|
|
return self.init_seed_dialog(password=new_password, |
|
|
|
wallet=wallet, |
|
|
|
wallet=wallet, wallet_name=wallet_name, mode=mode) |
|
|
|
wallet_name=wallet_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
try: |
|
|
|
seed = wallet.decode_seed(password) |
|
|
|
seed = wallet.decode_seed(password) |
|
|
|
@ -275,48 +277,44 @@ class InstallWizard(Widget): |
|
|
|
mode=mode, |
|
|
|
mode=mode, |
|
|
|
on_release=on_release).open() |
|
|
|
on_release=on_release).open() |
|
|
|
|
|
|
|
|
|
|
|
def load_network(self, wallet, mode=None): |
|
|
|
def load_network(self, wallet, mode='create'): |
|
|
|
#if not self.config.get('server'): |
|
|
|
#if not self.config.get('server'): |
|
|
|
if not self.network: |
|
|
|
if self.network: |
|
|
|
return wallet.start_threads(self.network) |
|
|
|
if self.network.interfaces: |
|
|
|
|
|
|
|
if mode not in ('restore', 'create'): |
|
|
|
if not self.network.interfaces: |
|
|
|
self.network_dialog() |
|
|
|
app.show_error(_('You are offline')) |
|
|
|
else: |
|
|
|
self.network.stop() |
|
|
|
app.show_error(_('You are offline')) |
|
|
|
self.network = None |
|
|
|
self.network.stop() |
|
|
|
return wallet.start_threads(self.network) |
|
|
|
self.network = None |
|
|
|
|
|
|
|
|
|
|
|
if mode not in ('restore', 'create'): |
|
|
|
if mode in ('restore', 'create'): |
|
|
|
self.network_dialog() |
|
|
|
# auto cycle |
|
|
|
return wallet.start_threads(self.network) |
|
|
|
self.config.set_key('auto_cycle', True, True) |
|
|
|
|
|
|
|
# start wallet threads |
|
|
|
self.config.set_key('auto_cycle', True, True) |
|
|
|
|
|
|
|
wallet.start_threads(self.network) |
|
|
|
wallet.start_threads(self.network) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not mode == 'restore': |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
def get_text(text): |
|
|
|
def get_text(text): |
|
|
|
def set_text(*l): app.info_bubble.ids.lbl.text=text |
|
|
|
def set_text(*l): app.info_bubble.ids.lbl.text=text |
|
|
|
Clock.schedule_once(set_text) |
|
|
|
Clock.schedule_once(set_text) |
|
|
|
|
|
|
|
|
|
|
|
def on_complete(*l): |
|
|
|
def on_complete(*l): |
|
|
|
if not self.network: |
|
|
|
if not self.network: |
|
|
|
app.show_info_bubble( |
|
|
|
app.show_info(_("This wallet was restored offline." |
|
|
|
text=_("This wallet was restored offline. It may contain" |
|
|
|
"It may contain more addresses than displayed.")) |
|
|
|
" more addresses than displayed."), |
|
|
|
return self.dispatch('on_wizard_complete', wallet) |
|
|
|
width='200dp', |
|
|
|
|
|
|
|
pos=Window.center) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if wallet.is_found(): |
|
|
|
if wallet.is_found(): |
|
|
|
app.show_info_bubble(_("Recovery successful"), |
|
|
|
app.show_info(_("Recovery successful")) |
|
|
|
width='200dp', |
|
|
|
|
|
|
|
pos=Window.center) |
|
|
|
|
|
|
|
else: |
|
|
|
else: |
|
|
|
app.show_info_bubble(_("No transactions found for this seed"), |
|
|
|
app.show_info(_("No transactions found for this seed")) |
|
|
|
width='200dp', |
|
|
|
self.dispatch('on_wizard_complete', wallet) |
|
|
|
pos=Window.center) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.waiting_dialog(lambda: wallet.restore(get_text), |
|
|
|
self.waiting_dialog(lambda: wallet.restore(get_text), |
|
|
|
on_complete=on_complete) |
|
|
|
on_complete=on_complete) |
|
|
|
|
|
|
|
|
|
|
|
def on_wizard_complete(self, instance, wallet): |
|
|
|
def on_wizard_complete(self, wallet): |
|
|
|
pass |
|
|
|
pass |
|
|
|
|