Example #1
0
def get_xpub(hw_session: HwSessionInfo, bip32_path):
    client = hw_session.hw_client
    if client:
        if isinstance(bip32_path, str):
            bip32_path.strip()
            if bip32_path.lower().find('m/') >= 0:
                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 = stash_utils.bip32_path_string_to_n(bip32_path)

            return btc.get_public_node(client, bip32_path).xpub

        elif hw_session.app_config.hw_type == HWType.keepkey:
            if isinstance(bip32_path, str):
                bip32_path = stash_utils.bip32_path_string_to_n(bip32_path)

            return client.get_public_node(bip32_path).xpub

        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)

            return ledger.get_xpub(client, bip32_path)
        else:
            raise Exception('Unknown hardware wallet type: ' +
                            hw_session.app_config.hw_type)
    else:
        raise Exception('HW client not open.')
Example #2
0
def sign_message(hw_session: HwSessionInfo, bip32path, message):
    client = hw_session.hw_client
    address_n = stash_utils.bip32_path_string_to_n(bip32path)
    try:
        return btc.sign_message(client, hw_session.app_config.hw_coin_name, address_n, message)
    except exceptions.Cancelled:
        raise CancelException('Cancelled')
Example #3
0
    def get_session_info_trezor(get_public_node_fun, hw_session: HwSessionInfo,
                                hw_client):
        nonlocal hw_type

        def call_get_public_node(ctrl, get_public_node_fun, path_n):
            pk = get_public_node_fun(path_n).node.public_key
            return pk

        path = stash_utils.get_default_bip32_base_path(
            hw_session.app_config.stash_network)
        path_n = stash_utils.bip32_path_string_to_n(path)

        # show message for Trezor T device while waiting for the user to choose the passphrase input method
        pub = WndUtils.run_thread_dialog(call_get_public_node,
                                         (get_public_node_fun, path_n),
                                         title=DEFAULT_HW_BUSY_TITLE,
                                         text=DEFAULT_HW_BUSY_MESSAGE,
                                         force_close_dlg_callback=partial(
                                             cancel_hw_thread_dialog,
                                             hw_client),
                                         show_window_delay_ms=1000)

        if pub:
            hw_session.set_base_info(path, pub)
        else:
            raise Exception('Couldn\'t read data from the hardware wallet.')
Example #4
0
 def set_bip32_path(self, path):
     Bip44Entry.set_bip32_path(self, path)
     if path:
         path_n = bip32_path_string_to_n(path)
         if path_n[-2] == 1:
             self.__is_change = True
         else:
             self.__is_change = False
Example #5
0
def get_address_and_pubkey(hw_session: HwSessionInfo, bip32_path):
    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 = stash_utils.bip32_path_string_to_n(bip32_path)
            return {
                'address':
                btc.get_address(client, hw_session.app_config.hw_coin_name,
                                bip32_path, False),
                'publicKey':
                btc.get_public_node(client, bip32_path).node.public_key
            }

        elif hw_session.app_config.hw_type == HWType.keepkey:
            if isinstance(bip32_path, str):
                bip32_path = stash_utils.bip32_path_string_to_n(bip32_path)
            return {
                'address':
                client.get_address(hw_session.app_config.hw_coin_name,
                                   bip32_path, False),
                'publicKey':
                client.get_public_node(bip32_path).node.public_key
            }

        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)

            return ledger.get_address_and_pubkey(client, bip32_path)
        else:
            raise Exception('Unknown hardware wallet type: ' +
                            hw_session.app_config.hw_type)
Example #6
0
    def get_child_entry(self, index) -> 'Bip44Entry':
        child = self.child_entries.get(index)
        if not child:
            key = self.get_bip32key()
            child_key = key.ChildKey(index)
            child_xpub = child_key.ExtendedKey(False, True)
            if self.bip32_path:
                bip32_path_n = bip32_path_string_to_n(self.bip32_path)
                bip32_path_n.append(index)
                bip32_path = bip32_path_n_to_string(bip32_path_n)
            else:
                raise Exception('Unknown BIP32 path of the parrent')

            child = Bip44Entry(tree_id=self.tree_id, id=None, parent=self, xpub=child_xpub, address_index=index,
                               bip32_path=bip32_path, bip32_key=child_key)
            self.child_entries[index] = child
        return child
Example #7
0
def sign_tx(hw_session: HwSessionInfo, utxos_to_spend: List[wallet_common.UtxoType],
            tx_outputs: List[wallet_common.TxOutputType], tx_fee):
    """
    Creates a signed transaction.
    :param hw_session:
    :param utxos_to_spend: list of utxos to send
    :param tx_outputs: list of transaction outputs
    :param tx_fee: transaction fee
    :return: tuple (serialized tx, total transaction amount in satoshis)
    """
    def load_prev_txes(tx_api, skip_cache: bool = False):
        txes = {}
        tx_api.skip_cache = skip_cache
        for utxo in utxos_to_spend:
            prev_hash = bytes.fromhex(utxo.txid)
            if prev_hash not in txes:
                tx = tx_api[prev_hash]
                txes[prev_hash] = tx
        return txes

    insight_network = 'insight_stash'
    if hw_session.app_config.is_testnet():
        insight_network += '_testnet'
    stash_network = hw_session.app_config.stash_network

    c_name = hw_session.app_config.hw_coin_name
    coin = coins.by_name[c_name]
    url = hw_session.app_config.get_tx_api_url()
    coin['bitcore'].clear()
    coin['bitcore'].append(url)

    tx_api = MyTxApiInsight(coin, '', hw_session.stashd_intf, hw_session.app_config.tx_cache_dir)
    client = hw_session.hw_client
    inputs = []
    outputs = []
    inputs_amount = 0
    for utxo_index, utxo in enumerate(utxos_to_spend):
        if not utxo.bip32_path:
            raise Exception('No BIP32 path for UTXO ' + utxo.txid)

        address_n = stash_utils.bip32_path_string_to_n(utxo.bip32_path)
        it = trezor_proto.TxInputType(
            address_n=address_n,
            prev_hash=binascii.unhexlify(utxo.txid),
            prev_index=int(utxo.output_index))

        inputs.append(it)
        inputs_amount += utxo.satoshis

    outputs_amount = 0
    for out in tx_outputs:
        outputs_amount += out.satoshis
        if out.address[0] in stash_utils.get_chain_params(stash_network).B58_PREFIXES_SCRIPT_ADDRESS:
            stype = trezor_proto.OutputScriptType.PAYTOSCRIPTHASH
            logging.debug('Transaction type: PAYTOSCRIPTHASH' + str(stype))
        elif out.address[0] in stash_utils.get_chain_params(stash_network).B58_PREFIXES_PUBKEY_ADDRESS:
            stype = trezor_proto.OutputScriptType.PAYTOADDRESS
            logging.debug('Transaction type: PAYTOADDRESS ' + str(stype))
        else:
            raise Exception('Invalid prefix of the destination address.')
        if out.bip32_path:
            address_n = stash_utils.bip32_path_string_to_n(out.bip32_path)
        else:
            address_n = None

        ot = trezor_proto.TxOutputType(
            address=out.address if address_n is None else None,
            address_n=address_n,
            amount=out.satoshis,
            script_type=stype
        )
        outputs.append(ot)

    if outputs_amount + tx_fee != inputs_amount:
        raise Exception('Transaction validation failure: inputs + fee != outputs')

    try:
        for skip_cache in (False, True):
            txes = load_prev_txes(tx_api, skip_cache)
            try:
                signed = btc.sign_tx(client, hw_session.app_config.hw_coin_name, inputs, outputs, prev_txes=txes)
                return signed[1], inputs_amount
            except exceptions.Cancelled:
                raise
            except Exception as e:
                if skip_cache:
                    raise
                log.exception('Exception occurred while signing transaction. Turning off the transaction cache '
                              'and retrying...')
        raise Exception('Internal error: transaction not signed')
    except exceptions.Cancelled:
        raise CancelException('Cancelled')
Example #8
0
    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=DEFAULT_HW_BUSY_TITLE,
                                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
                from trezorlib import exceptions

                try:
                    if isinstance(bip32_path, str):
                        bip32_path = stash_utils.bip32_path_string_to_n(
                            bip32_path)
                    ret = btc.get_address(client,
                                          hw_session.app_config.hw_coin_name,
                                          bip32_path, show_display)
                    return ret
                except (CancelException, exceptions.Cancelled):
                    raise CancelException()

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

                from keepkeylib.client import CallException

                try:
                    if isinstance(bip32_path, str):
                        bip32_path = stash_utils.bip32_path_string_to_n(
                            bip32_path)
                    return client.get_address(
                        hw_session.app_config.hw_coin_name, bip32_path,
                        show_display)
                except CallException as e:
                    if isinstance(e.args, tuple) and len(e.args) >= 2 and isinstance(e.args[1], str) and \
                            e.args[1].find('cancel') >= 0:
                        raise CancelException('Cancelled')

            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, show_display)
                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.')