示例#1
0
    def __init__(self, parent, config):
        QDialog.__init__(self, parent=parent)
        Ui_ConfigDlg.__init__(self)
        WndUtils.__init__(self, config)
        self.config = config
        self.main_window = parent
        self.local_config = AppConfig()
        self.local_config.copy_from(config)

        # list of connections from self.local_config.dash_net_configs split on separate lists for mainnet and testnet
        self.connections_mainnet = []
        self.connections_testnet = []
        self.connections_current = None
        self.current_network_cfg: Optional[DashNetworkConnectionCfg] = None

        # block ui controls -> cur config data copying while setting ui controls initial values
        self.disable_cfg_update = False
        self.is_modified = False
        self.setupUi()
示例#2
0
    def get_owner_key_to_display(self) -> str:
        ret = ''
        if self.masternode:
            if self.edit_mode:
                if self.masternode.dmn_owner_key_type == InputKeyType.PRIVATE:
                    ret = self.masternode.dmn_owner_private_key
                else:
                    ret = self.masternode.dmn_owner_address
            else:
                try:
                    if self.masternode.dmn_owner_key_type == InputKeyType.PRIVATE:
                        if self.act_view_as_owner_private_key.isChecked():
                            ret = self.masternode.dmn_owner_private_key
                        elif self.act_view_as_owner_public_address.isChecked():
                            if self.masternode.dmn_owner_private_key:
                                ret = crown_utils.wif_privkey_to_address(self.masternode.dmn_owner_private_key,
                                                                        self.app_config.crown_network)
                        elif self.act_view_as_owner_public_key.isChecked():
                            if self.masternode.dmn_owner_private_key:
                                ret = crown_utils.wif_privkey_to_pubkey(self.masternode.dmn_owner_private_key)
                        elif self.act_view_as_owner_public_key_hash.isChecked():
                            if self.masternode.dmn_owner_private_key:
                                pubkey = crown_utils.wif_privkey_to_pubkey(self.masternode.dmn_owner_private_key)
                                pubkey_bin = bytes.fromhex(pubkey)
                                pub_hash = bitcoin.bin_hash160(pubkey_bin)
                                ret = pub_hash.hex()
                        else:
                            ret = '???'
                    else:
                        if self.act_view_as_owner_public_address.isChecked():
                            ret = self.masternode.dmn_owner_address
                        elif self.act_view_as_owner_public_key_hash.isChecked():
                            ret = self.masternode.get_dmn_owner_pubkey_hash()
                        else:
                            ret = '???'
                except Exception as e:
                    msg = str(e)
                    if not msg:
                        msg = 'Key conversion error.'
                    WndUtils.errorMsg(msg)

        return ret
示例#3
0
    def validate_firmware_internal(self,
                                   version,
                                   fw,
                                   expected_fingerprint=None):
        """Adapted version of the 'validate_firmware' function from trezorlib"""
        if version == trezorlib.firmware.FirmwareFormat.TREZOR_ONE:
            if fw.embedded_onev2:
                log.debug(
                    "Trezor One firmware with embedded v2 image (1.8.0 or later)"
                )
            else:
                log.debug("Trezor One firmware image.")
        elif version == trezorlib.firmware.FirmwareFormat.TREZOR_ONE_V2:
            log.debug("Trezor One v2 firmware (1.8.0 or later)")
        elif version == trezorlib.firmware.FirmwareFormat.TREZOR_T:
            log.debug("Trezor T firmware image.")
            vendor = fw.vendor_header.text
            vendor_version = "{major}.{minor}".format(
                **fw.vendor_header.version)
            log.debug("Vendor header from {}, version {}".format(
                vendor, vendor_version))

        try:
            trezorlib.firmware.validate(version, fw, allow_unsigned=False)
            log.debug("Signatures are valid.")
        except trezorlib.firmware.Unsigned:
            if WndUtils.query_dlg(
                    'No signatures found. Continue?',
                    buttons=QMessageBox.Yes | QMessageBox.No,
                    default_button=QMessageBox.Yes,
                    icon=QMessageBox.Information) == QMessageBox.No:
                raise CancelException()

            try:
                trezorlib.firmware.validate(version, fw, allow_unsigned=True)
                log.debug("Unsigned firmware looking OK.")
            except trezorlib.firmware.FirmwareIntegrityError as e:
                log.exception(e)
                raise Exception("Firmware validation failed, aborting.")
        except trezorlib.firmware.FirmwareIntegrityError as e:
            log.exception(e)
            raise Exception("Firmware validation failed, aborting.")

        fingerprint = trezorlib.firmware.digest(version, fw).hex()
        log.debug("Firmware fingerprint: {}".format(fingerprint))
        if version == trezorlib.firmware.FirmwareFormat.TREZOR_ONE and fw.embedded_onev2:
            fingerprint_onev2 = trezorlib.firmware.digest(
                trezorlib.firmware.FirmwareFormat.TREZOR_ONE_V2,
                fw.embedded_onev2).hex()
            log.debug(
                "Embedded v2 image fingerprint: {}".format(fingerprint_onev2))
        if expected_fingerprint and fingerprint != expected_fingerprint:
            log.error("Expected fingerprint: {}".format(expected_fingerprint))
            raise Exception("Fingerprints do not match, aborting.")
 def __init__(self, parent: QDialog,
              config: AppConfig,
              dashd_intf: DashdInterface,
              raw_transaction: str,
              decoded_transaction: Optional[dict] = None,
              dependent_transactions: Optional[dict] = None
              ):
     QDialog.__init__(self, parent=parent)
     Ui_TransactionDlg.__init__(self)
     WndUtils.__init__(self, config)
     self.config = config
     self.parent = parent
     self.dashd_intf = dashd_intf
     self.transaction_sent = False
     self.raw_transaction = raw_transaction
     self.tx_id = None  # will be decoded from rawtransaction
     self.tx_size = None  # as above
     self.decoded_transaction: Optional[dict] = decoded_transaction
     self.dependent_transactions = dependent_transactions  # key: txid, value: transaction dict
     self.setupUi()
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.run_thread_dialog(load, (hw_device_id, mnemonic_words, pin, passphrase_enbled, hw_label),
                                          True)
    def on_btnChooseFirmwareFile_clicked(self):
        file_name = WndUtils.open_file_query(
            self.parent_dialog,
            self.app_config,
            message='Enter the firmware file name.',
            directory=None,
            filter='All Files (*.*)',
            initial_filter='All Files (*.*)')

        if file_name:
            self.selected_firmware_source_file = file_name
            self.edtFirmwareFilePath.setText(file_name)
def ask_for_word_callback(msg: str, wordlist: List[str]) -> str:
    def dlg():
        ui = hw_word_dlg.HardwareWalletWordDlg(msg, wordlist)
        if ui.exec_():
            return ui.get_word()
        else:
            return None

    if threading.current_thread() != threading.main_thread():
        return WndUtils.call_in_main_thread(dlg)
    else:
        return dlg()
    def __init__(self, parent, app_config: AppConfig):
        QDialog.__init__(self, parent=parent)
        Ui_ConfigDlg.__init__(self)
        WndUtils.__init__(self, app_config)
        self.app_config = app_config
        self.main_window = parent
        self.local_config = AppConfig(
            app_config.internal_ui_dark_mode_activated)
        self.local_config.copy_from(app_config)

        # list of connections from self.local_config.dash_net_configs split on separate lists for mainnet and testnet
        self.connections_mainnet = []
        self.connections_testnet = []
        self.connections_current = None
        self.current_network_cfg: Optional[DashNetworkConnectionCfg] = None

        # block ui controls -> cur config data copying while setting ui controls initial values
        self.disable_cfg_update = False
        self.is_modified = False
        self.global_options_modified = False  # user modified options not related to a config file
        self.setupUi(self)
 def __init__(self, parent) -> None:
     QDialog.__init__(self, parent)
     ui_wallet_tools_dlg.Ui_WalletToolsDlg.__init__(self)
     WndUtils.__init__(self, parent.app_config)
     self.finishing = False
     self.main_ui = parent
     self.app_config: AppConfig = parent.app_config
     self.current_action = ACTION_NONE
     self.action_widget: Optional[ActionPageBase] = None
     self.action_layout: Optional[QtWidgets.QVBoxLayout] = None
     self.hw_devices = HWDevices.get_instance()
     if not self.hw_devices:
         raise InternalError('HWDevices not initialized')
     self.hw_devices.save_state(
     )  # save the hw device currently connected in the main window
     self.hw_devices.set_allow_bootloader_mode(True)
     self.wdg_select_hw_device = CurrentHwDeviceWdg(self, self.hw_devices,
                                                    True)
     self.hw_devices.sig_connected_hw_device_changed.connect(
         self.on_connected_hw_device_changed)
     self.setupUi(self)
def ask_for_pin_callback(msg, hide_numbers=True):
    def dlg():
        ui = hw_pin_dlg.HardwareWalletPinDlg(msg, hide_numbers=hide_numbers)
        if ui.exec_():
            return ui.pin
        else:
            return None

    if threading.current_thread() != threading.main_thread():
        return WndUtils.call_in_main_thread(dlg)
    else:
        return dlg()
def ask_for_pass_callback():
    def dlg():
        ui = hw_pass_dlg.HardwareWalletPassDlg()
        if ui.exec_():
            return ui.getPassphrase()
        else:
            return None

    if threading.current_thread() != threading.main_thread():
        return WndUtils.call_in_main_thread(dlg)
    else:
        return dlg()
示例#12
0
 def update_ui(self):
     try:
         if self.cur_hw_device and self.cur_hw_device.hw_client and self.cur_hw_device.hw_type != HWType.ledger_nano:
             if self.current_step == Step.STEP_INPUT_OPTIONS:
                 self.pages.setCurrentIndex(Pages.PAGE_OPTIONS.value)
                 self.update_action_subtitle(
                     'enter hardware wallet options')
             elif self.current_step == Step.STEP_INITIALIZING_HW:
                 self.update_action_subtitle('initializing device')
                 self.pages.setCurrentIndex(Pages.PAGE_OPTIONS.value)
             elif self.current_step == Step.STEP_FINISHED:
                 self.update_action_subtitle('finished')
                 self.show_message_page(
                     '<b>Hardware wallet successfully initialized.</b>')
                 return
             self.show_action_page()
         else:
             self.show_message_page(
                 'Connect Trezor/Keepkey hardware wallet')
     except Exception as e:
         WndUtils.error_msg(str(e), True)
示例#13
0
 def __init__(self, utxos_source, main_ui):
     """
     Constructor
     :param utxos_source: list of tuples (dash address, bip32 path) - from which
         we'll list all unspent outputs
     :param masternodes: list of masternodes in configuration; used for checking if txid/index 
         is assigned to mn's collateral 
     """
     QDialog.__init__(self)
     WndUtils.__init__(self, main_ui.config)
     assert isinstance(utxos_source, list)
     assert isinstance(main_ui.dashd_intf, DashdInterface)
     self.utxos_source = utxos_source
     self.dashd_intf = main_ui.dashd_intf
     self.table_model = None
     self.source_address_mode = False
     self.utxos = []
     self.masternodes = main_ui.config.masternodes
     self.org_message = ''
     self.main_ui = main_ui
     self.setupUi()
示例#14
0
    def on_btnFindDMNTxHash_clicked(self, checked):
        if self.masternode and not self.updating_ui:
            found_protx = None
            if not ((self.masternode.ip and self.masternode.port) or
                    (self.masternode.collateralTx and self.masternode.collateralTxIndex)):
                WndUtils.errorMsg('To be able to locate the deterministic masternode transaction you need to '
                                  'provide the masternode ip + port or collateral tx + tx index.')
                return

            try:
                txes = self.crownd_intf.protx('list', 'registered', True)
                for protx in txes:
                    state = protx.get('state')
                    if state:
                        if (state.get('service') == self.masternode.ip + ':' + self.masternode.port) or \
                           (protx.get('collateralHash') == self.masternode.collateralTx and
                            str(protx.get('collateralIndex', '')) == self.masternode.collateralTxIndex):
                            found_protx = protx
                            break
            except Exception as e:
                pass

            if found_protx:
                if self.masternode.dmn_tx_hash == protx.get('proTxHash'):
                    WndUtils.infoMsg('You have te correct DMN TX hash in the masternode configuration.')
                else:
                    self.edtDMNTxHash.setText(protx.get('proTxHash'))
                    self.masternode.dmn_tx_hash = protx.get('proTxHash')
                    self.set_modified()
            else:
                WndUtils.warnMsg('Couldn\'t find this masternode in the list of registered deterministic masternodes.')
            self.set_modified()
    def setupUi(self, dlg):
        ui_wallet_tools_dlg.Ui_WalletToolsDlg.setupUi(self, self)
        self.setWindowTitle("Toolbox")
        WndUtils.change_widget_font_attrs(self.lblMessage,
                                          point_size_diff=3,
                                          bold=True)
        for action in (self.actHwSettings, self.actRecoverHw,
                       self.actInitializeHw, self.actWipeHw,
                       self.actUpdateHwFirmware, self.actCreateRpcauth,
                       self.actUdevRulesInfo):
            WndUtils.change_widget_font_attrs(action,
                                              point_size_diff=1,
                                              bold=False)
        self.activate_menu_page()

        lay = self.layout()
        lay.insertWidget(
            1, self.wdg_select_hw_device
        )  # hardware wallet selection panel is inserted just below the
        # main title

        self.action_layout = QtWidgets.QVBoxLayout(self.fraActionContainer)
        self.action_layout.setContentsMargins(6, 6, 6, 6)
        self.action_layout.setSpacing(3)
        self.action_layout.setObjectName("action_layout")
        WndUtils.change_widget_font_attrs(self.lblTitle,
                                          point_size_diff=3,
                                          bold=True)
    def setupUi(self, dlg):
        Ui_WdgRecoverHw.setupUi(self, self)
        self.rbSeedSourceHwScreen.toggled.connect(self.on_seed_source_change)
        self.rbSeedSourceAppWords.toggled.connect(self.on_seed_source_change)
        self.rbSeedSourceAppEntropy.toggled.connect(self.on_seed_source_change)
        self.pages.setCurrentIndex(Pages.PAGE_OPTIONS.value)
        WndUtils.set_icon(self, self.btnShowPIN, '*****@*****.**')
        WndUtils.set_icon(self, self.btnShowSecondaryPIN, '*****@*****.**')
        WndUtils.set_icon(self, self.btnShowPassphrase, '*****@*****.**')
        self.rbWordsCount12.toggled.connect(self.on_radio_word_count_toggled)
        self.rbWordsCount18.toggled.connect(self.on_radio_word_count_toggled)
        self.rbWordsCount24.toggled.connect(self.on_radio_word_count_toggled)
        self.btnShowPIN.pressed.connect(
            functools.partial(self.edtPrimaryPIN.setEchoMode,
                              QLineEdit.Normal))
        self.btnShowPIN.released.connect(
            functools.partial(self.edtPrimaryPIN.setEchoMode,
                              QLineEdit.Password))
        self.btnShowSecondaryPIN.pressed.connect(
            functools.partial(self.edtSecondaryPIN.setEchoMode,
                              QLineEdit.Normal))
        self.btnShowSecondaryPIN.released.connect(
            functools.partial(self.edtSecondaryPIN.setEchoMode,
                              QLineEdit.Password))
        self.btnShowPassphrase.pressed.connect(
            functools.partial(self.edtPassphrase.setEchoMode,
                              QLineEdit.Normal))
        self.btnShowPassphrase.released.connect(
            functools.partial(self.edtPassphrase.setEchoMode,
                              QLineEdit.Password))

        lay = self.page3.layout()
        lay.addWidget(self.words_wdg)
        self.set_word_count(self.word_count)
        self.update_styles()
 def __init__(self,
              message,
              hide_numbers=True,
              window_title: str = None,
              max_length=12,
              button_heights: Optional[int] = None,
              parent_window: Optional[QWidget] = None,
              columns: int = 3):
     QDialog.__init__(self)
     QDetectThemeChange.__init__(self)
     ui_hw_pin_dlg.Ui_HardwareWalletPinDlg.__init__(self)
     WndUtils.__init__(self, app_config=None)
     self.pin = ''
     self.message = message
     self.hide_numbers = hide_numbers
     self.window_title = window_title if window_title else 'Hardware wallet PIN'
     self.max_length = max_length
     self.button_heights = button_heights
     self.columns = columns
     if columns not in (2, 3):
         raise Exception('Invalid number of matrix columns')
     self.setupUi(self)
示例#18
0
 def __init__(self, main_dlg, config: AppConfig, fixd_intf: FixdInterface,
              masternode: MasternodeConfig,
              on_mn_config_updated_callback: Callable):
     QDialog.__init__(self, main_dlg)
     ui_upd_mn_service_dlg.Ui_UpdMnServiceDlg.__init__(self)
     WndUtils.__init__(self, main_dlg.config)
     self.main_dlg = main_dlg
     self.masternode = masternode
     self.app_config = config
     self.fixd_intf = fixd_intf
     self.on_mn_config_updated_callback = on_mn_config_updated_callback
     self.dmn_protx_hash = self.masternode.dmn_tx_hash
     self.dmn_actual_operator_pubkey = ""
     self.dmn_actual_operator_reward = 0
     self.dmn_new_operator_payout_address = ''
     self.dmn_prev_ip_port = self.masternode.ip + ':' + str(
         self.masternode.port)
     self.dmn_new_ip = ''
     self.dmn_new_port = ''
     self.upd_payout_active = False
     self.show_manual_commands = False
     self.setupUi()
 def on_wipe_code_enable_disable(self, _):
     if self.cur_hw_device and self.cur_hw_device.hw_client:
         if self.hw_opt_wipe_code_protection is True:
             # disable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to disable wipe code?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_wipe_code(self.cur_hw_device,
                                               remove=True)
                 self.update_ui()
         elif self.hw_opt_wipe_code_protection is False:
             # enable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to enable wipe code?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_wipe_code(self.cur_hw_device,
                                               remove=False)
                 self.update_ui()
 def on_passphrase_alwaysondevice_enable_disable(self, _):
     if self.cur_hw_device and self.cur_hw_device.hw_client:
         if self.hw_opt_passphrase_always_on_device is True:
             # disable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to disable passphrase always on device option?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_passphrase_always_on_device(
                     self.cur_hw_device, enabled=False)
                 self.update_ui()
         elif self.hw_opt_passphrase_always_on_device is False:
             # enable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to enable passphrase always on device option?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_passphrase_always_on_device(
                     self.cur_hw_device, enabled=True)
                 self.update_ui()
 def on_sd_card_protection_enable_disable(self, _):
     if self.cur_hw_device and self.cur_hw_device.hw_client:
         if self.hw_opt_sd_protection is True:
             # disable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to disable SD card protection?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_sd_protect(self.cur_hw_device,
                                                'disable')
                 self.update_ui()
         elif self.hw_opt_sd_protection is False:
             # enable passphrase
             if WndUtils.query_dlg(
                     'Do you really want to enable SD card protection?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Cancel,
                     icon=QMessageBox.Warning) == QMessageBox.Yes:
                 self.hw_devices.set_sd_protect(self.cur_hw_device,
                                                'enable')
                 self.update_ui()
示例#22
0
def hw_encrypt_value(hw_session: HwSessionInfo, bip32_path_n: List[int], label: str,
                     value: ByteString, ask_on_encrypt=True, ask_on_decrypt=True) -> Tuple[bytearray, bytearray]:
    """Encrypts a value with a hardware wallet.
    :param hw_session:
    :param bip32_path_n: bip32 path of the private key used for encryption
    :param label: key (in the meaning of key-value) used for encryption
    :param value: value being encrypted
    :param ask_on_encrypt: see Trezor doc
    :param ask_on_decrypt: see Trezor doc
    """

    def encrypt(ctrl, hw_session: HwSessionInfo, bip32_path_n: List[int], label: str,
                value: bytearray):
        ctrl.dlg_config_fun(dlg_title="Data encryption", show_progress_bar=False)
        ctrl.display_msg_fun(f'<b>Encrypting \'{label}\'...</b>'
                             f'<br><br>Enter the hardware wallet PIN/passphrase (if needed) to encrypt data.<br><br>'
                             f'<b>Note:</b> encryption passphrase is independent from the wallet passphrase  <br>'
                             f'and can vary for each encrypted file.')

        if hw_session.hw_type == HWType.trezor:
            from trezorlib import misc, btc
            from trezorlib import exceptions

            try:
                client = hw_session.hw_client
                data = misc.encrypt_keyvalue(client, bip32_path_n, label, value, ask_on_encrypt, ask_on_decrypt)
                pub_key = btc.get_public_node(client, bip32_path_n).node.public_key
                return data, pub_key
            except (CancelException, exceptions.Cancelled):
                raise CancelException()

        elif hw_session.hw_type == HWType.keepkey:

            client = hw_session.hw_client
            data = client.encrypt_keyvalue(bip32_path_n, label, value, ask_on_encrypt, ask_on_decrypt)
            pub_key = client.get_public_node(bip32_path_n).node.public_key
            return data, pub_key

        elif hw_session.hw_type == HWType.ledger_nano_s:

            raise Exception('Feature not available for Ledger Nano S.')

        else:
            raise Exception('Invalid HW type: ' + str(hw_session))

    if len(value) != 32:
        raise ValueError("Invalid password length (<> 32).")

    return WndUtils.run_thread_dialog(encrypt, (hw_session, bip32_path_n, label, value), True,
                                      force_close_dlg_callback=partial(cancel_hw_thread_dialog, hw_session.hw_client),
                                      show_window_delay_ms=200)
def get_address(hw_session: HwSessionInfo, bip32_path: str, show_display: bool = False, message_to_display: str = None):

    def _get_address(ctrl, hw_session: HwSessionInfo, bip32_path: str, show_display: bool = False,
                     message_to_display: str = None):
        if ctrl:
            ctrl.dlg_config_fun(dlg_title="Please confirm", show_progress_bar=False)
            if message_to_display:
                ctrl.display_msg_fun(message_to_display)
            else:
                ctrl.display_msg_fun('<b>Click the confirmation button on your hardware wallet to exit...</b>')

        client = hw_session.hw_client
        if client:
            if isinstance(bip32_path, str):
                bip32_path.strip()
                if bip32_path.lower().find('m/') >= 0:
                    # removing m/ prefix because of keepkey library
                    bip32_path = bip32_path[2:]

            if hw_session.app_config.hw_type == HWType.trezor:

                from trezorlib import btc
                if isinstance(bip32_path, str):
                    bip32_path = dash_utils.bip32_path_string_to_n(bip32_path)
                return btc.get_address(client, hw_session.app_config.hw_coin_name, bip32_path, show_display)

            elif hw_session.app_config.hw_type == HWType.keepkey:

                if isinstance(bip32_path, str):
                    bip32_path = dash_utils.bip32_path_string_to_n(bip32_path)
                return client.get_address(hw_session.app_config.hw_coin_name, bip32_path, show_display)

            elif hw_session.app_config.hw_type == HWType.ledger_nano_s:
                import hw_intf_ledgernano as ledger

                if isinstance(bip32_path, list):
                    # ledger requires bip32 path argument as a string
                    bip32_path = bip32_path_n_to_string(bip32_path)

                adr_pubkey = ledger.get_address_and_pubkey(client, bip32_path)
                return adr_pubkey.get('address')
            else:
                raise Exception('Unknown hardware wallet type: ' + hw_session.app_config.hw_type)
        else:
            raise Exception('HW client not open.')

    if show_display:
        return WndUtils.run_thread_dialog(_get_address, (hw_session, bip32_path, show_display, message_to_display),
                                          True)
    else:
        return _get_address(None, hw_session, bip32_path, show_display, message_to_display)
    def __init__(self,
                 config,
                 window,
                 connection=None,
                 on_connection_begin_callback=None,
                 on_connection_try_fail_callback=None,
                 on_connection_finished_callback=None):
        WndUtils.__init__(self, app_path=config.app_path)
        assert isinstance(config, AppConfig)

        self.config = config
        # conn configurations are used from the first item in the list; if one fails, then next is taken
        if connection:
            # this parameter is used for testing specific connection
            self.connections = [connection]
        else:
            # get connection list orderd by priority of use
            self.connections = self.config.get_ordered_conn_list()
        self.cur_conn_index = 0
        if self.connections:
            self.cur_conn_def = self.connections[self.cur_conn_index]
        else:
            self.cur_conn_def = None

        # below is the connection with which particular RPC call has started; if connection is switched because of
        # problems with some nodes, switching stops if we close round and return to the starting connection
        self.starting_conn = None

        self.ssh = None
        self.window = window
        self.active = False
        self.rpc_url = None
        self.proxy = None
        self.http_conn = None  # HTTPConnection object passed to the AuthServiceProxy (for convinient connection reset)
        self.on_connection_begin_callback = on_connection_begin_callback
        self.on_connection_try_fail_callback = on_connection_try_fail_callback
        self.on_connection_finished_callback = on_connection_finished_callback
        self.last_error_message = None
    def upload_firmware_thread(self, ctrl: CtrlObject):
        """
        Thread that performs upload of the selected firmware to the hardware wallet device. The device has to be in
        bootloader mode.
        """
        def add_info(msg: str):
            def append_message_mainth(msg_: str):
                t = self.lblUploadFirmwareMessage.text()
                t += f'<div>{msg}</div>'
                self.lblUploadFirmwareMessage.setText(t)
            WndUtils.call_in_main_thread(append_message_mainth, msg)

        update_ok = False
        try:
            self.hw_conn_change_allowed = False
            add_info('Uploading new firmware.<br><br><b>Click the confirmation button on your hardware wallet device '
                     'if necessary.</b>')
            if self.cur_hw_device.hw_type == HWType.trezor:
                update_ok = self.cur_hw_device.hw_client.firmware_update(self.selected_firmware_source_web.fingerprint,
                                                                         self.firmware_data)
            elif self.cur_hw_device.hw_type == HWType.keepkey:
                update_ok = self.cur_hw_device.hw_client.firmware_update(BytesIO(self.firmware_data))
            else:
                WndUtils.call_in_main_thread(self.go_to_prev_step)
                raise Exception('Invalid hardware wallet type')
            if not update_ok:
                WndUtils.error_msg('Operation failed. Look into the log file for details.')
        except CancelException:
            pass
        except Exception as e:
            WndUtils.error_msg('Operation failed with the following error: ' + str(e))
        finally:
            self.hw_conn_change_allowed = True
            self.upload_firmware_thread_obj = None
            if update_ok:
                WndUtils.call_in_main_thread(self.go_to_next_step)
            else:
                WndUtils.call_in_main_thread(self.go_to_prev_step)
示例#26
0
def hw_decrypt_value(hw_session: HwSessionInfo, bip32_path_n: List[int], label: str,
                     value: ByteString, ask_on_encrypt=True, ask_on_decrypt=True) -> Tuple[bytearray, bytearray]:
    """
    :param hw_session:
    :param passphrase_encoding: (for Keepkey only) it allows forcing the passphrase encoding compatible with BIP-39
        standard (NFKD), which is used by Trezor devices; by default Keepkey uses non-standard encoding (NFC).
    :param bip32_path_n: bip32 path of the private key used for encryption
    :param label: key (in the meaning of key-value) used for encryption
    :param value: encrypted value to be decrypted,
    :param ask_on_encrypt: see Trezor doc
    :param ask_on_decrypt: see Trezor doc
    """

    def decrypt(ctrl, hw_session: HwSessionInfo, bip32_path_n: List[int], label: str, value: bytearray):
        ctrl.dlg_config_fun(dlg_title="Data decryption", show_progress_bar=False)
        ctrl.display_msg_fun(f'<b>Decrypting \'{label}\'...</b><br><br>Enter the hardware wallet PIN/passphrase '
                             f'(if needed)<br> and click the confirmation button to decrypt data.')

        if hw_session.hw_type == HWType.trezor:

            from trezorlib import misc, btc
            from trezorlib import exceptions

            try:
                client = hw_session.hw_client
                data = misc.decrypt_keyvalue(client, bip32_path_n, label, value, ask_on_encrypt, ask_on_decrypt)
                pub_key = btc.get_public_node(client, bip32_path_n).node.public_key
                return data, pub_key
            except (CancelException, exceptions.Cancelled):
                raise CancelException()

        elif hw_session.hw_type == HWType.keepkey:

            client = hw_session.hw_client
            data = client.decrypt_keyvalue(bip32_path_n, label, value, ask_on_encrypt, ask_on_decrypt)
            pub_key = client.get_public_node(bip32_path_n).node.public_key
            return data, pub_key

        elif hw_session.hw_type == HWType.ledger_nano_s:

            raise Exception('Feature not available for Ledger Nano S.')

        else:
            raise Exception('Invalid HW type: ' + str(hw_session))

    if len(value) != 32:
        raise ValueError("Invalid password length (<> 32).")

    return WndUtils.run_thread_dialog(decrypt, (hw_session, bip32_path_n, label, value), True,
                                      force_close_dlg_callback=partial(cancel_hw_thread_dialog, hw_session.hw_client))
示例#27
0
    def generate_priv_key(self, pk_type:str, edit_control: QLineEdit, compressed: bool):
        if edit_control.text():
            if WndUtils.queryDlg(
                    f'This will overwrite the current {pk_type} private key value. Do you really want to proceed?',
                     buttons=QMessageBox.Yes | QMessageBox.Cancel,
                     default_button=QMessageBox.Yes, icon=QMessageBox.Warning) != QMessageBox.Yes:
                return None

        if pk_type == 'operator':
            pk = crown_utils.generate_bls_privkey()
        else:
            pk = crown_utils.generate_wif_privkey(self.app_config.crown_network, compressed=compressed)
        edit_control.setText(pk)
        return pk
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.run_thread_dialog(load, (hw_type, hw_device_id, strength, passphrase_enabled, pin_enabled,
                                                 hw_label), True, center_by_window=parent_window)
示例#29
0
def sign_tx(hw_session: HwSessionInfo, utxos_to_spend: List[UtxoType],
            tx_outputs: List[TxOutputType], tx_fee):
    """
    Creates a signed transaction.
    :param main_ui: Main window for configuration data
    :param utxos_to_spend: list of utxos to send
    :param tx_outputs: destination addresses. Fields: 0: dest FIX address. 1: the output value in satoshis,
        2: the bip32 path of the address if the output is the change address or None otherwise
    :param tx_fee: transaction fee
    :param rawtransactions: dict mapping txid to rawtransaction
    :return: tuple (serialized tx, total transaction amount in satoshis)
    """
    def sign(ctrl):
        ctrl.dlg_config_fun(dlg_title="Confirm transaction signing.",
                            show_progress_bar=False)
        ctrl.display_msg_fun(
            '<b>Click the confirmation button on your hardware wallet<br>'
            'and wait for the transaction to be signed...</b>')

        if hw_session.app_config.hw_type == HWType.trezor:
            import hw_intf_trezor as trezor

            return trezor.sign_tx(hw_session, utxos_to_spend, tx_outputs,
                                  tx_fee)

        elif hw_session.app_config.hw_type == HWType.keepkey:
            import hw_intf_keepkey as keepkey

            return keepkey.sign_tx(hw_session, utxos_to_spend, tx_outputs,
                                   tx_fee)

        elif hw_session.app_config.hw_type == HWType.ledger_nano_s:
            import hw_intf_ledgernano as ledger

            return ledger.sign_tx(hw_session, utxos_to_spend, tx_outputs,
                                  tx_fee)

        else:
            logging.error('Invalid HW type: ' +
                          str(hw_session.app_config.hw_type))

    # execute the 'prepare' function, but due to the fact that the call blocks the UI until the user clicks the HW
    # button, it's done inside a thread within a dialog that shows an appropriate message to the user
    sig = WndUtils.run_thread_dialog(sign, (),
                                     True,
                                     force_close_dlg_callback=partial(
                                         cancel_hw_thread_dialog,
                                         hw_session.hw_client))
    return sig
示例#30
0
def ask_for_pass_callback(pass_available_on_device: bool = False):
    def dlg():
        ui = hw_pass_dlg.HardwareWalletPassDlg(pass_available_on_device)
        if ui.exec_():
            if ui.getEnterOnDevice():
                return PASSPHRASE_ON_DEVICE
            else:
                return ui.getPassphrase()
        else:
            return None

    if threading.current_thread() != threading.main_thread():
        return WndUtils.call_in_main_thread(dlg)
    else:
        return dlg()