async def show_backup_success(ctx): text = "Use your backup\nwhen you need to\nrecover your wallet." await require( show_success(ctx, "success_backup", text, subheader="Your backup is done."))
async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success: if not storage.sd_salt.is_enabled(): raise wire.ProcessError("SD card protection not enabled") # Note that the SD card doesn't need to be present in order to disable SD # protection. The cleanup will not happen in such case, but that does not matter. # Confirm that user wants to proceed with the operation. await require_confirm_sd_protect(ctx, msg) # Get the current PIN and salt from the SD card. pin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN") # Check PIN and remove salt. if not config.change_pin(pin_to_int(pin), pin_to_int(pin), salt, None): await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(None) try: # Clean up. storage.sd_salt.remove_sd_salt() except Exception: # The cleanup is not necessary for the correct functioning of # SD-protection. If it fails for any reason, we suppress the exception, # because overall SD-protection was successfully disabled. pass await require( show_success(ctx, "success_sd", "You have successfully disabled SD protection.")) return Success(message="SD card protection disabled")
async def _show_confirmation_success(ctx, share_index=None, num_of_shares=None, group_index=None): if share_index is None: # it is a BIP39 backup subheader = "You have finished\nverifying your\nrecovery seed." text = "" elif share_index == num_of_shares - 1: if group_index is None: subheader = "You have finished\nverifying your\nrecovery shares." else: subheader = ( "You have finished\nverifying your\nrecovery shares\nfor group %s." % (group_index + 1)) text = "" else: if group_index is None: subheader = "Recovery share #%s\nchecked successfully." % ( share_index + 1) text = "Continue with share #%s." % (share_index + 2) else: subheader = "Group %s - Share %s\nchecked successfully." % ( (group_index + 1), (share_index + 1), ) text = "Continue with the next\nshare." return await require( show_success(ctx, "success_recovery", text, subheader=subheader))
async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success: if not storage.sd_salt.is_enabled(): raise wire.ProcessError("SD card protection not enabled") # Confirm that user wants to proceed with the operation. await require_confirm_sd_protect(ctx, msg) # Make sure SD card is present. await ensure_sdcard(ctx) # Get the current PIN and salt from the SD card. pin, old_salt = await request_pin_and_sd_salt(ctx, "Enter PIN") # Check PIN and change salt. new_salt, new_auth_key, new_salt_tag = _make_salt() await _set_salt(ctx, new_salt, new_salt_tag, stage=True) if not config.change_pin(pin, pin, old_salt, new_salt): await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(new_auth_key) try: # Clean up. storage.sd_salt.commit_sd_salt() except Exception: # If the cleanup fails, then request_sd_salt() will bring the SD card # into a consistent state. We suppress the exception, because overall # SD-protection was successfully refreshed. pass await require( show_success(ctx, "success_sd", "You have successfully refreshed SD protection.")) return Success(message="SD card protection refreshed")
async def show_dry_run_result(ctx: wire.GenericContext, result: bool, is_slip39: bool) -> None: if result: if is_slip39: text = "The entered recovery\nshares are valid and\nmatch what is currently\nin the device." else: text = "The entered recovery\nseed is valid and\nmatches the one\nin the device." await require( show_success(ctx, "success_dry_recovery", text, button="Continue")) else: if is_slip39: text = "The entered recovery\nshares are valid but\ndo not match what is\ncurrently in the device." else: text = "The entered recovery\nseed is valid but does\nnot match the one\nin the device." await require( show_warning(ctx, "warning_dry_recovery", text, button="Continue"))
async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success: if not is_initialized(): raise wire.NotInitialized("Device is not initialized") # confirm that user wants to change the pin await require_confirm_change_pin(ctx, msg) # get old pin curpin, salt = await request_pin_and_sd_salt(ctx, "Enter old PIN") # if changing pin, pre-check the entered pin before getting new pin if curpin and not msg.remove: if not config.check_pin(pin_to_int(curpin), salt): await error_pin_invalid(ctx) # get new pin if not msg.remove: newpin = await request_pin_confirm(ctx) else: newpin = "" # write into storage if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt): if newpin: await error_pin_matches_wipe_code(ctx) else: await error_pin_invalid(ctx) if newpin: if curpin: msg_screen = "You have successfully changed your PIN." msg_wire = "PIN changed" else: msg_screen = "You have successfully enabled PIN protection." msg_wire = "PIN enabled" else: msg_screen = "You have successfully disabled PIN protection." msg_wire = "PIN removed" await require(show_success(ctx, "success_pin", msg_screen)) return Success(message=msg_wire)
async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success: if not is_initialized(): raise wire.NotInitialized("Device is not initialized") # Confirm that user wants to set or remove the wipe code. has_wipe_code = config.has_wipe_code() await _require_confirm_action(ctx, msg, has_wipe_code) # Get the unlocking PIN. pin, salt = await request_pin_and_sd_salt(ctx) if not msg.remove: # Pre-check the entered PIN. if config.has_pin() and not config.check_pin(pin_to_int(pin), salt): await error_pin_invalid(ctx) # Get new wipe code. wipe_code = await _request_wipe_code_confirm(ctx, pin) else: wipe_code = "" # Write into storage. if not config.change_wipe_code(pin_to_int(pin), salt, pin_to_int(wipe_code)): await error_pin_invalid(ctx) if wipe_code: if has_wipe_code: msg_screen = "You have successfully changed the wipe code." msg_wire = "Wipe code changed" else: msg_screen = "You have successfully set the wipe code." msg_wire = "Wipe code set" else: msg_screen = "You have successfully disabled the wipe code." msg_wire = "Wipe code removed" await require(show_success(ctx, "success_wipe_code", msg_screen)) return Success(message=msg_wire)
async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success: if storage.sd_salt.is_enabled(): raise wire.ProcessError("SD card protection already enabled") # Confirm that user wants to proceed with the operation. await require_confirm_sd_protect(ctx, msg) # Make sure SD card is present. await ensure_sdcard(ctx) # Get the current PIN. if config.has_pin(): pin = pin_to_int(await request_pin(ctx, "Enter PIN", config.get_pin_rem())) else: pin = pin_to_int("") # Check PIN and prepare salt file. salt, salt_auth_key, salt_tag = _make_salt() await _set_salt(ctx, salt, salt_tag) if not config.change_pin(pin, pin, None, salt): # Wrong PIN. Clean up the prepared salt file. try: storage.sd_salt.remove_sd_salt() except Exception: # The cleanup is not necessary for the correct functioning of # SD-protection. If it fails for any reason, we suppress the # exception, because primarily we need to raise wire.PinInvalid. pass await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(salt_auth_key) await require( show_success(ctx, "success_sd", "You have successfully enabled SD protection.")) return Success(message="SD card protection enabled")
async def _finish_recovery(ctx: wire.GenericContext, secret: bytes, backup_type: EnumTypeBackupType) -> Success: if backup_type is None: raise RuntimeError storage.device.store_mnemonic_secret(secret, backup_type, needs_backup=False, no_backup=False) if backup_type in (BackupType.Slip39_Basic, BackupType.Slip39_Advanced): identifier = storage.recovery.get_slip39_identifier() exponent = storage.recovery.get_slip39_iteration_exponent() if identifier is None or exponent is None: # Identifier and exponent need to be stored in storage at this point raise RuntimeError storage.device.set_slip39_identifier(identifier) storage.device.set_slip39_iteration_exponent(exponent) storage.recovery.end_progress() await require( show_success(ctx, "success_recovery", "You have successfully recovered your wallet.")) return Success(message="Device recovered")