def wipe_device(hw_type: HWType, hw_device_id: Optional[str], parent_window=None) -> Tuple[Optional[str], bool]: """ Wipes the hardware wallet device. :param hw_type: app_config.HWType :param hw_device_id: id of the device selected by the user (TrezorClient, KeepkeyClient) :param parent_window: ref to a window according to which will be centered message dialogs created here :return: Tuple Ret[0]: Device id. After wiping a new device id is generated, which is returned to the caller. Ret[1]: True, if the user cancelled the operation. In this situation we deliberately don't raise the 'cancelled' exception, because in the case of changing of the device id (when wiping) we want to pass it back to the caller. """ def wipe(ctrl): ctrl.dlg_config_fun(dlg_title="Confirm wiping device.", show_progress_bar=False) ctrl.display_msg_fun( '<b>Read the messages displyed on your hardware wallet <br>' 'and click the confirmation button when necessary...</b>') if hw_type == HWType.trezor: from hw_intf_trezor import wipe_device return wipe_device(hw_device_id) elif hw_type == HWType.keepkey: from hw_intf_keepkey import wipe_device return wipe_device(hw_device_id) elif hw_type == HWType.ledger_nano_s: raise Exception('Not supported by Ledger Nano S.') else: raise Exception('Invalid HW type: ' + str(hw_type)) # execute the 'wipe' inside a thread to avoid blocking UI return WndUtils.threadFunctionDialog(wipe, (), True, center_by_window=parent_window)
def load_device_by_mnemonic(mnemonic_words: str, pin: str, passphrase: str, secondary_pin: str): """ Initialise Ledger Nano S device with a list of mnemonic words. :param mnemonic_words: 12, 18 or 24 mnemonic words separated with spaces to initialise device. :param pin: PIN to be set in the device (4- or 8-character string) :param passphrase: Passphrase to be set in the device or empty. :param secondary_pin: Secondary PIN to activate passphrase. It's required if 'passphrase' is set. """ def process(ctrl, mnemonic_words, pin, passphrase, secondary_pin): ctrl.dlg_config_fun(dlg_title="Please confirm", show_progress_bar=False) ctrl.display_msg_fun('<b>Please wait while initializing device...</b>') dongle = getDongle() # stage 1: initialize the hardware wallet with mnemonic words apdudata = bytearray() if pin: apdudata += bytearray([len(pin)]) + bytearray(pin, 'utf8') else: apdudata += bytearray([0]) # empty prefix apdudata += bytearray([0]) # empty passphrase in this phase apdudata += bytearray([0]) if mnemonic_words: apdudata += bytearray([len(mnemonic_words)]) + bytearray( mnemonic_words, 'utf8') else: apdudata += bytearray([0]) apdu = bytearray([0xE0, 0xD0, 0x00, 0x00, len(apdudata)]) + apdudata dongle.exchange(apdu, timeout=3000) # stage 2: setup the secondary pin and the passphrase if provided if passphrase and secondary_pin: ctrl.display_msg_fun( '<b>Configuring the passphrase, enter the primary PIN on your <br>' 'hardware wallet when asked...</b>') apdudata = bytearray() if pin: apdudata += bytearray([len(pin)]) + bytearray( secondary_pin, 'utf8') else: apdudata += bytearray([0]) # empty prefix apdudata += bytearray([0]) if passphrase: passphrase = unicodedata.normalize('NFKD', passphrase) apdudata += bytearray([len(passphrase)]) + bytearray( passphrase, 'utf8') else: apdudata += bytearray([0]) # empty mnemonic words in this phase apdudata += bytearray([0]) apdu = bytearray([0xE0, 0xD0, 0x01, 0x00, len(apdudata)]) + apdudata dongle.exchange(apdu, timeout=3000) dongle.close() del dongle try: return WndUtils.threadFunctionDialog( process, (mnemonic_words, pin, passphrase, secondary_pin), True) except BTChipException as e: if e.message == 'Invalid status 6982': raise Exception( 'Operation failed with the following error: %s. \n\nMake sure you have reset the device ' 'and started it in recovery mode.' % e.message) else: raise except Exception as e: raise
def reset_device(hw_type: HWType, hw_device_id: str, word_count: int, passphrase_enabled: bool, pin_enabled: bool, hw_label: str, parent_window=None) -> Tuple[Optional[str], bool]: """ Initialize device with a newly generated words. :param hw_type: app_config.HWType :param hw_device_id: id of the device selected by the user (TrezorClient, KeepkeyClient); None for Ledger Nano S :param word_count: number of words (12/18/24) :param passphrase_enbled: if True, hw will have passphrase enabled (Trezor/Keepkey) :param pin_enabled: if True, hw will have pin enabled (Trezor/Keepkey) :param hw_label: label for device (Trezor/Keepkey) :param parent_window: ref to a window according to which will be centered message dialogs created here :return: Tuple Ret[0]: Device id. If a device is wiped before initializing with mnemonics, a new device id is generated. It's returned to the caller. Ret[1]: True, if the user cancelled the operation. In this situation we deliberately don't raise the 'cancelled' exception, because in the case of changing of the device id (when wiping) we want to pass it back to the caller function. Ret[0] and Ret[1] are None for Ledger devices. """ def load(ctrl, hw_type: HWType, hw_device_id: str, strength: int, passphrase_enabled: bool, pin_enabled: bool, hw_label: str) -> Tuple[Optional[str], bool]: ctrl.dlg_config_fun(dlg_title="Please confirm", show_progress_bar=False) ctrl.display_msg_fun( '<b>Read the messages displyed on your hardware wallet <br>' 'and click the confirmation button when necessary...</b>') if hw_device_id: if hw_type == HWType.trezor: from hw_intf_trezor import reset_device return reset_device(hw_device_id, strength, passphrase_enabled, pin_enabled, hw_label) elif hw_type == HWType.keepkey: from hw_intf_keepkey import reset_device return reset_device(hw_device_id, strength, passphrase_enabled, pin_enabled, hw_label) else: raise Exception('Not supported by Ledger Nano S.') else: raise Exception('Not connected to a hardware wallet') if hw_type == HWType.ledger_nano_s: raise Exception('Not supported by Ledger Nano S.') else: if word_count not in (12, 18, 24): raise Exception('Invalid word count.') strength = {24: 32, 18: 24, 12: 16}.get(word_count) * 8 return WndUtils.threadFunctionDialog( load, (hw_type, hw_device_id, strength, passphrase_enabled, pin_enabled, hw_label), True, center_by_window=parent_window)
def load_device_by_mnemonic(hw_type: HWType, hw_device_id: Optional[str], mnemonic_words: str, pin: str, passphrase_enbled: bool, hw_label: str, passphrase: str, secondary_pin: str, parent_window=None) -> Tuple[Optional[str], bool]: """ Initializes hardware wallet with a mnemonic words. For security reasons use this function only on an offline system, that will never be connected to the Internet. :param hw_type: app_config.HWType :param hw_device_id: id of the device selected by the user (TrezorClient, KeepkeyClient); None for Ledger Nano S :param mnemonic_words: string of 12/18/24 mnemonic words (separeted by spaces) :param pin: string with a new pin :param passphrase_enbled: if True, hw will have passphrase enabled (Trezor/Keepkey) :param hw_label: label for device (Trezor/Keepkey) :param passphrase: passphrase to be saved in the device (Ledger Nano S) :param secondary_pin: PIN securing passphrase (Ledger Nano S) :param parent_window: ref to a window according to which will be centered message dialogs created here :return: Tuple Ret[0]: Device id. If a device is wiped before initializing with mnemonics, a new device id is generated. It's returned to the caller. Ret[1]: True, if the user cancelled the operation. In this situation we deliberately don't raise the 'cancelled' exception, because in the case of changing of the device id (when wiping) we want to pass it back to the caller. Ret[0] and Ret[1] are None for Ledger devices. """ def load(ctrl, hw_device_id: str, mnemonic: str, pin: str, passphrase_enbled: bool, hw_label: str) -> \ Tuple[Optional[str], bool]: ctrl.dlg_config_fun(dlg_title="Please confirm", show_progress_bar=False) ctrl.display_msg_fun( '<b>Read the messages displyed on your hardware wallet <br>' 'and click the confirmation button when necessary...</b>') if hw_device_id: if hw_type == HWType.trezor: from hw_intf_trezor import load_device_by_mnemonic return load_device_by_mnemonic(hw_device_id, mnemonic, pin, passphrase_enbled, hw_label) elif hw_type == HWType.keepkey: from hw_intf_keepkey import load_device_by_mnemonic return load_device_by_mnemonic(hw_device_id, mnemonic, pin, passphrase_enbled, hw_label) else: raise Exception('Not supported by Ledger Nano S.') else: raise Exception('Not connected to a hardware wallet') if hw_type == HWType.ledger_nano_s: import hw_intf_ledgernano hw_intf_ledgernano.load_device_by_mnemonic(mnemonic_words, pin, passphrase, secondary_pin) return hw_device_id, False else: return WndUtils.threadFunctionDialog( load, (hw_device_id, mnemonic_words, pin, passphrase_enbled, hw_label), True)