<commit_before>import base64
import re
import threading

from binascii import hexlify, unhexlify
from functools import partial

from electrum.bitcoin import (bc_address_to_hash_160, xpub_from_pubkey,
                              public_key_to_p2pkh, EncodeBase58Check,
                              TYPE_ADDRESS, TYPE_SCRIPT,
                              TESTNET, ADDRTYPE_P2PKH, ADDRTYPE_P2SH)
from electrum.i18n import _
from electrum.plugins import BasePlugin, hook
from electrum.transaction import deserialize, Transaction
from electrum.keystore import Hardware_KeyStore, is_xpubkey, parse_xpubkey

from ..hw_wallet import HW_PluginBase


# TREZOR initialization methods
TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4)

class TrezorCompatibleKeyStore(Hardware_KeyStore):

    def get_derivation(self):
        return self.derivation

    def get_client(self, force_pair=True):
        return self.plugin.get_client(self, force_pair)

    def decrypt_message(self, sequence, message, password):
        raise RuntimeError(_('Electrum and %s encryption and decryption are currently incompatible') % self.device)
        client = self.get_client()
        address_path = self.get_derivation() + "/%d/%d"%sequence
        address_n = client.expand_path(address_path)
        payload = base64.b64decode(message)
        nonce, message, msg_hmac = payload[:33], payload[33:-8], payload[-8:]
        result = client.decrypt_message(address_n, nonce, message, msg_hmac)
        return result.message

    def sign_message(self, sequence, message, password):
        client = self.get_client()
        address_path = self.get_derivation() + "/%d/%d"%sequence
        address_n = client.expand_path(address_path)
        msg_sig = client.sign_message(self.plugin.get_coin_name(), address_n, message)
        return msg_sig.signature

    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        # previous transactions used as inputs
        prev_tx = {}
        # path of the xpubs that are involved
        xpub_path = {}
        for txin in tx.inputs():
            pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin)
            tx_hash = txin['prevout_hash']
            prev_tx[tx_hash] = txin['prev_tx'] 
            for x_pubkey in x_pubkeys:
                if not is_xpubkey(x_pubkey):
                    continue
                xpub, s = parse_xpubkey(x_pubkey)
                if xpub == self.get_master_public_key():
                    xpub_path[xpub] = self.get_derivation()

        self.plugin.sign_transaction(self, tx, prev_tx, xpub_path)


class TrezorCompatiblePlugin(HW_PluginBase):
    # Derived classes provide:
    #
    #  class-static variables: client_class, firmware_URL, handler_class,
    #     libraries_available, libraries_URL, minimum_firmware,
    #     wallet_class, ckd_public, types, HidTransport

    MAX_LABEL_LEN = 32

    def __init__(self, parent, config, name):
        HW_PluginBase.__init__(self, parent, config, name)
        self.main_thread = threading.current_thread()
        # FIXME: move to base class when Ledger is fixed
        if self.libraries_available:
            self.device_manager().register_devices(self.DEVICE_IDS)

    def _try_hid(self, device):
        self.print_error("Trying to connect over USB...")
        if device.interface_number == 1:
            pair = [None, device.path]
        else:
            pair = [device.path, None]

        try:
            return self.hid_transport(pair)
        except BaseException as e:
            raise
            self.print_error("cannot connect at", device.path, str(e))
            return None
 
    def _try_bridge(self, device):
        self.print_error("Trying to connect over Trezor Bridge...")
        try:
            return self.bridge_transport({'path': hexlify(device.path)})
        except BaseException as e:
            self.print_error("cannot connect to bridge", str(e))
            return None

    def create_client(self, device, handler):
        # disable bridge because it seems to never returns if keepkey is plugged
        #transport = self._try_bridge(device) or self._try_hid(device)
        transport = self._try_hid(device)
        if not transport:
            self.print_error("cannot connect to device")
            return

        self.print_error("connected to device at", device.path)

        client = self.client_class(transport, handler, self)

        # Try a ping for device sanity
        try:
            client.ping('t')
        except BaseException as e:
            self.print_error("ping failed", str(e))
            return None<commit_msg>comment out raise trezor plugin<commit_after>import base64
import re
import threading

from binascii import hexlify, unhexlify
from functools import partial

from electrum.bitcoin import (bc_address_to_hash_160, xpub_from_pubkey,
                              public_key_to_p2pkh, EncodeBase58Check,
                              TYPE_ADDRESS, TYPE_SCRIPT,
                              TESTNET, ADDRTYPE_P2PKH, ADDRTYPE_P2SH)
from electrum.i18n import _
from electrum.plugins import BasePlugin, hook
from electrum.transaction import deserialize, Transaction
from electrum.keystore import Hardware_KeyStore, is_xpubkey, parse_xpubkey

from ..hw_wallet import HW_PluginBase


# TREZOR initialization methods
TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4)

class TrezorCompatibleKeyStore(Hardware_KeyStore):

    def get_derivation(self):
        return self.derivation

    def get_client(self, force_pair=True):
        return self.plugin.get_client(self, force_pair)

    def decrypt_message(self, sequence, message, password):
        raise RuntimeError(_('Electrum and %s encryption and decryption are currently incompatible') % self.device)
        client = self.get_client()
        address_path = self.get_derivation() + "/%d/%d"%sequence
        address_n = client.expand_path(address_path)
        payload = base64.b64decode(message)
        nonce, message, msg_hmac = payload[:33], payload[33:-8], payload[-8:]
        result = client.decrypt_message(address_n, nonce, message, msg_hmac)
        return result.message

    def sign_message(self, sequence, message, password):
        client = self.get_client()
        address_path = self.get_derivation() + "/%d/%d"%sequence
        address_n = client.expand_path(address_path)
        msg_sig = client.sign_message(self.plugin.get_coin_name(), address_n, message)
        return msg_sig.signature

    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        # previous transactions used as inputs
        prev_tx = {}
        # path of the xpubs that are involved
        xpub_path = {}
        for txin in tx.inputs():
            pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin)
            tx_hash = txin['prevout_hash']
            prev_tx[tx_hash] = txin['prev_tx'] 
            for x_pubkey in x_pubkeys:
                if not is_xpubkey(x_pubkey):
                    continue
                xpub, s = parse_xpubkey(x_pubkey)
                if xpub == self.get_master_public_key():
                    xpub_path[xpub] = self.get_derivation()

        self.plugin.sign_transaction(self, tx, prev_tx, xpub_path)


class TrezorCompatiblePlugin(HW_PluginBase):
    # Derived classes provide:
    #
    #  class-static variables: client_class, firmware_URL, handler_class,
    #     libraries_available, libraries_URL, minimum_firmware,
    #     wallet_class, ckd_public, types, HidTransport

    MAX_LABEL_LEN = 32

    def __init__(self, parent, config, name):
        HW_PluginBase.__init__(self, parent, config, name)
        self.main_thread = threading.current_thread()
        # FIXME: move to base class when Ledger is fixed
        if self.libraries_available:
            self.device_manager().register_devices(self.DEVICE_IDS)

    def _try_hid(self, device):
        self.print_error("Trying to connect over USB...")
        if device.interface_number == 1:
            pair = [None, device.path]
        else:
            pair = [device.path, None]

        try:
            return self.hid_transport(pair)
        except BaseException as e:
            # see fdb810ba622dc7dbe1259cbafb5b28e19d2ab114
            # raise
            self.print_error("cannot connect at", device.path, str(e))
            return None
 
    def _try_bridge(self, device):
        self.print_error("Trying to connect over Trezor Bridge...")
        try:
            return self.bridge_transport({'path': hexlify(device.path)})
        except BaseException as e:
            self.print_error("cannot connect to bridge", str(e))
            return None

    def create_client(self, device, handler):
        # disable bridge because it seems to never returns if keepkey is plugged
        #transport = self._try_bridge(device) or self._try_hid(device)
        transport = self._try_hid(device)
        if not transport:
            self.print_error("cannot connect to device")
            return

        self.print_error("connected to device at", device.path)

        client = self.client_class(transport, handler, self)

        # Try a ping for device sanity
        try:
            client.ping('t')
        except BaseException as e:
            self.print_error("ping failed", str(e))
            return None
{'fraction_non_alphanumeric': 0.08378637671889991, 'fraction_numerical': 0.007888284831041467, 'mean_word_length': 2.568657284138456, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1518061', 'n_tokens_mistral': 2823, 'n_tokens_neox': 2710, 'n_words': 673}