Esempio n. 1
0
def decrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    dec = decrypt_keyvalue(client, BIP32_PATH, dom, secret, False, True)
    client.close()
    return dec
Esempio n. 2
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

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

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)

    # Print out TREZOR's features and settings
    print client.features

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

    client.close()
Esempio n. 3
0
def choose_device(devices):
    if not len(devices):
        raise RuntimeError("No Trezor connected!")

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

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

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

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

    try:
        device_id = int(input())
        return devices[device_id]
    except Exception:
        raise ValueError("Invalid choice, exiting...")
Esempio n. 4
0
def encrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    enc = encrypt_keyvalue(client, BIP32_PATH, dom, secret.encode(), False, True)
    client.close()
    return enc.hex()
Esempio n. 5
0
def main():
    try:
        # List all connected TREZORs on USB
        devices = HidTransport.enumerate()

        # Check whether we found any
        if len(devices) == 0:
            input('No TREZOR found. Press any key...')
            return

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

        # Creates object for manipulating TREZOR
        client = TrezorClient(transport)

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

        # # Get the first address of first BIP44 account
        # # (should be the same address as shown in wallet.trezor.io)
        bip32_path = client.expand_path("m/44'/49344'/0'/0/0")
        address = client.get_address('Stash', bip32_path)
        print('Stash address:', address)

        client.close()
    except Exception as e:
        print(str(e))
        traceback.print_exc(file=sys.stdout)
        input('Press any key...')
Esempio n. 6
0
def main():
    # List all debuggable TREZORs
    devices = [
        device for device in enumerate_devices()
        if hasattr(device, 'find_debug')
    ]

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

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    sector = int(sys.argv[1])
    f = open(sys.argv[2], "rb")
    content = f.read(sectorlens[sector])
    if (len(content) != sectorlens[sector]):
        print("Not enough bytes in file")
        return

    debug.flash_erase(sector)
    step = 0x400
    for offset in range(0, sectorlens[sector], step):
        debug.memory_write(sectoraddrs[sector] + offset,
                           content[offset:offset + step],
                           flash=True)
    client.close()
Esempio n. 7
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    arg1 = int(sys.argv[1], 16)
    arg2 = int(sys.argv[2], 16)
    step = 0x400 if arg2 >= 0x400 else arg2

    f = open('memory.dat', 'w')

    for addr in range(arg1, arg1 + arg2, step):
        mem = debug.memory_read(addr, step)
        f.write(mem)

    f.close()

    client.close()
Esempio n. 8
0
def choose_device(devices):
    if not len(devices):
        raise RuntimeError("No TREZOR connected!")

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

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

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

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

    try:
        device_id = int(input())
        return devices[device_id]
    except Exception:
        raise ValueError("Invalid choice, exiting...")
Esempio n. 9
0
def main():
    # List all connected TREZORs on USB/UDP
    devices = TrezorDevice.enumerate()

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

    # Use first connected device
    transport = devices[0]

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)

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

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

    client.close()
Esempio n. 10
0
class TrezorTest(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 = TrezorDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = TrezorClient(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 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_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()
Esempio n. 11
0
def encrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    enc = encrypt_keyvalue(client, BIP32_PATH, dom, secret.encode(), False,
                           True)
    client.close()
    return enc.hex()
Esempio n. 12
0
def main():
    try:
        client = TrezorClient(get_transport())
    except Exception as e:
        print(e)
        return

    arg1 = sys.argv[1]                     # output file
    arg2 = int(sys.argv[2], 10)            # total number of how many bytes of entropy to read
    step = 1024 if arg2 >= 1024 else arg2  # trezor will only return 1KB at a time

    with io.open(arg1, 'wb') as f:
        for i in range(0, arg2, step):
            entropy = client.get_entropy(step)
            f.write(entropy)

    client.close()
def main():
    try:
        client = TrezorClient(get_transport(), ui=ui.ClickUI())
    except Exception as e:
        print(e)
        return

    arg1 = sys.argv[1]                     # output file
    arg2 = int(sys.argv[2], 10)            # total number of how many bytes of entropy to read
    step = 1024 if arg2 >= 1024 else arg2  # trezor will only return 1KB at a time

    with io.open(arg1, 'wb') as f:
        for i in range(0, arg2, step):
            entropy = misc.get_entropy(client, step)
            f.write(entropy)

    client.close()
Esempio n. 14
0
def main():
    # Use first connected device
    transport = get_transport()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)

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

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

    client.close()
Esempio n. 15
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    debug.memory_write(int(sys.argv[1], 16), binascii.unhexlify(sys.argv[2]), flash=True)
    client.close()
Esempio n. 16
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

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

    # Creates object for manipulating TREZOR
    debug_transport = HidTransport(devices[0], **{'debug_link': True})
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    mem = debug.memory_write(int(sys.argv[1],16), binascii.unhexlify(sys.argv[2]), flash=True)
    client.close()
Esempio n. 17
0
class TrezorTest(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 = TrezorDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = TrezorClient(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 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_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()
Esempio n. 18
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

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

    # Creates object for manipulating TREZOR
    debug_transport = HidTransport(devices[0], **{'debug_link': True})
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    mem = debug.memory_read(int(sys.argv[1],16), int(sys.argv[2],16))
    f = open('memory.dat', 'w')
    f.write(mem)
    f.close()

    client.close()
Esempio n. 19
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

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

    # Creates object for manipulating TREZOR
    debug_transport = HidTransport(devices[0], **{'debug_link': True})
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    mem = debug.memory_read(int(sys.argv[1], 16), int(sys.argv[2], 16))
    f = open('memory.dat', 'w')
    f.write(mem)
    f.close()

    client.close()
Esempio n. 20
0
def main():
    # List all debuggable TREZORs
    devices = [
        device for device in enumerate_devices()
        if hasattr(device, 'find_debug')
    ]

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

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    debug.memory_write(int(sys.argv[1], 16),
                       bytes.fromhex(sys.argv[2]),
                       flash=True)
    client.close()
Esempio n. 21
0
devices = HidTransport.enumerate()
# Check whether we found any
if len(devices) == 0:
    print('No TREZOR found')
    sys.exit()
# Use first connected device

transport = devices[0]
# Creates object for manipulating TREZOR
client = TrezorClient(transport)

adrs = []
for i in tqdm(range(ADRS_TOTAL)):
    bip32_path = client.expand_path("49'/2'/0'/0/{0}".format(i))
    adrs.append(
        client.get_address('Litecoin',
                           bip32_path,
                           script_type=proto.InputScriptType.SPENDP2SHWITNESS))
client.close()
#print(adrs)
pickle.dump(adrs, open('LTC.pickle', 'wb'))

# SPENDWITNESS
# SPENDP2SHWITNESS
# SAMPLE ADR: MKVW8NewajMWijvKg7td2e7aUq8cyFYtPB

# (trezorfeb) sbassi@Us-IT00354:~/projects/takocoin/takomisc/trezorfeb$ trezorctl get_address --coin Bitcoin --script-type segwit --address "m/49'/0'/0'/0/0"
# bc1qrwl055767s26920eq7tfpaa4m97m302cnkh6w4
#
Esempio n. 22
0
class TrezorClient(HardwareWalletClient):
    def __init__(self, path, password=''):
        super(TrezorClient, self).__init__(path, password)
        if path.startswith('udp'):
            logging.debug('Simulator found, using DebugLink')
            transport = get_transport(path)
            self.client = TrezorClientDebugLink(transport=transport)
        else:
            self.client = Trezor(transport=get_transport(path), ui=ClickUI())

        # 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):
        expanded_path = tools.parse_path(path)
        output = btc.get_public_node(self.client, 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 psbt format
    def sign_tx(self, tx):

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

        # Do multiple passes for multisig
        passes = 1
        p = 0

        while p < passes:
            # Prepare inputs
            inputs = []
            to_ignore = [
            ]  # Note down which inputs whose signatures we're going to ignore
            for input_num, (psbt_in, txin) in py_enumerate(
                    list(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
                scriptcode = b''
                if psbt_in.non_witness_utxo:
                    utxo = psbt_in.non_witness_utxo.vout[txin.prevout.n]
                    txinputtype.script_type = proto.InputScriptType.SPENDADDRESS
                    scriptcode = utxo.scriptPubKey
                    txinputtype.amount = psbt_in.non_witness_utxo.vout[
                        txin.prevout.n].nValue
                elif psbt_in.witness_utxo:
                    utxo = psbt_in.witness_utxo
                    # Check if the output is p2sh
                    if psbt_in.witness_utxo.is_p2sh():
                        txinputtype.script_type = proto.InputScriptType.SPENDP2SHWITNESS
                    else:
                        txinputtype.script_type = proto.InputScriptType.SPENDWITNESS
                    scriptcode = psbt_in.witness_utxo.scriptPubKey
                    txinputtype.amount = psbt_in.witness_utxo.nValue

                # Set the script
                if psbt_in.witness_script:
                    scriptcode = psbt_in.witness_script
                elif psbt_in.redeem_script:
                    scriptcode = psbt_in.redeem_script

                def ignore_input():
                    txinputtype.address_n = [0x80000000]
                    inputs.append(txinputtype)
                    to_ignore.append(input_num)

                # Check for multisig
                is_ms, multisig = parse_multisig(scriptcode)
                if is_ms:
                    # Add to txinputtype
                    txinputtype.multisig = multisig
                    if psbt_in.non_witness_utxo:
                        if utxo.is_p2sh:
                            txinputtype.script_type = proto.InputScriptType.SPENDMULTISIG
                        else:
                            # Cannot sign bare multisig, ignore it
                            ignore_input()
                            continue
                elif not is_ms and psbt_in.non_witness_utxo and not utxo.is_p2pkh:
                    # Cannot sign unknown spk, ignore it
                    ignore_input()
                    continue
                elif not is_ms and psbt_in.witness_utxo and psbt_in.witness_script:
                    # Cannot sign unknown witness script, ignore it
                    ignore_input()
                    continue

                # Find key to sign with
                found = False
                our_keys = 0
                for key in psbt_in.hd_keypaths.keys():
                    keypath = psbt_in.hd_keypaths[key]
                    if keypath[
                            0] == master_fp and key not in psbt_in.partial_sigs:
                        if not found:
                            txinputtype.address_n = keypath[1:]
                            found = True
                        our_keys += 1

                # Determine if we need to do more passes to sign everything
                if our_keys > passes:
                    passes = our_keys

                if not found:
                    # This input is not one of ours
                    ignore_input()
                    continue

                # append to inputs
                inputs.append(txinputtype)

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

            # prepare outputs
            outputs = []
            for out in tx.tx.vout:
                txoutput = proto.TxOutputType()
                txoutput.amount = out.nValue
                txoutput.script_type = proto.OutputScriptType.PAYTOADDRESS
                if out.is_p2pkh():
                    txoutput.address = to_address(out.scriptPubKey[3:23],
                                                  p2pkh_version)
                elif out.is_p2sh():
                    txoutput.address = to_address(out.scriptPubKey[2:22],
                                                  p2sh_version)
                else:
                    wit, ver, prog = out.is_witness()
                    if wit:
                        txoutput.address = bech32.encode(bech32_hrp, ver, prog)
                    else:
                        raise TypeError("Output is not an address")

                # append to outputs
                outputs.append(txoutput)

            # Prepare prev txs
            prevtxs = {}
            for psbt_in in tx.inputs:
                if psbt_in.non_witness_utxo:
                    prev = psbt_in.non_witness_utxo

                    t = proto.TransactionType()
                    t.version = prev.nVersion
                    t.lock_time = prev.nLockTime

                    for vin in prev.vin:
                        i = proto.TxInputType()
                        i.prev_hash = ser_uint256(vin.prevout.hash)[::-1]
                        i.prev_index = vin.prevout.n
                        i.script_sig = vin.scriptSig
                        i.sequence = vin.nSequence
                        t.inputs.append(i)

                    for vout in prev.vout:
                        o = proto.TxOutputBinType()
                        o.amount = vout.nValue
                        o.script_pubkey = vout.scriptPubKey
                        t.bin_outputs.append(o)
                    logging.debug(psbt_in.non_witness_utxo.hash)
                    prevtxs[ser_uint256(
                        psbt_in.non_witness_utxo.sha256)[::-1]] = t

            # Sign the transaction
            tx_details = proto.SignTx()
            tx_details.version = tx.tx.nVersion
            tx_details.lock_time = tx.tx.nLockTime
            if self.is_testnet:
                signed_tx = btc.sign_tx(self.client, "Testnet", inputs,
                                        outputs, tx_details, prevtxs)
            else:
                signed_tx = btc.sign_tx(self.client, "Bitcoin", inputs,
                                        outputs, tx_details, prevtxs)

            # Each input has one signature
            for input_num, (psbt_in, sig) in py_enumerate(
                    list(zip(tx.inputs, signed_tx[0]))):
                if input_num in to_ignore:
                    continue
                for pubkey in psbt_in.hd_keypaths.keys():
                    fp = psbt_in.hd_keypaths[pubkey][0]
                    if fp == master_fp and pubkey not in psbt_in.partial_sigs:
                        psbt_in.partial_sigs[pubkey] = sig + b'\x01'
                        break

            p += 1

        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):
        path = tools.parse_path(keypath)
        result = btc.sign_message(self.client, 'Bitcoin', path, message)
        return {
            'signature': base64.b64encode(result.signature).decode('utf-8')
        }

    # Display address of specified type on the device. Only supports single-key based addresses.
    def display_address(self, keypath, p2sh_p2wpkh, bech32):
        expanded_path = tools.parse_path(keypath)
        address = btc.get_address(
            self.client,
            "Testnet" if self.is_testnet else "Bitcoin",
            expanded_path,
            show_display=True,
            script_type=proto.InputScriptType.SPENDWITNESS if bech32 else
            (proto.InputScriptType.SPENDP2SHWITNESS
             if p2sh_p2wpkh else proto.InputScriptType.SPENDADDRESS))
        return {'address': address}

    # 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')
        passphrase_enabled = False
        if self.password:
            passphrase_enabled = True
        device.reset(self.client, passphrase_protection=bool(self.password))
        return {'success': True}

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

    # Restore device from mnemonic or xprv
    def restore_device(self, label=''):
        passphrase_enabled = False
        device.recover(self.client,
                       label=label,
                       input_callback=mnemonic_words,
                       passphrase_protection=bool(self.password))
        return {'success': True}

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

    # Close the device
    def close(self):
        self.client.close()
Esempio n. 23
0
def main():
    numinputs = 100
    sizeinputtx = 10

    # Use first connected device
    try:
        transport = get_transport()
    except Exception as e:
        print(e)
        return

    print(transport)

    txstore = MyTxApiBitcoin()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    # client.set_tx_api(TxApiTestnet)
    txstore.set_client(client)
    txstore.set_publickey(
        client.get_public_node(client.expand_path("44'/0'/0'")))
    print("creating input txs")
    txstore.create_inputs(numinputs, sizeinputtx)
    print("go")
    client.set_tx_api(txstore)
    # client.set_tx_api(MyTxApiBitcoin())

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

    # Get the first address of first BIP44 account
    # (should be the same address as shown in wallet.trezor.io)

    outputs = [
        proto_types.TxOutputType(
            amount=0,
            script_type=proto_types.PAYTOADDRESS,
            address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm'
            # op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
            # address_n=client.expand_path("44'/0'/0'/0/35"),
            # address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj',
        ),
        # proto_types.TxOutputType(
        #     amount=0,
        #     script_type=proto_types.PAYTOOPRETURN,
        #     op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
        # ),
        # proto_types.TxOutputType(
        #     amount= 8120,
        #     script_type=proto_types.PAYTOADDRESS,
        #     address_n=client.expand_path("44'/1'/0'/1/0"),
        #     address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
        #     address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK',
        # ),
        # proto_types.TxOutputType(
        # amount= 18684 - 2000,
        # script_type=proto_types.PAYTOADDRESS,
        # address_n=client.expand_path("44'/0'/0'/0/7"),
        # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
        # # address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z',
        # ),
        # proto_types.TxOutputType(
        # amount= 1000,
        # script_type=proto_types.PAYTOADDRESS,
        # # address_n=client.expand_path("44'/0'/0'/0/18"),
        # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
        # # address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM',
        # ),
    ]

    #    (signatures, serialized_tx) = client.sign_tx('Testnet', inputs, outputs)
    (signatures, serialized_tx) = client.sign_tx('Bitcoin',
                                                 txstore.get_inputs(),
                                                 txstore.get_outputs())
    print('Transaction:', binascii.hexlify(serialized_tx))

    client.close()
Esempio n. 24
0
def sign(addr, msg, tx):
    # List all connected Trezors on USB
    devices = HidTransport.enumerate()

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

    # Use first connected device
    transport = devices[0]

    # Determine coin/address type corresponding to signing addresses
    addr_prefix = addr[0]
    coin = PREFIX_TO_COIN[addr_prefix]
    # TODO: Remove this to enable mainnet addresses. Currently temporarily disabled for safety.
    if coin == 'Bitcoin':
        raise ValueError(
            'Mainnet addresses currently not supported for safety')

    # Creates object for manipulating trezor
    client = TrezorClient(transport)
    if coin == 'Testnet':
        TxApi = TxApiBlockCypher(coin,
                                 'https://api.blockcypher.com/v1/btc/test3/')
        print('Making testnet api')
    if coin == 'Bitcoin':
        TxApi = TxApiBlockCypher(coin,
                                 'https://api.blockcypher.com/v1/btc/main/')
        print("Making bitcoin api")

    # Set the api for trezor client
    client.set_tx_api(TxApi)

    # Find the bip32 path of the address we are signing a message or tx from
    found_path = find_path(target_address=addr, client=client, coin=coin)
    if found_path is None:
        raise ValueError(
            'The address {} was not found on the connected trezor {} in search for its bip32 path'
            .format(addr, transport))
    else:
        print('Found bip32 path for: {} - signing from this address'.format(
            client.get_address(coin, found_path)))

    # Sign the specified message from the specified source address. Signature is in base64
    if msg is not None:
        print('Signing message: "{}"\nFrom address: {}'.format(msg, addr))
        res = client.sign_message(
            coin_name=coin,
            n=found_path,
            message=msg,
            script_type=PREFIX_TO_INPUT_SCRIPT[addr_prefix])
        print('Verify signing action on your trezor')
        print('Signature:', str(base64.b64encode(res.signature), 'ascii'))

    if tx is not None:
        # In this basic implementation, remember that tx data comes in the format:
        # <PREV HASH> <PREV INDEX> <DESTINATION ADDRESS> <AMOUNT> <FEE>
        prev_hash = tx[0]
        prev_index = int(tx[1])
        dest_address = tx[2]
        send_amount = int(tx[3])
        fee = int(tx[4])

        # Uses blockcypher API to get the amount (satoshi) of the UTXO. Amount is in satoshis
        utxo_amount = TxApi.get_tx(prev_hash).bin_outputs[prev_index].amount

        if send_amount + fee > utxo_amount:
            raise ValueError(
                'UTXO amount of {} is too small for sending {} satoshi with {} satoshi fee'
                .format(utxo_amount, send_amount, fee))

        print('Using UTXO: {} and index {} to send {} {} coins to: {}'.format(
            prev_hash, prev_index, send_amount / 100000000, coin,
            dest_address))

        # Prepare the inputs of the transaction
        input_type = get_input_script_type(api=TxApi,
                                           txhash=prev_hash,
                                           index=prev_index)
        inputs = [
            proto_types.TxInputType(
                address_n=found_path,
                prev_hash=binascii.unhexlify(prev_hash),
                prev_index=prev_index,
                script_type=input_type,
                amount=utxo_amount  # Amount is in satoshis
            ),
        ]

        # Prepare the outputs of the transaction
        outputs = [
            proto_types.TxOutputType(
                amount=send_amount,  # Amount is in satoshis
                script_type=PREFIX_TO_OUTPUT_SCRIPT[dest_address[0]],
                address=dest_address),
        ]
        # Determine amount to send to change address. Amount is in satoshis
        change = utxo_amount - send_amount - fee
        # Add change output, which is change address on the bip32 path of the sending address
        if change > 0:
            change_path = found_path[:]
            change_path[3] = 1
            change_address = client.get_address(coin, change_path)

            outputs.append(
                proto_types.TxOutputType(
                    amount=change,  # Amount is in satoshis
                    script_type=PREFIX_TO_OUTPUT_SCRIPT[change_address[0]],
                    address=change_address))
            print('Sending change amount of {} {} coins to change address: {}'.
                  format(change / 100000000, coin, change_address))

        # All information is ready, sign transaction and print it
        print('Verify transaction on your trezor')
        (signatures, serialized_tx) = client.sign_tx(coin, inputs, outputs)
        # print('Signatures:', signatures)
        print('Signed transaction:', serialized_tx.hex())

    client.close()
Esempio n. 25
0
class TrezorClient(HardwareWalletClient):

    # device is an HID device that has already been opened.
    def __init__(self, device, path):
        super(TrezorClient, self).__init__(device)
        device.close()
        self.client = Trezor(transport=get_transport("hid:" + path.decode()))

        # 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 = tools.parse_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 psbt 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 = proto.InputScriptType.SPENDADDRESS
            elif psbt_in.witness_utxo:
                # Check if the output is p2sh
                if psbt_in.witness_utxo.is_p2sh():
                    txinputtype.script_type = proto.InputScriptType.SPENDP2SHWITNESS
                else:
                    txinputtype.script_type = proto.InputScriptType.SPENDWITNESS

            # 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 = list(psbt_in.hd_keypaths[pubkey][1:])
                if fp == master_fp:
                    # Set the keypath
                    txinputtype.address_n = 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'
            bech32_hrp = 'tb'
        else:
            p2pkh_version = b'\x00'
            p2sh_version = b'\x05'
            bech32_hrp = 'bc'

        # prepare outputs
        outputs = []
        for out in tx.tx.vout:
            txoutput = proto.TxOutputType()
            txoutput.amount = out.nValue
            txoutput.script_type = proto.OutputScriptType.PAYTOADDRESS
            if out.is_p2pkh():
                txoutput.address = to_address(out.scriptPubKey[3:23],
                                              p2pkh_version)
            elif out.is_p2sh():
                txoutput.address = to_address(out.scriptPubKey[2:22],
                                              p2sh_version)
            else:
                wit, ver, prog = out.is_witness()
                if wit:
                    txoutput.address = bech32.encode(bech32_hrp, ver, prog)
                else:
                    raise TypeError("Output is not an address")

            # append to outputs
            outputs.append(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]
        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'
                break
            signatures.remove(sig)

        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):
        raise NotImplementedError(
            'The HardwareWalletClient base class does not '
            'implement this method')

    # 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 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')

    # Close the device
    def close(self):
        self.client.close()
Esempio n. 26
0
def main():
    numinputs = 600
    sizeinputtx = 10

    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

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

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

    txstore = MyTXAPIBitcoin()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
#    client.set_tx_api(TXAPITestnet())
    txstore.set_client(client)
    txstore.set_publickey(client.get_public_node(client.expand_path("44'/0'/0'")))
    print("creating input txs")
    txstore.create_inputs(numinputs, sizeinputtx)
    print("go")
    client.set_tx_api(txstore)
#    client.set_tx_api(MyTXAPIBitcoin())

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

    # Get the first address of first BIP44 account
    # (should be the same address as shown in mytrezor.com)

    outputs = [
        proto_types.TxOutputType(
            amount=0,
            script_type=proto_types.PAYTOADDRESS,
            address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm'
#            op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
#            address_n=client.expand_path("44'/0'/0'/0/35"),
#            address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj',
        ),
#        proto_types.TxOutputType(
#            amount=0,
#            script_type=proto_types.PAYTOOPRETURN,
#            op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
#        ),
#        proto_types.TxOutputType(
#            amount= 8120,
#            script_type=proto_types.PAYTOADDRESS,
#            address_n=client.expand_path("44'/1'/0'/1/0"),
#            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
#            address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK',
#        ),
#         proto_types.TxOutputType(
#             amount= 18684 - 2000,
#             script_type=proto_types.PAYTOADDRESS,
#             address_n=client.expand_path("44'/0'/0'/0/7"),
# #            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
# #            address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z',
#         ),
#         proto_types.TxOutputType(
#             amount= 1000,
#             script_type=proto_types.PAYTOADDRESS,
# #            address_n=client.expand_path("44'/0'/0'/0/18"),
# #            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
#             address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM',
#         ),
    ]

#    (signatures, serialized_tx) = client.sign_tx('Testnet', inputs, outputs)
    (signatures, serialized_tx) = client.sign_tx('Bitcoin', txstore.get_inputs(), txstore.get_outputs())
    print('Transaction:', binascii.hexlify(serialized_tx))

    client.close()