Beispiel #1
0
def hsm_status_report():
    # Return a JSON-able object. Documented and external programs
    # rely on this output... and yet, don't overshare either.
    from auth import UserAuthorizedAction
    from main import hsm_active, settings
    from hsm_ux import ApproveHSMPolicy

    rv = dict()
    rv['active'] = bool(hsm_active)

    if not hsm_active:
        rv['policy_available'] = hsm_policy_available()

        ar = UserAuthorizedAction.active_request
        if ar and isinstance(ar, ApproveHSMPolicy):
            # we are waiting for local user to approve entry into HSM mode
            rv['approval_wait'] = True

        rv['users'] = Users.list()
        rv['wallets'] = [ms.name for ms in MultisigWallet.get_all()]

    rv['chain'] = settings.get('chain', 'BTC')

    if hsm_active:
        hsm_active.status_report(rv)

    return rv
Beispiel #2
0
    def __init__(self, j, idx):
        # read json dict provided
        self.spent_so_far = 0  # for velocity

        def check_user(u):
            if not Users.valid_username(u):
                raise ValueError("Unknown user: %s" % u)
            return u

        self.index = idx + 1
        self.per_period = pop_int(j, 'per_period', 0, MAX_SATS)
        self.max_amount = pop_int(j, 'max_amount', 0, MAX_SATS)
        self.users = pop_list(j, 'users', check_user)
        self.whitelist = pop_list(j, 'whitelist', cleanup_whitelist_value)
        self.min_users = pop_int(j, 'min_users', 1, len(self.users))
        self.local_conf = pop_bool(j, 'local_conf')
        self.wallet = pop_string(j, 'wallet', 1, 20)

        assert sorted(set(self.users)) == sorted(self.users), 'dup users'

        # usernames need to be correct and already known
        if self.min_users is None:
            self.min_users = len(self.users) if self.users else None
        else:
            # redundant w/ code in pop_int() above
            assert 1 <= self.min_users <= len(self.users), "range"

        # if specified, 'wallet' must be an existing multisig wallet's name
        if self.wallet and self.wallet != '1':
            names = [ms.name for ms in MultisigWallet.get_all()]
            assert self.wallet in names, "unknown MS wallet: " + self.wallet

        assert_empty_dict(j)
Beispiel #3
0
def generate_public_contents():
    # Generate public details about wallet.
    #
    # simple text format:
    #   key = value
    # or #comments
    # but value is JSON
    from main import settings
    from public_constants import AF_CLASSIC

    num_rx = 5

    chain = chains.current_chain()

    with stash.SensitiveValues() as sv:

        yield ('''\
# Coldcard Wallet Summary File
## For wallet with master key fingerprint: {xfp}

Wallet operates on blockchain: {nb}

For BIP44, this is coin_type '{ct}', and internally we use
symbol {sym} for this blockchain.

## IMPORTANT WARNING

Do **not** deposit to any address in this file unless you have a working
wallet system that is ready to handle the funds at that address!

## Top-level, 'master' extended public key ('m/'):

{xpub}

What follows are derived public keys and payment addresses, as may
be needed for different systems.


'''.format(nb=chain.name,
           xpub=chain.serialize_public(sv.node),
           sym=chain.ctype,
           ct=chain.b44_cointype,
           xfp=xfp2str(sv.node.my_fingerprint())))

        for name, path, addr_fmt in chains.CommonDerivations:

            if '{coin_type}' in path:
                path = path.replace('{coin_type}', str(chain.b44_cointype))

            if '{' in name:
                name = name.format(core_name=chain.core_name)

            show_slip132 = ('Core' not in name)

            yield ('''## For {name}: {path}\n\n'''.format(name=name,
                                                          path=path))
            yield (
                '''First %d receive addresses (account=0, change=0):\n\n''' %
                num_rx)

            submaster = None
            for i in range(num_rx):
                subpath = path.format(account=0, change=0, idx=i)

                # find the prefix of the path that is hardneded
                if "'" in subpath:
                    hard_sub = subpath.rsplit("'", 1)[0] + "'"
                else:
                    hard_sub = 'm'

                if hard_sub != submaster:
                    # dump the xpub needed

                    if submaster:
                        yield "\n"

                    node = sv.derive_path(hard_sub, register=False)
                    yield ("%s => %s\n" %
                           (hard_sub, chain.serialize_public(node)))
                    if show_slip132 and addr_fmt != AF_CLASSIC and (
                            addr_fmt in chain.slip132):
                        yield (
                            "%s => %s   ##SLIP-132##\n" %
                            (hard_sub, chain.serialize_public(node, addr_fmt)))

                    submaster = hard_sub
                    node.blank()
                    del node

                # show the payment address
                node = sv.derive_path(subpath, register=False)
                yield ('%s => %s\n' % (subpath, chain.address(node, addr_fmt)))

                node.blank()
                del node

            yield ('\n\n')

    from multisig import MultisigWallet
    if MultisigWallet.exists():
        yield '\n# Your Multisig Wallets\n\n'
        from uio import StringIO

        for ms in MultisigWallet.get_all():
            fp = StringIO()

            ms.render_export(fp)
            print("\n---\n", file=fp)

            yield fp.getvalue()
            del fp