コード例 #1
0
        def set_text(widget, text: str):
            def call(widget, text):
                widget.setText(text)
                widget.repaint()
                widget.setVisible(True)

            WndUtils.call_in_main_thread(call, widget, text)
コード例 #2
0
    def hide_request_character_dialog(self):
        if self.char_request_dialog and self.char_request_dialog_shown:

            def hide():
                self.char_request_dialog.hide()
                del self.char_request_dialog
                self.char_request_dialog = None
                self.char_request_dialog_shown = False

            WndUtils.call_in_main_thread(hide)
コード例 #3
0
    def get_collateral_tx_address_thread(self, ctrl: CtrlObject,
                                         bip44_wallet: Bip44Wallet):
        utxos = []
        break_scanning = False
        txes_cnt = 0
        msg = 'Scanning wallet transactions for 1000 Dash UTXOs.<br>' \
              'This may take a while (<a href="break">break</a>)....'
        ctrl.dlg_config_fun(dlg_title="Scanning wallet",
                            show_progress_bar=False)
        ctrl.display_msg_fun(msg)

        def check_break_scanning():
            nonlocal break_scanning
            if break_scanning:
                # stop the scanning process if the dialog finishes or the address/bip32path has been found
                raise BreakFetchTransactionsException()

        def fetch_txes_feeback(tx_cnt: int):
            nonlocal msg, txes_cnt
            txes_cnt += tx_cnt
            ctrl.display_msg_fun(msg + '<br><br>' +
                                 'Number of transactions fetched so far: ' +
                                 str(txes_cnt))

        def on_msg_link_activated(link: str):
            nonlocal break_scanning
            if link == 'break':
                break_scanning = True

        lbl = ctrl.get_msg_label_control()
        if lbl:

            def set():
                lbl.setOpenExternalLinks(False)
                lbl.setTextInteractionFlags(lbl.textInteractionFlags()
                                            & ~Qt.TextSelectableByMouse)
                lbl.linkActivated.connect(on_msg_link_activated)
                lbl.repaint()

            WndUtils.call_in_main_thread(set)

        try:
            bip44_wallet.on_fetch_account_txs_feedback = fetch_txes_feeback
            bip44_wallet.fetch_all_accounts_txs(check_break_scanning)

            for utxo in bip44_wallet.list_utxos_for_account(
                    account_id=None, filter_by_satoshis=1e11):
                utxos.append(utxo)

        except BreakFetchTransactionsException:
            return None
        return utxos
コード例 #4
0
 def get_latest_firmware_thread(self, ctr: CtrlObject, hw_model: HWModel):
     try:
         fws = hw_intf.get_hw_firmware_web_sources((hw_model, ),
                                                   only_official=True,
                                                   only_latest=True)
         if fws:
             self.latest_firmwares[hw_model] = fws[0]
             WndUtils.call_in_main_thread(self.update_ui)
         else:
             self.latest_firmwares[
                 hw_model] = None  # mark that we weren't able to read the latest firmware version
     except Exception as e:
         logging.error(
             'Error while reading the latest version of the hw firmware: ' +
             str(e))
コード例 #5
0
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()
コード例 #6
0
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()
コード例 #7
0
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()
コード例 #8
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()
コード例 #9
0
def connect_trezor(
        device_id: Optional[str] = None) -> Optional[MyTrezorClient]:
    """
    Connect to a Trezor device.
    :param device_id:
    :return: ref to a trezor client if connection successfull or None if we are sure that no Trezor device connected.
    """

    logging.info('Started function')

    def get_client() -> Optional[MyTrezorClient]:
        from trezorlib.transport_hid import HidTransport
        count = len(HidTransport.enumerate())
        if not count:
            logging.warning('Number of Trezor devices: 0')

        for d in HidTransport.enumerate():
            transport = HidTransport(d)
            client = MyTrezorClient(transport, ask_for_pin_callback,
                                    ask_for_pass_callback)
            if not device_id or client.features.device_id == device_id:
                return client
            else:
                client.clear_session()
                client.close()
        return None

    # HidTransport.enumerate() has to be called in the main thread - second call from bg thread
    # causes SIGSEGV
    client = WndUtils.call_in_main_thread(get_client)
    if client:
        logging.info(
            'Trezor connected. Firmware version: %s.%s.%s, vendor: %s, initialized: %s, '
            'pp_protection: %s, pp_cached: %s, bootloader_mode: %s ' %
            (str(client.features.major_version),
             str(client.features.minor_version),
             str(client.features.patch_version), str(
                 client.features.vendor), str(client.features.initialized),
             str(client.features.passphrase_protection),
             str(client.features.passphrase_cached),
             str(client.features.bootloader_mode)))
        return client
    else:
        if device_id:
            msg = 'Cannot connect to the Trezor device with this id: %s.' % device_id
        else:
            msg = 'Cannot find any Trezor device.'
        raise Exception(msg)
コード例 #10
0
def connect_keepkey(passphrase_encoding: Optional[str] = 'NFC',
                    device_id: Optional[str] = None) -> Optional[MyKeepkeyClient]:
    """
    Connect to a Keepkey device.
    :passphrase_encoding: Allowed values: 'NFC' or 'NFKD'. Note: Keekpey uses NFC encoding for passphrases, which is
        incompatible with BIP-39 standard (NFKD). This argument gives the possibility to enforce comforming the
        standard encoding.
    :return: ref to a keepkey client if connection successfull or None if we are sure that no Keepkey device connected.
    """

    logging.info('Started function')
    def get_client() -> Optional[MyKeepkeyClient]:
        from keepkeylib.transport_hid import HidTransport

        count = len(HidTransport.enumerate())
        if not count:
            logging.warning('Number of Keepkey devices: 0')

        for d in HidTransport.enumerate():
            transport = HidTransport(d)
            client = MyKeepkeyClient(transport, ask_for_pin_callback, ask_for_pass_callback, passphrase_encoding)
            if not device_id or client.features.device_id == device_id:
                return client
            else:
                client.clear_session()
                client.close()
        return None

    # HidTransport.enumerate() has to be called in the main thread - second call from bg thread
    # causes SIGSEGV
    client = WndUtils.call_in_main_thread(get_client)
    if client:
        logging.info('Keepkey connected. Firmware version: %s.%s.%s, vendor: %s, initialized: %s, '
                     'pp_protection: %s, pp_cached: %s, bootloader_mode: %s ' %
                     (str(client.features.major_version),
                      str(client.features.minor_version),
                      str(client.features.patch_version), str(client.features.vendor),
                      str(client.features.initialized),
                      str(client.features.passphrase_protection), str(client.features.passphrase_cached),
                      str(client.features.bootloader_mode)))
        return client
    else:
        if device_id:
            msg = 'Cannot connect to the Keepkey device with this id: .' % device_id
        else:
            msg = 'Cannot find any Keepkey device.'
        raise Exception(msg)
コード例 #11
0
    def sign_protx_message_with_hw(self, msg_to_sign) -> str:
        sig = WndUtils.call_in_main_thread(
            hw_intf.hw_sign_message, self.main_dlg.hw_session,
            self.dmn_collateral_tx_address_path, msg_to_sign,
            'Click the confirmation button on your hardware wallet to sign the ProTx payload message.'
        )

        if sig.address != self.dmn_collateral_tx_address:
            log.error(
                f'Protx payload signature address mismatch. Is: {sig.address}, should be: '
                f'{self.dmn_collateral_tx_address}.')
            raise Exception(
                f'Protx payload signature address mismatch. Is: {sig.address}, should be: '
                f'{self.dmn_collateral_tx_address}.')
        else:
            sig_bin = base64.b64encode(sig.signature)
            payload_sig_str = sig_bin.decode('ascii')
            return payload_sig_str
コード例 #12
0
    def ask_for_password(username, host, message=None):
        if not SshPassCache.parent_window:
            raise Exception('SshPassCache not initialized')

        def query_psw(msg):
            password, ok = QInputDialog.getText(SshPassCache.parent_window,
                                                'Password Dialog',
                                                msg,
                                                echo=QLineEdit.Password)
            return password, ok

        if not message:
            message = 'Enter password for ' + username + '@' + host + ':'

        if threading.current_thread() != threading.main_thread():
            password, ok = WndUtils.call_in_main_thread(query_psw, message)
        else:
            password, ok = query_psw(message)

        if not ok:
            raise UserCancelledConnection
        return password
コード例 #13
0
def ask_for_martix_element_callback(msg,
                                    columns: int = 3,
                                    parent_window: Optional[QWidget] = None):
    # noinspection SqlResolve
    def dlg():
        ui = hw_pin_dlg.HardwareWalletPinDlg(
            msg,
            hide_numbers=True,
            window_title='Enter element of seed word',
            max_length=1,
            button_heights=35,
            parent_window=parent_window,
            columns=columns)
        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()
コード例 #14
0
    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)
コード例 #15
0
 def request_character(self,
                       cur_characters: Optional[str],
                       label: Optional[str] = None) -> int:
     return WndUtils.call_in_main_thread(self._request_character,
                                         cur_characters, label)
コード例 #16
0
def connect_keepkey(passphrase_encoding: Optional[str] = 'NFC',
                    device_id: Optional[str] = None) -> Optional[MyKeepkeyClient]:
    """
    Connect to a Keepkey device.
    :passphrase_encoding: Allowed values: 'NFC' or 'NFKD'. Note: Keekpey uses NFC encoding for passphrases, which is
        incompatible with BIP-39 standard (NFKD). This argument gives the possibility to enforce comforming the
        standard encoding.
    :return: ref to a keepkey client if connection successfull or None if we are sure that no Keepkey device connected.
    """

    logging.info('Started function')
    def get_client() -> Optional[MyKeepkeyClient]:
        hw_clients, exceptions = get_device_list(passphrase_encoding=passphrase_encoding)
        if not hw_clients:
            if exceptions:
                raise exceptions[0]
        else:
            selected_client = None
            if device_id:
                # we have to select a device with the particular id number
                for cli in hw_clients:
                    if cli['device_id'] == device_id:
                        selected_client = cli['client']
                        break
                    else:
                        cli['client'].close()
                        cli['client'] = None
            else:
                # we are not forced to automatically select the particular device
                if len(hw_clients) > 1:
                    hw_names = [a['desc'] for a in hw_clients]

                    selected_index = select_hw_device(None, 'Select Keepkey device', hw_names)
                    if selected_index is not None and (0 <= selected_index < len(hw_clients)):
                        selected_client = hw_clients[selected_index]
                else:
                    selected_client = hw_clients[0]['client']

            # close all the clients but the selected one
            for cli in hw_clients:
                if cli['client'] != selected_client:
                    cli['client'].close()
                    cli['client'] = None

            return selected_client
        return None

    # HidTransport.enumerate() has to be called in the main thread - second call from bg thread
    # causes SIGSEGV
    client = WndUtils.call_in_main_thread(get_client)
    if client:
        logging.info('Keepkey connected. Firmware version: %s.%s.%s, vendor: %s, initialized: %s, '
                     'pp_protection: %s, pp_cached: %s, bootloader_mode: %s ' %
                     (str(client.features.major_version),
                      str(client.features.minor_version),
                      str(client.features.patch_version), str(client.features.vendor),
                      str(client.features.initialized),
                      str(client.features.passphrase_protection), str(client.features.passphrase_cached),
                      str(client.features.bootloader_mode)))
        return client
    else:
        if device_id:
            msg = 'Cannot connect to the Keepkey device with this id: .' % device_id
        else:
            msg = 'Cannot find any Keepkey device.'
        raise Exception(msg)
コード例 #17
0
def connect_trezor(
        device_id: Optional[str] = None) -> Optional[MyTrezorClient]:
    """
    Connect to a Trezor device.
    :param device_id:
    :return: ref to a trezor client if connection successfull or None if we are sure that no Trezor device connected.
    """

    logging.info('Started function')

    def get_client() -> Optional[MyTrezorClient]:

        hw_clients, exceptions = get_device_list()
        if not hw_clients:
            if exceptions:
                raise exceptions[0]
        else:
            selected_client = None
            if device_id:
                # we have to select a device with the particular id number
                for cli in hw_clients:
                    if cli['device_id'] == device_id:
                        selected_client = cli['client']
                        break
                    else:
                        cli['client'].close()
                        cli['client'] = None
            else:
                # we are not forced to automatically select the particular device
                if len(hw_clients) > 1:
                    hw_names = [a['desc'] for a in hw_clients]

                    selected_index = select_hw_device(None,
                                                      'Select Trezor device',
                                                      hw_names)
                    if selected_index is not None and (0 <= selected_index <
                                                       len(hw_clients)):
                        selected_client = hw_clients[selected_index]['client']
                else:
                    selected_client = hw_clients[0]['client']

            # close all the clients but the selected one
            for cli in hw_clients:
                if cli['client'] != selected_client:
                    cli['client'].close()
                    cli['client'] = None

            return selected_client
        return None

    # HidTransport.enumerate() has to be called in the main thread - second call from bg thread
    # causes SIGSEGV
    client = WndUtils.call_in_main_thread(get_client)
    if client:
        logging.info(
            'Trezor connected. Firmware version: %s.%s.%s, vendor: %s, initialized: %s, '
            'pp_protection: %s, pp_cached: %s, bootloader_mode: %s ' %
            (str(client.features.major_version),
             str(client.features.minor_version),
             str(client.features.patch_version), str(
                 client.features.vendor), str(client.features.initialized),
             str(client.features.passphrase_protection),
             str(client.features.passphrase_cached),
             str(client.features.bootloader_mode)))
        return client
    else:
        if device_id:
            msg = 'Cannot connect to the Trezor device with this id: %s.' % device_id
        else:
            msg = 'Cannot find any Trezor device.'
        raise Exception(msg)
コード例 #18
0
    def prepare_firmware_upload_thread(self, ctrl: CtrlObject):
        """
        Thread that performs the steps of preparing the firmware for upload and making sure that
        the device is in the bootloader mode.
        """
        def add_info(msg: str):
            def append_message_mainth(msg_: str):
                t = self.lblPrepareFirmwareMessage.text()
                t += f'<div>{msg}</div>'
                self.lblPrepareFirmwareMessage.setText(t)
            WndUtils.call_in_main_thread(append_message_mainth, msg)

        def operation_succeeded():
            self.set_btn_continue_enabled(True)
            self.set_btn_back_enabled(True)
            self.set_btn_cancel_enabled(True)

        def operation_failed(message: str):
            WndUtils.error_msg(message)
            self.set_btn_continue_enabled(False)
            self.set_btn_back_enabled(True)
            self.set_btn_cancel_enabled(True)

        try:
            firmware_fingerprint = ''
            if self.hw_firmware_source_type == FirmwareSource.INTERNET:
                if not self.selected_firmware_source_web:
                    raise Exception('Firmware source not available.')

                url = self.selected_firmware_source_web.url
                firmware_fingerprint = self.selected_firmware_source_web.fingerprint
                file_name = os.path.basename(urllib.parse.urlparse(url).path)
                f_, ext_ = os.path.splitext(file_name)
                if f_ and not re.match('.*\d+\.\d+\.\d+.*', f_):
                    # add version string to the name of the file being downloaded
                    file_name = f_ + '-' + self.selected_firmware_source_web.version + ext_
                local_file_path = os.path.join(self.app_config.cache_dir, file_name)

                add_info(f' * Downloading firmware from <a href="{url}">{url}</a>')

                try:
                    response = urllib.request.Request(url, data=None, headers={'User-Agent': app_defs.BROWSER_USER_AGENT})
                    f = urllib.request.urlopen(response)
                    self.firmware_data = f.read()
                except Exception as e:
                    raise Exception('Could not download firmware file ' + url + ': ' + str(e))

                try:
                    add_info(' * Saving firmware to a temp file ' + local_file_path)
                    with open(local_file_path, 'wb') as out_fptr:
                        out_fptr.write(self.firmware_data)
                except Exception as e:
                    pass
            else:
                add_info(f' * Reading firmware from ' + self.selected_firmware_source_file)
                with open(self.selected_firmware_source_file, 'rb') as fptr:
                    self.firmware_data = fptr.read()

            add_info(' * Verifying firmware')

            if self.cur_hw_device.hw_type == HWType.trezor:
                if self.firmware_data[:8] == b'54525a52' or self.firmware_data[:8] == b'54525a56':
                    data = binascii.unhexlify(self.firmware_data)
                else:
                    data = self.firmware_data
                self.cur_hw_device.hw_client.validate_firmware(firmware_fingerprint, data)

            elif self.cur_hw_device.hw_type == HWType.keepkey:
                if self.firmware_data[:8] == b'4b504b59':
                    data = binascii.unhexlify(self.firmware_data)
                else:
                    data = self.firmware_data
                self.cur_hw_device.hw_client.validate_firmware(firmware_fingerprint, data)

            add_info('<br><b>1. Make sure you have your backup seed on hand as some updates may erase data from your '
                     'device.</b><br><br>'
                     '<b>2. Put the device into bootloader mode and press the &lt;Continue&gt; button to upload the '
                     'new firmware.</b>')
            WndUtils.call_in_main_thread(operation_succeeded)

        except Exception as e:
            WndUtils.call_in_main_thread(operation_failed, str(e))
コード例 #19
0
 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)
コード例 #20
0
    def get_collateral_tx_address_thread(self, ctrl: CtrlObject):
        txes_cnt = 0
        msg = ''
        break_scanning = False
        ctrl.dlg_config_fun(dlg_title="Validating collateral transaction.",
                            show_progress_bar=False)
        ctrl.display_msg_fun('Verifying collateral transaction...')

        def check_break_scanning():
            nonlocal break_scanning
            if self.finishing or break_scanning:
                # stop the scanning process if the dialog finishes or the address/bip32path has been found
                raise BreakFetchTransactionsException()

        def fetch_txes_feeback(tx_cnt: int):
            nonlocal msg, txes_cnt
            txes_cnt += tx_cnt
            ctrl.display_msg_fun(msg + '<br><br>' +
                                 'Number of transactions fetched so far: ' +
                                 str(txes_cnt))

        def on_msg_link_activated(link: str):
            nonlocal break_scanning
            if link == 'break':
                break_scanning = True

        try:
            tx = self.dashd_intf.getrawtransaction(self.dmn_collateral_tx,
                                                   1,
                                                   skip_cache=True)
        except Exception as e:
            raise Exception(
                'Cannot get the collateral transaction due to the following errror: '
                + str(e))

        vouts = tx.get('vout')
        if vouts:
            if self.dmn_collateral_tx_index < len(vouts):
                vout = vouts[self.dmn_collateral_tx_index]
                spk = vout.get('scriptPubKey')
                if not spk:
                    raise Exception(
                        f'The collateral transaction ({self.dmn_collateral_tx}) output '
                        f'({self.dmn_collateral_tx_index}) doesn\'t have value in the scriptPubKey '
                        f'field.')
                ads = spk.get('addresses')
                if not ads or len(ads) < 0:
                    raise Exception(
                        'The collateral transaction output doesn\'t have the Dash address assigned.'
                    )
                self.dmn_collateral_tx_address = ads[0]
            else:
                raise Exception(
                    f'Transaction {self.dmn_collateral_tx} doesn\'t have output with index: '
                    f'{self.dmn_collateral_tx_index}')
        else:
            raise Exception('Invalid collateral transaction')

        ctrl.display_msg_fun(
            'Verifying the collateral transaction address on your hardware wallet.'
        )
        if not self.main_dlg.connect_hardware_wallet():
            return False

        if self.dmn_collateral_tx_address_path:
            addr = hw_intf.get_address(self.main_dlg.hw_session,
                                       self.dmn_collateral_tx_address_path)
            msg = ''
            if addr != self.dmn_collateral_tx_address:
                log.warning(
                    f'The address returned by the hardware wallet ({addr}) for the BIP32 path '
                    f'{self.dmn_collateral_tx_address_path} differs from the address stored the mn configuration '
                    f'(self.dmn_collateral_tx_address). Need to scan wallet for a correct BIP32 path.'
                )

                msg = '<span style="color:red">The BIP32 path of the collateral address from your mn config is incorret.<br></span>' \
                      f'Trying to find the BIP32 path of the address {self.dmn_collateral_tx_address} in your wallet.' \
                      f'<br>This may take a while (<a href="break">break</a>)...'
                self.dmn_collateral_tx_address_path = ''
        else:
            msg = 'Looking for a BIP32 path of the Dash address related to the masternode collateral.<br>' \
                  'This may take a while (<a href="break">break</a>)....'

        if not self.dmn_collateral_tx_address_path and not self.finishing:
            lbl = ctrl.get_msg_label_control()
            if lbl:

                def set():
                    lbl.setOpenExternalLinks(False)
                    lbl.setTextInteractionFlags(lbl.textInteractionFlags()
                                                & ~Qt.TextSelectableByMouse)
                    lbl.linkActivated.connect(on_msg_link_activated)
                    lbl.repaint()

                WndUtils.call_in_main_thread(set)

            ctrl.display_msg_fun(msg)

            # fetch the transactions that involved the addresses stored in the wallet - during this
            # all the used addresses are revealed
            addr = self.bip44_wallet.scan_wallet_for_address(
                self.dmn_collateral_tx_address, check_break_scanning,
                fetch_txes_feeback)
            if not addr:
                if not break_scanning:
                    WndUtils.errorMsg(
                        f'Couldn\'t find a BIP32 path of the collateral address ({self.dmn_collateral_tx_address}).'
                    )
                return False
            else:
                self.dmn_collateral_tx_address_path = addr.bip32_path

        return True
コード例 #21
0
        def finished_with_success():
            def call():
                self.next_step()

            WndUtils.call_in_main_thread(call)