async def homescreen_dialog( ctx: wire.GenericContext, homepage: RecoveryHomescreen, button_label: str, info_func: Callable = None, ) -> None: while True: if info_func: continue_recovery = await info_confirm( ctx, homepage, code=ButtonRequestType.RecoveryHomepage, confirm=button_label, info_func=info_func, info="Info", cancel="Abort", ) else: continue_recovery = await confirm( ctx, homepage, code=ButtonRequestType.RecoveryHomepage, confirm=button_label, major_confirm=True, ) if continue_recovery: # go forward in the recovery process break # user has chosen to abort, confirm the choice dry_run = storage_recovery.is_dry_run() if await confirm_abort(ctx, dry_run): raise RecoveryAborted
async def recovery_process(ctx: wire.GenericContext) -> Success: try: return await _continue_recovery_process(ctx) except recover.RecoveryAborted: dry_run = storage_recovery.is_dry_run() if dry_run: storage_recovery.end_progress() else: storage.wipe() raise wire.ActionCancelled("Cancelled")
async def _continue_recovery_process(ctx: wire.GenericContext) -> Success: # gather the current recovery state from storage dry_run = storage_recovery.is_dry_run() word_count, backup_type = recover.load_slip39_state() # Both word_count and backup_type are derived from the same data. Both will be # either set or unset. We use 'backup_type is None' to detect status of both. # The following variable indicates that we are (re)starting the first recovery step, # which includes word count selection. is_first_step = backup_type is None if not is_first_step: assert word_count is not None # If we continue recovery, show starting screen with word count immediately. await _request_share_first_screen(ctx, word_count) secret = None while secret is None: if is_first_step: # If we are starting recovery, ask for word count first... word_count = await _request_word_count(ctx, dry_run) # ...and only then show the starting screen with word count. await _request_share_first_screen(ctx, word_count) assert word_count is not None # ask for mnemonic words one by one words = await layout.request_mnemonic(ctx, word_count, backup_type) # if they were invalid or some checks failed we continue and request them again if not words: continue try: secret, backup_type = await _process_words(ctx, words) # If _process_words succeeded, we now have both backup_type (from # its result) and word_count (from _request_word_count earlier), which means # that the first step is complete. is_first_step = False except MnemonicError: await layout.show_invalid_mnemonic(ctx, word_count) assert backup_type is not None if dry_run: result = await _finish_recovery_dry_run(ctx, secret, backup_type) else: result = await _finish_recovery(ctx, secret, backup_type) return result
def __init__(self, text: str, subtext: str = None): self.text = text self.subtext = subtext self.dry_run = storage_recovery.is_dry_run() self.repaint = True