Esempio n. 1
0
def parse_new_wallet(s):
    show_main()
    gui.update(30)

    # wallet format:
    # name&descriptor
    arr = s.split("&")
    if len(arr) != 2:
        gui.error("Invalid wallet format")
        return
    w = keystore.check_new_wallet(*arr)
    keys_str = []
    for key in w.keys:
        k = ("%r" % key).replace("]", "]\n")
        if keystore.owns_key(key):
            keys_str.append("#7ED321 My key: # %s" % k)
        else:
            keys_str.append("#F5A623 External key: # %s" % k)
    keys = "\n\n".join(keys_str)
    if w.script_type not in SUPPORTED_SCRIPTS.keys():
        raise ValueError("Script type \"%s\" is not supported" % w.script_type)
    sc = w.script_type
    msg = "Policy: %s\nScript: %s\n%s\n\n%s" % (w.policy, SUPPORTED_SCRIPTS[w.script_type], sc, keys)

    scr = popups.prompt("Add wallet \"%s\"?" % arr[0], msg, ok=cb_with_args(new_wallet_confirm, name=arr[0], descriptor=arr[1]))
    scr.message.set_recolor(True)
Esempio n. 2
0
 def cb(*args, **kwargs):
     try:
         return fn(*args, **kwargs)
     except Exception as e:
         b = BytesIO()
         sys.print_exception(e, b)
         gui.error("Something bad happened...\n\n%s" % b.getvalue().decode())
Esempio n. 3
0
 def cb():
     try:
         select_network(name)
         show_main()
     except Exception as e:
         print(e)
         gui.error("%r" % e)
Esempio n. 4
0
def parse_transaction(b64_tx, success_callback=None, error_callback=None):
    # we will go to main afterwards
    show_main()
    try:
        raw = a2b_base64(b64_tx)
        tx = psbt.PSBT.parse(raw)
    except:
        gui.error("Failed at transaction parsing")
        if error_callback is not None:
            error_callback("invalid argument")
        return
    # blue wallet trick - if the fingerprint is 0 we use our fingerprint
    for scope in [tx.inputs, tx.outputs]:
        for el in scope:
            for der in el.bip32_derivations:
                if el.bip32_derivations[
                        der].fingerprint == b'\x00\x00\x00\x00':
                    el.bip32_derivations[
                        der].fingerprint = keystore.fingerprint
    try:
        data = keystore.check_psbt(tx)
    except Exception as e:
        gui.error("Problem with the transaction: %r" % e)
        if error_callback is not None:
            error_callback("invalid argument")
        return
    title = "Spending %u\nfrom %s" % (data["spending"], data["wallet"].name)
    popups.prompt_tx(title,
                     data,
                     ok=cb_with_args(sign_psbt,
                                     wallet=data["wallet"],
                                     tx=tx,
                                     success_callback=success_callback),
                     cancel=cb_with_args(error_callback, "user cancel"))
Esempio n. 5
0
def save_entropy_plain():
    obj = {"entropy": hexlify(entropy).decode('utf-8')}
    with open(reckless_fname, "w") as f:
        f.write(json.dumps(obj))
    with open(reckless_fname, "r") as f:
        d = json.loads(f.read())
    if "entropy" in d  and d["entropy"] == hexlify(entropy).decode('utf-8'):
        gui.alert("Success!", "Your key is saved in the memory now")
    else:
        gui.error("Something went wrong")
Esempio n. 6
0
def parse_transaction(b64_tx, success_callback=None, error_callback=None):
    # we will go to main afterwards
    show_main()
    try:
        raw = a2b_base64(b64_tx)
        tx = psbt.PSBT.parse(raw)
    except:
        gui.error("Failed at transaction parsing")
        if error_callback is not None:
            error_callback("invalid argument")
        return
    # blue wallet trick - if the fingerprint is 0 we use our fingerprint
    for scope in [tx.inputs, tx.outputs]:
        for el in scope:
            for der in el.bip32_derivations:
                if el.bip32_derivations[der].fingerprint == b'\x00\x00\x00\x00':
                    el.bip32_derivations[der].fingerprint = keystore.fingerprint
    try:
        data = keystore.check_psbt(tx)
    except Exception as e:
        gui.error("Problem with the transaction: %r" % e)
        if error_callback is not None:
            error_callback("invalid argument")
        return

    # check for address gap limit
    gap_limit = False
    w = data["wallet"]
    wallet_key = b"\xfc\xca\x01" + data["wallet"].fingerprint
    for el in tx.inputs + tx.outputs:
        if el.bip32_derivations:
            # full PSBT
            for der in el.bip32_derivations:
                drv = el.bip32_derivations[der].derivation
                if drv[-1] > w.gap_limit + (w.last_chg_idx if drv[-2] else w.last_rcv_idx):
                    gap_limit = True
        elif wallet_key in el.unknown:
            # compressed PSBT
            idxs = el.unknown[wallet_key]
            chg = int.from_bytes(idxs[0:4], 'little')
            idx = int.from_bytes(idxs[4:8], 'little')
            if idx > w.gap_limit + (w.last_chg_idx if chg else w.last_rcv_idx):
                gap_limit = True
    if gap_limit:
        data["warning"] = ("#ff0000 Possible gap limit exceeded with some#\n"
                           "#ff0000 addresses. Your funds may get locked. #\n "
                           "#ff0000 Proceed at your own risk!#")

    title = "Spending %u\nfrom %s" % (data["spending"], data["wallet"].name)
    popups.prompt_tx(title, data,
        ok=cb_with_args(sign_psbt, wallet=data["wallet"], tx=tx, success_callback=success_callback),
        cancel=cb_with_args(error_callback, "user cancel")
    )
Esempio n. 7
0
def load_key():
    global entropy
    with open(reckless_fname, "r") as f:
        d = json.loads(f.read())
        entropy = unhexlify(d["entropy"])
    if "hmac" in d:
        hmac_calc = hmac_sha512(Key.key, entropy)
        if unhexlify(d["hmac"]) != hmac_calc:
            raise ValueError('Hmac does not match!')
        Key.iv = unhexlify(d["iv"])
        entropy = entropy_decrypt(entropy)
    if entropy is not None:
        ask_for_password()
    else:
        gui.error("Failed to load your recovery phrase.")
Esempio n. 8
0
def show_xpub(name, derivation, xpub=None):
    xpubs_menu()
    gui.update(30)
    try:
        if xpub is None:
            xpub = keystore.get_xpub(derivation)
        prefix = "[%s]" % bip32.path_to_str(bip32.parse_path(derivation), fingerprint=keystore.fingerprint)
    except:
        gui.error("Derivation path \"%s\" doesn't look right..." % derivation)
        return
    xpub_str = xpub.to_base58(network["xpub"])
    slip132 = xpub.to_base58()
    if slip132 == xpub_str:
        slip132 = None
    popups.show_xpub(name, xpub_str, slip132=slip132, prefix=prefix)
Esempio n. 9
0
def load_key():
    global entropy
    try:
        with open(reckless_fname, "r") as f:
            d = json.loads(f.read())
            entropy = unhexlify(d["entropy"])
        if "hmac" in d:
            hmac_calc = hmac_sha512(Key.key, entropy)
            if unhexlify(d["hmac"]) != hmac_calc:
                raise ValueError('Hmac does not match!')
            Key.iv = unhexlify(d["iv"])
            entropy = entropy_decrypt(entropy)
        ask_for_password()
    except:
        gui.error("Something went wrong, sorry")
Esempio n. 10
0
def confirm_new_wallet(s):
    show_main()
    gui.update(30)
    # wallet format:
    # name&descriptor
    arr = s.split("&")
    if len(arr) != 2:
        gui.error("Invalid wallet format")
        return
    try:
        keystore.check_new_wallet(*arr)
    except Exception as e:
        gui.error("%r" % e)
        return
    popups.prompt("Add wallet \"%s\"?" % arr[0], arr[1], ok=cb_with_args(new_wallet_confirm, name=arr[0], descriptor=arr[1]))
Esempio n. 11
0
def save_entropy_encrypted():
    try:
        Key.iv = get_random_bytes(16)
        entropy_encrypted = entropy_encrypt(entropy)
        hmac_entropy_encrypted = hmac_sha512(Key.key, entropy_encrypted)
        obj = {
            "entropy": hexlify(entropy_encrypted).decode('utf-8'),
            "iv": hexlify(Key.iv).decode('utf-8'),
            "hmac": hexlify(hmac_entropy_encrypted).decode('utf-8')
        }
        with open(reckless_fname, "w") as f:
            f.write(json.dumps(obj))
        with open(reckless_fname, "r") as f:
            d = json.loads(f.read())
        if "entropy" in d and d["entropy"] == hexlify(entropy_encrypted).decode('utf-8') and \
                unhexlify(d["hmac"]) == hmac_entropy_encrypted and entropy == entropy_decrypt(entropy_encrypted):
            gui.alert("Success!", "Your encrypted key is saved in the memory now")
        else:
            gui.error("Something went wrong")
    except Exception as e:
        gui.error("Fail: %r" % e)
Esempio n. 12
0
def verify_address(s):
    # we will go to main afterwards
    show_main()
    # verifies address in the form [bitcoin:]addr?index=i
    s = s.replace("bitcoin:", "")
    arr = s.split("?")
    index = None
    addr = None
    # check that ?index= is there
    if len(arr) > 1:
        addr = arr[0]
        meta_arr = arr[1].split("&")
        # search for `index=`
        for meta in meta_arr:
            if meta.startswith("index="):
                try:
                    index = int(meta.split("=")[1])
                except:
                    gui.error("Index is not an integer...")
                    return
    if index is None or addr is None:
        # where we will go next
        gui.error(
            "No derivation index in the address metadata - can't verify.")
        return
    for w in keystore.wallets:
        if w.address(index) == addr:
            popups.qr_alert("Address #%d from wallet\n\"%s\"" %
                            (index + 1, w.name),
                            "bitcoin:%s" % addr,
                            message_text=addr)
            return
    gui.error("Address doesn't belong to any wallet. Wrong device or network?")
Esempio n. 13
0
def save_settings(config):
    try:
        if USB_ENABLED and not config["usb"]:
            os.remove("%s/%s" % (storage_root, "USB_ENABLED"))
        if not USB_ENABLED and config["usb"]:
            with open("%s/%s" % (storage_root, "USB_ENABLED"), "w") as f:
                f.write("dummy") # should be hmac instead
        if DEV_ENABLED and not config["developer"]:
            os.remove("%s/%s" % (storage_root, "DEV_ENABLED"))
        if not DEV_ENABLED and config["developer"]:
            with open("%s/%s" % (storage_root, "DEV_ENABLED"), "w") as f:
                f.write("dummy") # should be hmac instead
        time.sleep_ms(100)
        if simulator:
            # meh... kinda doesn't work on unixport
            sys.exit()
        else:
            import pyb
            pyb.hard_reset()
    except Exception as e:
        gui.error("Failed to update settings!\n%r" % e)
    print(config)
Esempio n. 14
0
def verify_address(s):
    # we will go to main afterwards
    show_main()
    # verifies address in the form [bitcoin:]addr?index=i
    s = s.replace("bitcoin:", "")
    arr = s.split("?")
    index = None
    addr = None
    # check that ?index= is there
    if len(arr) > 1:
        addr = arr[0]
        meta_arr = arr[1].split("&")
        # search for `index=`
        for meta in meta_arr:
            if meta.startswith("index="):
                try:
                    index = int(meta.split("=")[1])
                except:
                    gui.error("Index is not an integer...")
                    return
    if index is None or addr is None:
        # where we will go next
        gui.error("No derivation index in the address metadata - can't verify.")
        return
    for w in keystore.wallets:
        if w.address(index) == addr:
            warning = ""
            if index > w.last_rcv_idx + w.gap_limit:
                warning = ("\n\n #ff0000 Possible gap limit. Using this address# "
                           "#ff0000 may lead to locking of your funds!#")
            elif index <= w.last_rcv_idx:
                warning = ("\n\n #ff0000 This address may have been used before.#\n"
                           "#ff0000 Reusing it would diminish your privacy!#")
            popups.qr_alert("Address #%d from wallet\n\"%s\"" % (index, w.name),
                            "bitcoin:%s"%addr, message_text=addr + warning)
            return
    gui.error("Address doesn't belong to any wallet. Wrong device or network?")
Esempio n. 15
0
def qr_scanner_error(msg):
    cancel_scan()
    gui.error(msg)
Esempio n. 16
0
def delete_entropy():
    try:
        os.remove(reckless_fname)
        gui.alert("Success!", "Your key is deleted")
    except:
        gui.error("Failed to delete the key")