Exemple #1
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}")
Exemple #2
0
 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}
Exemple #3
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)
Exemple #4
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")))
Exemple #5
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)
Exemple #6
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)
Exemple #7
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
 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
Exemple #9
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
Exemple #10
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
Exemple #11
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
Exemple #12
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()))
Exemple #13
0
def master_xpub(dev):
    if hasattr(dev.dev, 'pipe'):
        # this works better against simulator in HSM mode, where the xpub cmd may be disabled
        return simulator_fixed_xpub

    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