Ejemplo n.º 1
0
        def doit():
            dlen, _ = dev.upload_file(firmware, verify=True)
            assert dlen == len(firmware)

            # append the firmware header a second time
            result = dev.send_recv(CCProtocolPacker.upload(size, size+FW_HEADER_SIZE, hdr))

            # make it reboot into bootlaoder which might install it
            dev.send_recv(CCProtocolPacker.reboot())
Ejemplo n.º 2
0
def bag_number(number):
    "Factory: set or read bag number -- single use only!"
    dev = ColdcardDevice(sn=force_serial)

    nn = b'' if not number else number.encode('ascii')

    resp = dev.send_recv(CCProtocolPacker.bag_number(nn))

    print("Bag number: %r" % resp)
Ejemplo n.º 3
0
    async def create_user(self, username, authmode, new_pw=None):
        # typically we'll let Coldcard pick password
        if authmode == USER_AUTH_HMAC and new_pw:
            secret = self.dev.hash_password(new_pw.encode('utf8'))
        else:
            secret = b''

        await self.send_recv(
            CCProtocolPacker.create_user(username, authmode, secret))
Ejemplo n.º 4
0
 def ping_check(self):
     # check connection is working
     assert self.dev.session_key, 'not encrypted?'
     req = b'1234 Electrum Plugin 4321'  # free up to 59 bytes
     try:
         echo = self.dev.send_recv(CCProtocolPacker.ping(req))
         assert echo == req
     except:
         raise RuntimeError("Communication trouble with Coldcard")
Ejemplo n.º 5
0
Archivo: coldcardi.py Proyecto: nvk/HWI
 def get_pubkey_at_path(self, path):
     path = path.replace('h', '\'')
     path = path.replace('H', '\'')
     xpub = self.device.send_recv(CCProtocolPacker.get_xpub(path),
                                  timeout=None)
     if self.is_testnet:
         return {'xpub': xpub_main_2_test(xpub)}
     else:
         return {'xpub': xpub}
Ejemplo n.º 6
0
 def ping_check(self):
     # check connection is working
     assert self.dev.session_key, 'not encrypted?'
     req = b'1234 Electrum Plugin 4321'      # free up to 59 bytes
     try:
         echo = self.dev.send_recv(CCProtocolPacker.ping(req))
         assert echo == req
     except:
         raise RuntimeError("Communication trouble with Coldcard")
Ejemplo n.º 7
0
def file_upload(filename, blksize, multisig=False):
    "Send file to Coldcard (PSBT transaction or firmware)"

    # NOTE: mostly for debug/dev usage.
    dev = ColdcardDevice(sn=force_serial)

    file_len, sha = real_file_upload(filename, blksize, dev=dev)

    if multisig:
        dev.send_recv(CCProtocolPacker.multisig_enroll(file_len, sha))
Ejemplo n.º 8
0
def file_upload(filename, blksize, multisig=False):
    """Send file to Coldcard (PSBT transaction or firmware)"""

    # NOTE: mostly for debug/dev usage.
    with get_device() as dev:

        file_len, sha = real_file_upload(filename, dev, blksize=blksize)

        if multisig:
            dev.send_recv(CCProtocolPacker.multisig_enroll(file_len, sha))
Ejemplo n.º 9
0
    async def run(self):
        # connect to, and maintain a connection to a single Coldcard

        logging.info("Connecting to Coldcard.")

        while 1:
            try:
                if not self.serial and os.path.exists(settings.SIMULATOR_SOCK):
                    # if simulator is running, just use it.
                    sn = settings.SIMULATOR_SOCK
                else:
                    sn = self.serial

                d = ColdcardDevice(sn=sn)
                logging.info(f"Found Coldcard {d.serial}.")

                await asyncio.get_running_loop().run_in_executor(
                    executor, d.check_mitm)

                async with self.lock:
                    self.dev = d
            except:
                logging.error("Cannot connect to Coldcard (will retry)",
                              exc_info=0)
                await asyncio.sleep(settings.RECONNECT_DELAY)
                continue

            # stay connected, and check we are working periodically
            logging.info(f"Connected to Coldcard {self.dev.serial}.")

            STATUS.connected = True

            # read static info about coldcard
            STATUS.xfp = xfp2str(self.dev.master_fingerprint)
            STATUS.serial_number = self.dev.serial
            STATUS.is_testnet = (self.dev.master_xpub[0] == 't')
            STATUS.hsm = {}
            STATUS.reset_pending_auth()
            STATUS.notify_watchers()
            await self.hsm_status()

            while 1:
                await asyncio.sleep(settings.PING_RATE)
                try:
                    # use long timeout here, even tho simple command, because the CC may
                    # we working on something else right now (thinking).
                    h = await self.send_recv(CCProtocolPacker.hsm_status(),
                                             timeout=20000)
                    logging.info("ping ok")
                    await self.hsm_status(h)
                except MissingColdcard:
                    self._conn_broken()
                    break
                except:
                    logging.error("Ping failed", exc_info=1)
Ejemplo n.º 10
0
def get_xpub(subpath):
    """Get the XPUB for this wallet (master level, or any derivation)"""

    with get_device() as dev:
        if len(subpath) == 1:
            if subpath[0] == 'bip44':
                subpath = BIP44_FIRST

        xpub = dev.send_recv(CCProtocolPacker.get_xpub(subpath), timeout=None)

        click.echo(xpub)
Ejemplo n.º 11
0
    def doit(config):
        # upload the file, trigger import
        file_len, sha = dev.upload_file(config.encode('ascii'))

        dev.send_recv(CCProtocolPacker.multisig_enroll(file_len, sha))

        time.sleep(.2)
        title, story = cap_story()
        #print(repr(story))

        return title, story
Ejemplo n.º 12
0
def get_block_chain():
    '''Get which blockchain (Bitcoin/Testnet) is configured.

    BTC=>Bitcoin  or  XTN=>Bitcoin Testnet
    '''

    dev = ColdcardDevice(sn=force_serial)

    code = dev.send_recv(CCProtocolPacker.block_chain())

    click.echo(code)
Ejemplo n.º 13
0
    def doit(accept=True, in_psbt=None, finalize=False, accept_ms_import=False):

        if accept_ms_import:
            # XXX would be better to do cap_story here, but that would limit test to simulator
            need_keypress('y')
            time.sleep(0.050)

        if accept != None:
            need_keypress('y' if accept else 'x')

        if accept == False:
            with pytest.raises(CCUserRefused):
                done = None
                while done == None:
                    time.sleep(0.050)
                    done = dev.send_recv(CCProtocolPacker.get_signed_txn(), timeout=None)
            return
        else:
            done = None
            while done == None:
                time.sleep(0.050)
                done = dev.send_recv(CCProtocolPacker.get_signed_txn(), timeout=None)

        assert len(done) == 2

        resp_len, chk = done
        psbt_out = dev.download_file(resp_len, chk)

        if not finalize:
            if in_psbt:
                from psbt import BasicPSBT
                assert BasicPSBT().parse(in_psbt) != None
        else:
            from pycoin.tx.Tx import Tx
            # parse it
            res = psbt_out
            assert res[0:4] != b'psbt', 'still a PSBT, but asked for finalize'
            t = Tx.from_bin(res)
            assert t.version in [1, 2]

        return psbt_out
Ejemplo n.º 14
0
def sign_transaction(psbt_in,
                     psbt_out,
                     verbose=False,
                     hex_mode=False,
                     finalize=True):
    "Approve a spending transaction (by signing it on Coldcard)"

    dev = ColdcardDevice(sn=force_serial)

    dev.check_mitm()

    # not enforcing policy here on msg contents, so we can define that on product
    taste = psbt_in.read(10)
    psbt_in.seek(0)
    if taste == b'70736274ff':
        # hex encoded; make binary
        psbt_in = io.BytesIO(a2b_hex(psbt_in.read()))
        hex_mode = True
    elif taste[0:5] != b'psbt\xff':
        click.echo("File doesn't have PSBT magic number at start.")
        sys.exit(1)

    # upload the transaction
    txn_len, sha = real_file_upload(psbt_in, dev=dev)

    # start the signing process
    ok = dev.send_recv(CCProtocolPacker.sign_transaction(txn_len, sha),
                       timeout=None)
    assert ok == None

    result, _ = wait_and_download(dev, CCProtocolPacker.get_signed_txn(), 1)

    if finalize:
        # assume(?) transaction is completely signed, and output the
        # bitcoin transaction to be sent.
        # XXX maybe do this on embedded side, when txn is final?
        # XXX otherwise, need to parse PSBT and also handle combining properly
        pass

    # save it
    psbt_out.write(b2a_hex(result) if hex_mode else result)
Ejemplo n.º 15
0
def get_pubkey(subpath):
    """
    Get the public key for a derivation path

    Dump 33-byte (compressed, SEC encoded) public key value.
    """
    with get_device() as dev:
        xpub = dev.send_recv(CCProtocolPacker.get_xpub(subpath), timeout=None)
        pubkey, _ = decode_xpub(xpub)
        vk = VerifyingKey.from_string(get_pubkey_string(pubkey),
                                      curve=SECP256k1)
        click.echo(b2a_hex(vk.to_string("compressed")))
Ejemplo n.º 16
0
def get_xpub(subpath):
    "Get the XPUB for this wallet (master level, or any derivation)"

    dev = ColdcardDevice(sn=force_serial)

    if len(subpath) == 1:
        if subpath[0] == 'bip44':
            subpath = BIP44_FIRST

    xpub = dev.send_recv(CCProtocolPacker.get_xpub(subpath), timeout=None)

    click.echo(xpub)
Ejemplo n.º 17
0
    def doit(M, addr_fmt=None, do_import=True):
        passwords = ['Me', 'Myself', 'And I', '']

        if 0:
            # WORKING, but slow .. and it's constant data
            keys = []
            for pw in passwords:
                xfp = set_bip39_pw(pw)

                sk = dev.send_recv(CCProtocolPacker.get_xpub("m/45'"))
                node = BIP32Node.from_wallet_key(sk)

                keys.append((xfp, None, node))

            assert len(set(x for x,_,_ in keys)) == 4, keys
            pprint(keys)
        else:
            # Much, FASTER!
            assert dev.is_simulator
            keys = [(3503269483, None,
                        BIP32Node.from_hwif('tpubD9429UXFGCTKJ9NdiNK4rC5ygqSUkginycYHccqSg5gkmyQ7PZRHNjk99M6a6Y3NY8ctEUUJvCu6iCCui8Ju3xrHRu3Ez1CKB4ZFoRZDdP9')),
                     (2389277556, None,
                        BIP32Node.from_hwif('tpubD97nVL37v5tWyMf9ofh5rznwhh1593WMRg6FT4o6MRJkKWANtwAMHYLrcJFsFmPfYbY1TE1LLQ4KBb84LBPt1ubvFwoosvMkcWJtMwvXgSc')),
                 (3190206587, None,
                        BIP32Node.from_hwif('tpubD9ArfXowvGHnuECKdGXVKDMfZVGdephVWg8fWGWStH3VKHzT4ph3A4ZcgXWqFu1F5xGTfxncmrnf3sLC86dup2a8Kx7z3xQ3AgeNTQeFxPa')),
                (1130956047, None,
                        BIP32Node.from_hwif('tpubD8NXmKsmWp3a3DXhbihAYbYLGaRNVdTnr6JoSxxfXYQcmwVtW2hv8QoDwng6JtEonmJoL3cNEwfd2cLXMpGezwZ2vL2dQ7259bueNKj9C8n')),
            ]

        if do_import:
            # render as a file for import
            config = f"name: Myself-{M}\npolicy: {M} / 4\n\n"

            if addr_fmt:
                config += f'format: {addr_fmt.upper()}\n'

            config += '\n'.join('%s: %s' % (xfp2str(xfp), sk.hwif()) for xfp, _, sk in keys)
            #print(config)

            title, story = offer_ms_import(config)
            #print(story)

            # dont care if update or create; accept it.
            time.sleep(.1)
            need_keypress('y')

        def select_wallet(idx):
            # select to specific pw
            xfp = set_bip39_pw(passwords[idx])
            assert xfp == keys[idx][0]

        return (keys, select_wallet)
Ejemplo n.º 18
0
def hsm_status():
    """
    Get current status of HSM feature.
    Is it running, what is the policy (summary only).
    """
    with get_device() as dev:
        dev.check_mitm()

        resp = dev.send_recv(CCProtocolPacker.hsm_status())

        o = json.loads(resp)

        click.echo(pformat(o))
Ejemplo n.º 19
0
def enroll_xpub(name, min_signers, path,  num_signers, output_file=None, verbose=False, just_add=False):
    '''
Create a skeleton file which defines a multisig wallet.

When completed, use with: "ckcc upload -m wallet.txt" or put on SD card.
'''

    dev = ColdcardDevice(sn=force_serial)
    dev.check_mitm()

    xfp = dev.master_fingerprint
    my_xpub = dev.send_recv(CCProtocolPacker.get_xpub(path), timeout=None)
    new_line = "%s: %s" % (xfp2str(xfp), my_xpub)

    if just_add:
        click.echo(new_line)
        sys.exit(0)

    N = num_signers

    if N < min_signers:
        N = min_signers

    if not (1 <= N < 15):
        click.echo("N must be 1..15")
        sys.exit(1)

    if min_signers == 0:
        min_signers = N 

    if not (1 <= min_signers <= N):
        click.echo(f"Minimum number of signers (M) must be between 1 and N={N}")
        sys.exit(1)

    if not (1 <= len(name) <= 20) or name != str(name.encode('utf8'), 'ascii', 'ignore'):
        click.echo("Name must be between 1 and 20 characters of ASCII.")
        sys.exit(1)

    # render into a template
    config = f'name: {name}\npolicy: {min_signers} of {N}\n\n#path: {path}\n{new_line}\n'
    if num_signers != 1:
        config += '\n'.join(f'#{i+2}# FINGERPRINT: xpub123123123123123' for i in range(num_signers-1))
        config += '\n'

    if verbose or not output_file:
        click.echo(config[:-1])

    if output_file:
        output_file.write(config)
        output_file.close()
        click.echo(f"Wrote to: {output_file.name}")
Ejemplo n.º 20
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     print_error('[coldcard]', 'Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         __, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub)
     except InvalidMasterKeyVersionBytes:
         raise UserFacingException(_('Invalid xpub magic. Make sure your {} device is set to the correct chain.')
                                   .format(self.device)) from None
     if xtype != 'standard':
         xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number)
     return xpub
Ejemplo n.º 21
0
    def sign_transaction_start(self, raw_psbt, finalize=True):
        # Multiple steps to sign:
        # - upload binary
        # - start signing UX
        # - wait for coldcard to complete process, or have it refused.
        # - download resulting txn
        assert 20 <= len(raw_psbt) < MAX_TXN_LEN, 'PSBT is too big'
        dlen, chk = self.dev.upload_file(raw_psbt)

        resp = self.dev.send_recv(CCProtocolPacker.sign_transaction(dlen, chk, finalize=finalize),
                                    timeout=None)

        if resp != None:
            raise ValueError(resp)
Ejemplo n.º 22
0
    def sign_transaction_start(self, raw_psbt, finalize=True):
        # Multiple steps to sign:
        # - upload binary
        # - start signing UX
        # - wait for coldcard to complete process, or have it refused.
        # - download resulting txn
        assert 20 <= len(raw_psbt) < MAX_TXN_LEN, 'PSBT is too big'
        dlen, chk = self.dev.upload_file(raw_psbt)

        resp = self.dev.send_recv(CCProtocolPacker.sign_transaction(dlen, chk, finalize=finalize),
                                    timeout=None)

        if resp != None:
            raise ValueError(resp)
Ejemplo n.º 23
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     print_error('[coldcard]', 'Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         __, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub)
     except InvalidMasterKeyVersionBytes:
         raise Exception(_('Invalid xpub magic. Make sure your {} device is set to the correct chain.')
                         .format(self.device)) from None
     if xtype != 'standard':
         xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number)
     return xpub
Ejemplo n.º 24
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     print_error('[coldcard]', 'Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         node = BIP32Node.from_xkey(xpub)
     except InvalidMasterKeyVersionBytes:
         raise UserFacingException(_('Invalid xpub magic. Make sure your {} device is set to the correct chain.')
                                   .format(self.device)) from None
     if xtype != 'standard':
         xpub = node._replace(xtype=xtype).to_xpub()
     return xpub
Ejemplo n.º 25
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     _logger.info('Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         node = BIP32Node.from_xkey(xpub)
     except InvalidMasterKeyVersionBytes:
         raise UserFacingException(_('Invalid xpub magic. Make sure your {} device is set to the correct chain.')
                                   .format(self.device)) from None
     if xtype != 'standard':
         xpub = node._replace(xtype=xtype).to_xpub()
     return xpub
Ejemplo n.º 26
0
    def doit(filename, finalize=False, stxn_flags=0x0):
        if filename[0:5] == b'psbt\xff':
            ip = filename
            filename = 'memory'
        else:
            ip = open(filename, 'rb').read()
            if ip[0:10] == b'70736274ff':
                ip = a2b_hex(ip.strip())
            assert ip[0:5] == b'psbt\xff'

        ll, sha = dev.upload_file(ip)

        dev.send_recv(CCProtocolPacker.sign_transaction(ll, sha, finalize, flags=stxn_flags))

        return ip
Ejemplo n.º 27
0
def hsm_status():
    '''
Get current status of HSM feature.

Is it running, what is the policy (summary only).
'''
    
    dev = ColdcardDevice(sn=force_serial)
    dev.check_mitm()

    resp = dev.send_recv(CCProtocolPacker.hsm_status())

    o = json.loads(resp)

    click.echo(pformat(o))
Ejemplo n.º 28
0
    async def user_auth(self, username, token, totp, psbt_hash):
        if len(token) == 6 and token.isdigit():
            # assume TOTP if token (password) is 6-numeric digits
            totp_time = totp or int(time.time() // 30)
            token = token.encode('ascii')
        else:
            # assume it's a raw password. need to hash it up
            # TODO: move this hashing into browser
            secret = self.dev.hash_password(token.encode('utf8'))
            token = HMAC(secret, msg=psbt_hash, digestmod=sha256).digest()
            totp_time = 0

        await self.send_recv(
            CCProtocolPacker.user_auth(username.encode('ascii'), token,
                                       totp_time))
Ejemplo n.º 29
0
    def doit(M,
             N,
             addr_fmt=None,
             name=None,
             unique=0,
             accept=False,
             common=None,
             keys=None,
             do_import=True):
        keys = keys or make_multisig(M, N, unique=unique)

        if not do_import:
            return keys

        # render as a file for import
        name = name or f'test-{M}-{N}'
        config = f"name: {name}\npolicy: {M} / {N}\n\n"

        if addr_fmt:
            config += f'format: {addr_fmt.title()}\n'

        if common:
            config += f'derivation: {common}\n'

        config += '\n'.join('%s: %s' %
                            (xfp2str(xfp), dd.hwif(as_private=False))
                            for xfp, m, dd in keys)
        #print(config)

        title, story = offer_ms_import(config)

        assert 'Create new multisig' in story
        assert name in story
        assert f'Policy: {M} of {N}\n' in story

        if accept:
            time.sleep(.1)
            need_keypress('y')

            # Test it worked.
            time.sleep(.1)  # required
            xor = 0
            for xfp, _, _ in keys:
                xor ^= xfp
            assert dev.send_recv(CCProtocolPacker.multisig_check(M, N,
                                                                 xor)) == 1

        return keys
Ejemplo n.º 30
0
def master_xpub(dev):
    r = dev.send_recv(CCProtocolPacker.get_xpub('m'), timeout=None, encrypt=1)

    assert r[1:4] == 'pub', r

    if r[0:4] == dev.master_xpub[0:4]:
        assert r == dev.master_xpub
    elif dev.master_xpub:
        # testnet vs. mainnet difference
        from pycoin.key.BIP32Node import BIP32Node
        a = BIP32Node.from_wallet_key(r)
        b = BIP32Node.from_wallet_key(dev.master_xpub)

        assert a.secret_exponent() == b.secret_exponent()

    return r
Ejemplo n.º 31
0
def show_address(script, fingerprints, quiet=False, segwit=False, wrap=False):
    '''Show a multisig payment address on-screen.

    Needs a redeem script and list of fingerprint/path (4369050F/1/0/0 for example).

    This is provided as a demo or debug feature. You'll need need some way to
    generate the full redeem script (hex), and the fingerprints and paths used to
    generate each public key inside that. The order of fingerprint/paths must
    match order of pubkeys in the script.
    '''

    dev = ColdcardDevice(sn=force_serial)

    addr_fmt = AF_P2SH
    if segwit:
        addr_fmt = AF_P2WSH
    if wrap:
        addr_fmt = AF_P2WSH_P2SH

    script = a2b_hex(script)
    N = len(fingerprints)

    assert 1 <= N <= 15, "bad N"

    min_signers = script[0] - 80
    assert 1 <= min_signers <= N, "bad M"

    assert script[-1] == 0xAE, "expect script to end with OP_CHECKMULTISIG"
    assert script[-2] == 80 + N, "second last byte should encode N"

    xfp_paths = []
    for idx, xfp in enumerate(fingerprints):
        assert '/' in xfp, 'Needs a XFP/path: ' + xfp
        xfp, p = xfp.split('/', 1)

        xfp_paths.append(str_to_int_path(xfp, p))

    addr = dev.send_recv(CCProtocolPacker.show_p2sh_address(min_signers,
                                                            xfp_paths,
                                                            script,
                                                            addr_fmt=addr_fmt),
                         timeout=None)

    if quiet:
        click.echo(addr)
    else:
        click.echo('Displaying address:\n\n%s\n' % addr)
Ejemplo n.º 32
0
 def doit(k):
     if hasattr(dev.dev, 'pipe'):
         # simulator has special USB command
         dev.send_recv(CCProtocolPacker.sim_keypress(k.encode('ascii')))
     elif request.config.getoption("--manual"):
         # need actual user interaction
         print("==> NOW, on the Coldcard, press key: %r" % k, file=sys.stderr)
     else:
         # try to use debug interface to simulate the press
         # XXX for some reason, picocom must **already** be running for this to work.
         # - otherwise, this locks up
         devs = list(glob.glob('/dev/tty.usbmodem*'))
         if len(devs) == 1:
             with open(devs[0], 'wb', 0) as fd:
                 fd.write(k.encode('ascii'))
         else:
             raise pytest.fail('need to provide keypresses')
Ejemplo n.º 33
0
def show_address(path, quiet=False, segwit=False, wrap=False):
    """Show the human version of an address"""
    with get_device() as dev:
        if wrap:
            addr_fmt = AF_P2WPKH_P2SH
        elif segwit:
            addr_fmt = AF_P2WPKH
        else:
            addr_fmt = AF_CLASSIC

        addr = dev.send_recv(CCProtocolPacker.show_address(path, addr_fmt),
                             timeout=None)

        if quiet:
            click.echo(addr)
        else:
            click.echo('Displaying address:\n\n%s\n' % addr)
Ejemplo n.º 34
0
def get_pubkey(subpath):
    '''Get the public key for a derivation path

    Dump 33-byte (compressed, SEC encoded) public key value.
    '''

    try:
        from pycoin.key.BIP32Node import BIP32Node
    except:
        raise click.Abort("pycoin must be installed, not found.")

    dev = ColdcardDevice(sn=force_serial)

    xpub = dev.send_recv(CCProtocolPacker.get_xpub(subpath), timeout=None)

    node = BIP32Node.from_hwif(xpub)

    click.echo(b2a_hex(node.sec()))
Ejemplo n.º 35
0
def show_address(path, quiet=False, segwit=False, wrap=False):
    "Show the human version of an address"

    dev = ColdcardDevice(sn=force_serial)

    if wrap:
        addr_fmt = AF_P2WPKH_P2SH
    elif segwit:
        addr_fmt = AF_P2WPKH
    else:
        addr_fmt = AF_CLASSIC

    addr = dev.send_recv(CCProtocolPacker.show_address(path, addr_fmt), timeout=None)

    if quiet:
        print(addr)
    else:
        print('Displaying address:\n\n%s\n' % addr)
Ejemplo n.º 36
0
 def sign_transaction_poll(self):
     # poll device... if user has approved, will get tuple: (legnth, checksum) else None
     return self.dev.send_recv(CCProtocolPacker.get_signed_txn(), timeout=None)
Ejemplo n.º 37
0
 def show_address(self, path, addr_fmt):
     # prompt user w/ addres, also returns it immediately.
     return self.dev.send_recv(CCProtocolPacker.show_address(path, addr_fmt), timeout=None)
Ejemplo n.º 38
0
 def sign_message_start(self, path, msg):
     # this starts the UX experience.
     self.dev.send_recv(CCProtocolPacker.sign_message(msg, path), timeout=None)
Ejemplo n.º 39
0
 def sign_message_poll(self):
     # poll device... if user has approved, will get tuple: (addr, sig) else None
     return self.dev.send_recv(CCProtocolPacker.get_signed_msg(), timeout=None)
Ejemplo n.º 40
0
 def get_version(self):
     # gives list of strings
     return self.dev.send_recv(CCProtocolPacker.version(), timeout=1000).split('\n')