Exemple #1
0
    def setUp(self):
        transport = config.TRANSPORT(*config.TRANSPORT_ARGS,
                                     **config.TRANSPORT_KWARGS)
        if hasattr(config, 'DEBUG_TRANSPORT'):
            debug_transport = config.DEBUG_TRANSPORT(
                *config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
            self.client = KeepKeyDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = KeepKeyClient(transport)
        self.client.set_tx_api(tx_api.TxApiBitcoin)
        # self.client.set_buttonwait(3)

        #                     1      2     3    4      5      6      7     8      9    10    11    12
        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
        self.mnemonic_all = ' '.join(['all'] * 12)

        self.pin4 = '1234'
        self.pin6 = '789456'
        self.pin8 = '45678978'

        self.client.wipe_device()

        print("Setup finished")
        print("--------------")
def main():
    # List all connected KeepKeys on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No KeepKey found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating KeepKey
    client = KeepKeyClient(transport)

    # Print out KeepKey's features and settings
    print(client.features)

    # Get the first address of first BIP44 account
    # (should be the same address as shown in KeepKey wallet Chrome extension)
    bip32_path = client.expand_path("44'/0'/0'/0/0")
    address = client.get_address('Bitcoin', bip32_path)
    print('Bitcoin address:', address)

    client.close()
Exemple #3
0
def main():
    # List all connected KeepKeys on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No KeepKey found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating KeepKey
    client = KeepKeyClient(transport)

    # Print out KeepKey's features and settings
    print(client.features)

    # Get the first address of first BIP44 account
    # (should be the same address as shown in KeepKey wallet Chrome extension)
    mpath = "44'/0'/0'/0"
    bip32_path = client.expand_path(mpath)

    print bip32.serialize(client.get_public_node(bip32_path).node, 0x043587CF)

    for i in range(11):
        child_path = '%s%s' % ("44'/0'/0'/0/", str(i))
        address = client.get_address('tDash', client.expand_path(child_path))
        print 'tDASH address:', child_path, address

    client.close()
Exemple #4
0
def main():
    args = parse_args(Commands)

    if args.cmd == 'list':
        devices = list_usb()
        if args.json:
            print(json.dumps(devices))
        else:
            for dev in devices:
                if dev[1] != None:
                    print("%s - debuglink enabled" % dev[0])
                else:
                    print(dev[0])
        return

    transport = get_transport(args.transport, args.path)
    if args.verbose:
        client = KeepKeyClientDebug(transport)
    else:
        client = KeepKeyClient(transport)

    cmds = Commands(client)

    res = args.func(cmds, args)

    if args.json:
        print(json.dumps(res, sort_keys=True, indent=4))
    else:
        print(res)
Exemple #5
0
class KeepKeyClient(HardwareWalletClient):

    # device is an HID device that has already been opened.
    def __init__(self, device, path):
        super(KeepKeyClient, self).__init__(device)
        device.close()
        devices = HidTransport.enumerate()
        self.client = None
        for d in devices:
            if d[0] == path:
                transport = HidTransport(d)
                self.client = KeepKey(transport)
                break

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")

    # Must return a dict with the xpub
    # Retrieves the public key at the specified BIP 32 derivation path
    def get_pubkey_at_path(self, path):
        expanded_path = self.client.expand_path(path)
        output = self.client.get_public_node(expanded_path)
        print({'xpub':output.xpub})
        return

    # Must return a hex string with the signed transaction
    # The tx must be in the combined unsigned transaction format
    def sign_tx(self, tx):
        raise NotImplementedError('The HardwareWalletClient base class does not '
            'implement this method')

    # Must return a base64 encoded string with the signed message
    # The message can be any string
    def sign_message(self, message):
        raise NotImplementedError('The HardwareWalletClient base class does not '
            'implement this method')

    # Setup a new device
    def setup_device(self):
        raise NotImplementedError('The HardwareWalletClient base class does not '
            'implement this method')

    # Wipe this device
    def wipe_device(self):
        raise NotImplementedError('The HardwareWalletClient base class does not '
            'implement this method')
Exemple #6
0
def main():
    devices = wait_for_devices()
    transport = choose_device(devices)
    client = KeepKeyClient(transport)

    rootdir = os.environ['encfs_root']  # Read "man encfs" for more
    passw_file = os.path.join(rootdir, 'password.dat')

    if not os.path.exists(passw_file):
        # New encfs drive, let's generate password

        sys.stderr.write('Please provide label for new drive: ')
        label = input()

        sys.stderr.write('Computer asked KeepKey for new strong password.\n')
        sys.stderr.write('Please confirm action on your device.\n')

        # 32 bytes, good for AES
        keepkey_entropy = client.get_entropy(32)
        urandom_entropy = os.urandom(32)
        passw = hashlib.sha256(keepkey_entropy + urandom_entropy).digest()

        if len(passw) != 32:
            raise Exception("32 bytes password expected")

        bip32_path = [10, 0]
        passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw, False, True)

        data = {'label': label,
                'bip32_path': bip32_path,
                'password_encrypted_hex': binascii.hexlify(passw_encrypted)}

        json.dump(data, open(passw_file, 'wb'))

    # Let's load password
    data = json.load(open(passw_file, 'r'))

    sys.stderr.write('Please confirm action on your device.\n')
    passw = client.decrypt_keyvalue(data['bip32_path'],
                                    data['label'],
                                    binascii.unhexlify(data['password_encrypted_hex']),
                                    False, True)

    print(passw)
Exemple #7
0
    def __init__(self, path, password=''):
        super(KeepkeyClient, self).__init__(path, password)
        devices = HidTransport.enumerate()
        transport = HidTransport((path.encode(), None))
        self.client = KeepKey(transport)

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")

        self.password = password
        os.environ['PASSPHRASE'] = password
Exemple #8
0
def main():
    # List all connected KeepKeys on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No KeepKey found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating KeepKey
    client = KeepKeyClient(transport)

    # Print out KeepKey's features and settings
    print(client.features)

    # Get the first address of first BIP44 account
    # (should be the same address as shown in KeepKey wallet Chrome extension)
    bip32_path = client.expand_path("44'/0'/0'/0/0")
    address = client.get_address('morningstar', bip32_path)
    print('morningstar address:', address)

    client.close()
Exemple #9
0
    def __init__(self, device, path):
        super(KeepKeyClient, self).__init__(device)
        device.close()
        devices = HidTransport.enumerate()
        self.client = None
        for d in devices:
            if d[0] == path:
                transport = HidTransport(d)
                self.client = KeepKey(transport)
                break

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")
Exemple #10
0
def choose_device(devices):
    if not len(devices):
        raise Exception("No KeepKey connected!")

    if len(devices) == 1:
        try:
            return HidTransport(devices[0])
        except IOError:
            raise Exception("Device is currently in use")

    i = 0
    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Available devices:\n")
    for d in devices:
        try:
            t = HidTransport(d)
        except IOError:
            sys.stderr.write("[-] <device is currently in use>\n")
            continue

        client = KeepKeyClient(t)

        if client.features.label:
            sys.stderr.write("[%d] %s\n" % (i, client.features.label))
        else:
            sys.stderr.write("[%d] <no label>\n" % i)
        t.close()
        i += 1

    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Please choose device to use: ")

    try:
        device_id = int(input())
        return HidTransport(devices[device_id])
    except:
        raise Exception("Invalid choice, exiting...")
Exemple #11
0
         time.sleep(0.5)
         if enumerateCount == 3:
             break
         enumerateCount += 1
         continue
 if enumerateStatus is False:
     print("Enumerate hard failed, power cycling")
     continue
 print("Fetching path...")
 for d in HidTransport.enumerate():
     if path in d:
         transport = HidTransport(d)
         break
 print("Transport locked, continuing...")
 phy.set_capture_size(256)
 client = KeepKeyClient(transport)
 print("KeepKeyClient OK, arming glitcher...")
 phy.arm()
 print("Arm OK")
 try:
     signal.alarm(10)
     client.reset_device(True,
                         256,
                         False,
                         False,
                         "",
                         'english',
                         safety=False)
     data = "No exception"
     signal.alarm(0)
 except keepkeylib.client.CallException as e:
Exemple #12
0
class KeepkeyClient(HardwareWalletClient):
    def __init__(self, path, password=''):
        super(KeepkeyClient, self).__init__(path, password)
        devices = HidTransport.enumerate()
        transport = HidTransport((path.encode(), None))
        self.client = KeepKey(transport)

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")

        self.password = password
        os.environ['PASSPHRASE'] = password

    # Must return a dict with the xpub
    # Retrieves the public key at the specified BIP 32 derivation path
    def get_pubkey_at_path(self, path):
        path = path.replace('h', '\'')
        path = path.replace('H', '\'')
        expanded_path = self.client.expand_path(path)
        output = self.client.get_public_node(expanded_path)
        if self.is_testnet:
            return {'xpub': xpub_main_2_test(output.xpub)}
        else:
            return {'xpub': output.xpub}

    # Must return a hex string with the signed transaction
    # The tx must be in the combined unsigned transaction format
    def sign_tx(self, tx):

        # Get this devices master key fingerprint
        master_key = self.client.get_public_node([0])
        master_fp = get_xpub_fingerprint(master_key.xpub)

        # Prepare inputs
        inputs = []
        for psbt_in, txin in zip(tx.inputs, tx.tx.vin):
            txinputtype = proto.TxInputType()

            # Set the input stuff
            txinputtype.prev_hash = ser_uint256(txin.prevout.hash)[::-1]
            txinputtype.prev_index = txin.prevout.n
            txinputtype.sequence = txin.nSequence

            # Detrermine spend type
            if psbt_in.non_witness_utxo:
                txinputtype.script_type = 0
            elif psbt_in.witness_utxo:
                # Check if the output is p2sh
                if psbt_in.witness_utxo.is_p2sh():
                    txinputtype.script_type = 3
                else:
                    txinputtype.script_type = 4

            # Check for 1 key
            if len(psbt_in.hd_keypaths) == 1:
                # Is this key ours
                pubkey = list(psbt_in.hd_keypaths.keys())[0]
                fp = psbt_in.hd_keypaths[pubkey][0]
                keypath = psbt_in.hd_keypaths[pubkey][1:]
                if fp == master_fp:
                    # Set the keypath
                    txinputtype.address_n.extend(keypath)

            # Check for multisig (more than 1 key)
            elif len(psbt_in.hd_keypaths) > 1:
                raise TypeError("Cannot sign multisig yet")
            else:
                raise TypeError("All inputs must have a key for this device")

            # Set the amount
            if psbt_in.non_witness_utxo:
                txinputtype.amount = psbt_in.non_witness_utxo.vout[
                    txin.prevout.n].nValue
            elif psbt_in.witness_utxo:
                txinputtype.amount = psbt_in.witness_utxo.nValue

            # append to inputs
            inputs.append(txinputtype)

        # address version byte
        if self.is_testnet:
            p2pkh_version = b'\x6f'
            p2sh_version = b'\xc4'
        else:
            p2pkh_version = b'\x00'
            p2sh_version = b'\x05'

        # prepare outputs
        outputs = []
        for out in tx.tx.vout:
            txoutput = proto.TxOutputType()
            txoutput.amount = out.nValue
            if out.is_p2pkh():
                txoutput.address = to_address(out.scriptPubKey[3:23],
                                              p2pkh_version)
                txoutput.script_type = 0
            elif out.is_p2sh():
                txoutput.address = to_address(out.scriptPubKey[2:22],
                                              p2sh_version)
                txoutput.script_type = 1
            else:
                # TODO: Figure out what to do here. for now, just break
                break

            # append to outputs
            outputs.append(txoutput)
            logging.debug(txoutput)

        # Sign the transaction
        self.client.set_tx_api(TxAPIPSBT(tx))
        if self.is_testnet:
            signed_tx = self.client.sign_tx("Testnet", inputs, outputs,
                                            tx.tx.nVersion, tx.tx.nLockTime)
        else:
            signed_tx = self.client.sign_tx("Bitcoin", inputs, outputs,
                                            tx.tx.nVersion, tx.tx.nLockTime)

        signatures = signed_tx[0]
        logging.debug(binascii.hexlify(signed_tx[1]))
        for psbt_in in tx.inputs:
            for pubkey, sig in zip(psbt_in.hd_keypaths.keys(), signatures):
                fp = psbt_in.hd_keypaths[pubkey][0]
                keypath = psbt_in.hd_keypaths[pubkey][1:]
                if fp == master_fp:
                    psbt_in.partial_sigs[pubkey] = sig + b'\x01'

        return {'psbt': tx.serialize()}

    # Must return a base64 encoded string with the signed message
    # The message can be any string
    def sign_message(self, message, keypath):
        raise NotImplementedError(
            'The KeepKey does not currently implement signmessage')

    # Display address of specified type on the device. Only supports single-key based addresses.
    def display_address(self, keypath, p2sh_p2wpkh, bech32):
        raise NotImplementedError(
            'The KeepKey does not currently implement displayaddress')

    # Setup a new device
    def setup_device(self, label='', passphrase=''):
        if self.client.features.initialized:
            raise DeviceAlreadyInitError(
                'Device is already initialized. Use wipe first and try again')
        self.client.reset_device(False, 256, bool(self.password), True, label,
                                 'english')
        return {'success': True}

    # Wipe this device
    def wipe_device(self):
        self.client.wipe_device()
        return {'success': True}

    # Restore device from mnemonic or xprv
    def restore_device(self, label=''):
        self.client.recovery_device(False, 24, bool(self.password), True,
                                    label, 'english')
        return {'success': True}

    # Begin backup process
    def backup_device(self, label='', passphrase=''):
        raise UnavailableActionError(
            'The Keepkey does not support creating a backup via software')

    # Close the device
    def close(self):
        self.client.close()
Exemple #13
0
     time.sleep(0.5)
     if enumerateCount == 3:
       break
     enumerateCount += 1
     continue
 if enumerateStatus is False:
   print("Enumerate hard failed, power cycling")
   continue
 print("Fetching path...")
 for d in HidTransport.enumerate():
   if path in d:
     transport = HidTransport(d)
     break
 print("Transport locked, continuing...")
 phy.set_capture_size(1025)
 client = KeepKeyClient(transport)
 print("KeepKeyClient OK, arming glitcher...")
 scope.arm()
 phy.arm()
 print("Arm OK")
 if oneshot:
   input("Hit enter to fire glitch event...")
 try:
   signal.alarm(10)
   data = client.ping("HelloHelloHelloHelloHello")
   print(data)
   if data != "HelloHelloHelloHelloHello":
     sys.exit(0)
   data = base64.b64encode(data.encode("utf-8"))
 except:
   data = ""
Exemple #14
0
from keepkeylib.transport_hid import HidTransport
import keepkeylib.types_pb2 as proto_types
from keepkeylib import tx_api
from keepkeylib.tx_api import TXAPIDashTestnet

tx_api.rpcuser = '******'
tx_api.rpcpassword = '******'

devices = HidTransport.enumerate()

if len(devices) == 0:
    print('No KeepKey found')
    sys.exit()

transport = HidTransport(devices[0])
client = KeepKeyClient(transport)
client.set_tx_api(TXAPIDashTestnet())

inp1 = proto_types.TxInputType(
    address_n=[44 | 0x80000000, 165 | 0x80000000, 0 | 0x80000000, 0,
               0],  # yjJUQ42u8Z86s9LiUmNgvS9dSzhunWbuQR
    # amount=500000000
    prev_hash=binascii.unhexlify(
        '4a1f3f89d95dd162e30399386dd7748c7fa02ec958320f4542923cf3a63fde48'),
    prev_index=1,
)

out1 = proto_types.TxOutputType(
    address='yV7G6wcfkqfjw3SyykJzYnsL3fqJByqXYG',
    amount=500000000 - 10000,
    script_type=proto_types.PAYTOADDRESS,
def check_hw_wallet():
    printdbg('checking hw wallet')
    #client = None

    client = None
    signing = False

    if TYPE_HW_WALLET.lower().startswith("keepkey"):
        from keepkeylib.client import KeepKeyClient
        from keepkeylib.transport_hid import HidTransport
        import keepkeylib.ckd_public as bip32

        try:
            devices = HidTransport.enumerate()

        except Exception as e:
            err_msg = str(e.args)
            print_err_exit(get_caller_name(), get_function_name(), err_msg)

        if len(devices) == 0:
            print('===> No HW Wallet found')
            signing = False

        else:

            try:
                print('===> keepkey HW Wallet found')
                transport = HidTransport(devices[0])
                client = KeepKeyClient(transport)
                signing = True

            except Exception as e:
                err_msg = str(e.args)
                print_err_exit(get_caller_name(), get_function_name(), err_msg)

    elif TYPE_HW_WALLET.lower().startswith("trezor"):
        from trezorlib.client import TrezorClient
        from trezorlib.transport_hid import HidTransport
        import trezorlib.ckd_public as bip32

        try:
            devices = HidTransport.enumerate()

        except Exception as e:
            err_msg = str(e.args)
            print_err_exit(get_caller_name(), get_function_name(), err_msg)

        if len(devices) == 0:
            print('===> No HW Wallet found')
            signing = False

        else:
            try:
                print('===> trezor HW Wallet found')
                transport = HidTransport(devices[0])
                client = TrezorClient(transport)
                signing = True

            except Exception as e:
                err_msg = str(e.args)
                print_err_exit(get_caller_name(), get_function_name(), err_msg)

    elif TYPE_HW_WALLET.lower().startswith("ledgernanos"):
        #from btchip.btchip import *
        #from btchip.btchipUtils import *

        try:
            devices = getDongle(False)

        except Exception as e:
            err_msg = str(e.args)
            print_err_exit(get_caller_name(), get_function_name(), err_msg)

        if not devices:
            print('===> No HW Wallet found')
            signing = False

        else:
            try:
                print('===> Ledger nano s HW Wallet found')
                client = btchip(devices)
                signing = True

            except Exception as e:
                err_msg = str(e.args)
                print_err_exit(get_caller_name(), get_function_name(), err_msg)

    if client is not None:

        if TYPE_HW_WALLET.lower().startswith("ledgernanos"):
            pass

        else:
            try:
                wallet_supported_coins = list_coins(client)

            except Exception as e:
                err_msg = str(e.args)
                print_err_exit(get_caller_name(), get_function_name(), err_msg)

            if coin_name not in wallet_supported_coins:
                err_msg = 'only following coins supported by wallet\n\t' + \
                    str(wallet_supported_coins)
                print_err_exit(get_caller_name(), get_function_name(), err_msg)

    else:
        err_msg = "Can't run florijncoinmnb without hw wallet"
        print_err_exit(get_caller_name(), get_function_name(), err_msg)

    if TYPE_HW_WALLET.lower().startswith("ledgernanos"):
        mpath = get_mpath()

        return client, signing, mpath

    else:
        try:
            mpath = get_mpath()
            bip32_path = client.expand_path(mpath)
            xpub = bip32.serialize(
                client.get_public_node(bip32_path).node,
                (0x0488B21E if MAINNET else 0x043587CF))

        except AssertionError as e:
            err_msg = str(e.args)
            print_err_exit(get_caller_name(), get_function_name(), err_msg)

        except Exception as e:
            err_msg = str(e.args)
            print_err_exit(get_caller_name(), get_function_name(), err_msg)

        except KeyboardInterrupt:
            print_err_exit(get_caller_name(), get_function_name(),
                           "KeyboardInterrupt")

    printdbg('check_hw_wallet : signing : %s' % signing)
    printdbg('check_hw_wallet : xpub[:7] : %s' % xpub[:7])
    printdbg('check_hw_wallet : xpub[-7:] : %s' % xpub[-7:])
    printdbg('check_hw_wallet : mpath : %s' % mpath)

    return client, signing, bip32, mpath, xpub
Exemple #16
0
class KeepKeyTest(unittest.TestCase):
    def setUp(self):
        transport = config.TRANSPORT(*config.TRANSPORT_ARGS,
                                     **config.TRANSPORT_KWARGS)
        if hasattr(config, 'DEBUG_TRANSPORT'):
            debug_transport = config.DEBUG_TRANSPORT(
                *config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
            self.client = KeepKeyDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = KeepKeyClient(transport)
        self.client.set_tx_api(tx_api.TxApiBitcoin)
        # self.client.set_buttonwait(3)

        #                     1      2     3    4      5      6      7     8      9    10    11    12
        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
        self.mnemonic_all = ' '.join(['all'] * 12)
        self.mnemonic_abandon = ' '.join(['abandon'] * 11) + ' about'

        self.pin4 = '1234'
        self.pin6 = '789456'
        self.pin8 = '45678978'

        self.client.wipe_device()

        print("Setup finished")
        print("--------------")

    def setup_mnemonic_allallall(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic_all,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_abandon(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic_abandon,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_nopin_nopassphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_pin_nopassphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin=self.pin4,
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_pin_passphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin=self.pin4,
                                            passphrase_protection=True,
                                            label='test',
                                            language='english')

    def tearDown(self):
        self.client.close()

    def assertEndsWith(self, s, suffix):
        self.assertTrue(s.endswith(suffix),
                        "'{}'.endswith('{}')".format(s, suffix))
Exemple #17
0
class KeepKeyTest(unittest.TestCase):
    def setUp(self):
        transport = config.TRANSPORT(*config.TRANSPORT_ARGS,
                                     **config.TRANSPORT_KWARGS)
        if hasattr(config, 'DEBUG_TRANSPORT'):
            debug_transport = config.DEBUG_TRANSPORT(
                *config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
            if VERBOSE:
                self.client = KeepKeyDebuglinkClientVerbose(transport)
            else:
                self.client = KeepKeyDebuglinkClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = KeepKeyClient(transport)
        self.client.set_tx_api(tx_api.TxApiBitcoin)
        # self.client.set_buttonwait(3)

        #                     1      2     3    4      5      6      7     8      9    10    11    12
        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
        self.mnemonic20007 = 'fix spot clown mobile oven eagle pond arrest opera buyer muffin myself'
        self.mnemonic_all = ' '.join(['all'] * 12)
        self.mnemonic_abandon = ' '.join(['abandon'] * 11) + ' about'

        self.pin4 = '1234'
        self.pin6 = '789456'
        self.pin8 = '45678978'

        self.client.wipe_device()

        if VERBOSE:
            print("Setup finished")
            print("--------------")

    def setup_mnemonic_allallall(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic_all,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_abandon(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic_abandon,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_nopin_nopassphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_vuln20007(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic20007,
                                            pin='',
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_pin_nopassphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin=self.pin4,
                                            passphrase_protection=False,
                                            label='test',
                                            language='english')

    def setup_mnemonic_pin_passphrase(self):
        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12,
                                            pin=self.pin4,
                                            passphrase_protection=True,
                                            label='test',
                                            language='english')

    def tearDown(self):
        self.client.close()

    def assertEqual(self, lhs, rhs):
        if type(lhs) == type(b'') and type(rhs) == type(''):
            super(KeepKeyTest, self).assertEqual(lhs, rhs.encode('utf-8'))
        else:
            super(KeepKeyTest, self).assertEqual(lhs, rhs)

    def assertEndsWith(self, s, suffix):
        self.assertTrue(s.endswith(suffix),
                        "'{}'.endswith('{}')".format(s, suffix))

    def requires_firmware(self, ver_required):
        self.client.init_device()
        features = self.client.features
        version = "%s.%s.%s" % (features.major_version, features.minor_version,
                                features.patch_version)
        if semver.compare(version, ver_required) < 0:
            self.skipTest("Firmware version " + ver_required +
                          " or higher is required to run this test")