def new_device_xpubs(device_type): err = None app.specter.check() # get default new name name = device_type.capitalize() device_name = name i = 2 while device_name in app.specter.devices.names(): device_name = "%s %d" % (name, i) i += 1 xpubs = "" if request.method == 'POST': device_name = request.form['device_name'] if device_name in app.specter.devices.names(): err = "Device with this name already exists" xpubs = request.form['xpubs'] normalized, parsed, failed = normalize_xpubs(xpubs) if len(failed) > 0: err = "Failed to parse these xpubs:\n" + "\n".join(failed) if err is None: dev = app.specter.devices.add(name=device_name, device_type=device_type, keys=normalized) return redirect("/devices/%s/" % dev["alias"]) return render_template("new_device_xpubs.html", device_type=device_type, device_name=device_name, xpubs=xpubs, error=err, specter=app.specter, rand=rand)
def device(device_alias): app.specter.check() try: device = app.specter.devices.get_by_alias(device_alias) except: return render_template("base.html", error="Device not found", specter=app.specter, rand=rand) if request.method == 'POST': action = request.form['action'] if action == "forget": app.specter.devices.remove(device) return redirect("/") if action == "delete_key": key = request.form['key'] device.remove_key(key) if action == "add_keys": return render_template("new_device_xpubs.html", device_alias=device_alias, device=device, device_type=device["type"], specter=app.specter, rand=rand) if action == "morekeys": # refactor to fn xpubs = request.form['xpubs'] normalized, parsed, failed = normalize_xpubs(xpubs) err = None if len(failed) > 0: err = "Failed to parse these xpubs:\n" + "\n".join(failed) return render_template("new_device_xpubs.html", device_alias=device_alias, device=device, xpubs=xpubs, device_type=device["type"], error=err, specter=app.specter, rand=rand) if err is None: device.add_keys(normalized) device = copy.deepcopy(device) device["keys"] = [get_key_meta(key) for key in device["keys"]] device["keys"].sort(key=lambda x: x["chain"] + x["purpose"], reverse=True) return render_template("device.html", device_alias=device_alias, device=device, purposes=purposes, specter=app.specter, rand=rand)
def hwi_extract_xpubs(): specter = get_spector_instance() device_name = request.form['device_name'] if device_name in specter.devices.names(): return jsonify(success=False, error="Device with this name already exists") type = request.form.get("type") path = request.form.get("path") try: client = get_hwi_client(type, path) # Client will be configured for testnet if our Specter instance is # currently connected to testnet. This will prevent us from # getting mainnet xpubs unless we set is_testnet here: client.is_testnet = False xpubs = "" master_xpub = client.get_pubkey_at_path('m/0')['xpub'] master_fpr = hwilib_commands.get_xpub_fingerprint_hex(master_xpub) # HWI calls to client.get_pubkey_at_path() return "xpub"-prefixed xpubs # regardless of derivation path. Update to match SLIP-0132 prefixes. # See: # https://github.com/satoshilabs/slips/blob/master/slip-0132.md # Extract nested Segwit xpub = client.get_pubkey_at_path('m/49h/0h/0h')['xpub'] ypub = convert_xpub_prefix(xpub, b'\x04\x9d\x7c\xb2') xpubs += "[%s/49'/0'/0']%s\n" % (master_fpr, ypub) # native Segwit xpub = client.get_pubkey_at_path('m/84h/0h/0h')['xpub'] zpub = convert_xpub_prefix(xpub, b'\x04\xb2\x47\x46') xpubs += "[%s/84'/0'/0']%s\n" % (master_fpr, zpub) # Multisig nested Segwit xpub = client.get_pubkey_at_path('m/48h/0h/0h/1h')['xpub'] Ypub = convert_xpub_prefix(xpub, b'\x02\x95\xb4\x3f') xpubs += "[%s/48'/0'/0'/1']%s\n" % (master_fpr, Ypub) # Multisig native Segwit xpub = client.get_pubkey_at_path('m/48h/0h/0h/2h')['xpub'] Zpub = convert_xpub_prefix(xpub, b'\x02\xaa\x7e\xd3') xpubs += "[%s/48'/0'/0'/2']%s\n" % (master_fpr, Zpub) # And testnet client.is_testnet = True # Testnet nested Segwit xpub = client.get_pubkey_at_path('m/49h/1h/0h')['xpub'] upub = convert_xpub_prefix(xpub, b'\x04\x4a\x52\x62') xpubs += "[%s/49'/1'/0']%s\n" % (master_fpr, upub) # Testnet native Segwit xpub = client.get_pubkey_at_path('m/84h/1h/0h')['xpub'] vpub = convert_xpub_prefix(xpub, b'\x04\x5f\x1c\xf6') xpubs += "[%s/84'/1'/0']%s\n" % (master_fpr, vpub) # Testnet multisig nested Segwit xpub = client.get_pubkey_at_path('m/48h/1h/0h/1h')['xpub'] Upub = convert_xpub_prefix(xpub, b'\x02\x42\x89\xef') xpubs += "[%s/48'/1'/0'/1']%s\n" % (master_fpr, Upub) # Testnet multisig native Segwit xpub = client.get_pubkey_at_path('m/48h/1h/0h/2h')['xpub'] Vpub = convert_xpub_prefix(xpub, b'\x02\x57\x54\x83') xpubs += "[%s/48'/1'/0'/2']%s\n" % (master_fpr, Vpub) # Do proper cleanup otherwise have to reconnect device to access again client.close() except Exception as e: print(e) if client: try: client.close() except Exception: # We tried... pass return jsonify(success=False, error=e) normalized, parsed, failed = normalize_xpubs(xpubs) if len(failed) > 0: return jsonify(success=False, error="Failed to parse these xpubs:\n" + "\n".join(failed)) print(normalized) device = specter.devices.add(name=device_name, device_type=type, keys=normalized) return jsonify(success=True, device_alias=device["alias"])