|
|
|
@ -27,12 +27,18 @@ INPUT_SCRIPTS = {
|
|
|
|
|
"address": messages.InputScriptType.SPENDADDRESS,
|
|
|
|
|
"segwit": messages.InputScriptType.SPENDWITNESS,
|
|
|
|
|
"p2shsegwit": messages.InputScriptType.SPENDP2SHWITNESS,
|
|
|
|
|
"pkh": messages.InputScriptType.SPENDADDRESS,
|
|
|
|
|
"wpkh": messages.InputScriptType.SPENDWITNESS,
|
|
|
|
|
"sh-wpkh": messages.InputScriptType.SPENDP2SHWITNESS,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OUTPUT_SCRIPTS = {
|
|
|
|
|
"address": messages.OutputScriptType.PAYTOADDRESS,
|
|
|
|
|
"segwit": messages.OutputScriptType.PAYTOWITNESS,
|
|
|
|
|
"p2shsegwit": messages.OutputScriptType.PAYTOP2SHWITNESS,
|
|
|
|
|
"pkh": messages.OutputScriptType.PAYTOADDRESS,
|
|
|
|
|
"wpkh": messages.OutputScriptType.PAYTOWITNESS,
|
|
|
|
|
"sh-wpkh": messages.OutputScriptType.PAYTOP2SHWITNESS,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEFAULT_COIN = "Bitcoin"
|
|
|
|
@ -184,6 +190,63 @@ def get_public_node(client, coin, address, curve, script_type, show_display):
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_descriptor(client, coin, account, script_type, show_display):
|
|
|
|
|
coin = coin or DEFAULT_COIN
|
|
|
|
|
if script_type == messages.InputScriptType.SPENDADDRESS:
|
|
|
|
|
acc_type = 44
|
|
|
|
|
fmt = "pkh({})"
|
|
|
|
|
elif script_type == messages.InputScriptType.SPENDP2SHWITNESS:
|
|
|
|
|
acc_type = 49
|
|
|
|
|
fmt = "sh(wpkh({}))"
|
|
|
|
|
elif script_type == messages.InputScriptType.SPENDWITNESS:
|
|
|
|
|
acc_type = 84
|
|
|
|
|
fmt = "wpkh({})"
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError("Unsupported account type")
|
|
|
|
|
|
|
|
|
|
if coin is None or coin == "Bitcoin":
|
|
|
|
|
coin_type = 0
|
|
|
|
|
elif coin == "Testnet":
|
|
|
|
|
coin_type = 1
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError("Unsupported coin")
|
|
|
|
|
|
|
|
|
|
path = f"m/{acc_type}'/{coin_type}'/{account}'"
|
|
|
|
|
n = tools.parse_path(path)
|
|
|
|
|
pub = btc.get_public_node(
|
|
|
|
|
client,
|
|
|
|
|
n,
|
|
|
|
|
show_display=show_display,
|
|
|
|
|
coin_name=coin,
|
|
|
|
|
script_type=script_type,
|
|
|
|
|
ignore_xpub_magic=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fingerprint = pub.root_fingerprint if pub.root_fingerprint is not None else 0
|
|
|
|
|
external = f"[{fingerprint:08x}{path[1:]}]{pub.xpub}/0/*"
|
|
|
|
|
internal = f"[{fingerprint:08x}{path[1:]}]{pub.xpub}/1/*"
|
|
|
|
|
return fmt.format(external), fmt.format(internal)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cli.command()
|
|
|
|
|
@click.option("-c", "--coin")
|
|
|
|
|
@click.option(
|
|
|
|
|
"-n", "--account", required=True, type=int, help="account index (0 = first account)"
|
|
|
|
|
)
|
|
|
|
|
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS), default="address")
|
|
|
|
|
@click.option("-d", "--show-display", is_flag=True)
|
|
|
|
|
@with_client
|
|
|
|
|
def get_descriptor(client, coin, account, script_type, show_display):
|
|
|
|
|
"""Get descriptor of given account."""
|
|
|
|
|
try:
|
|
|
|
|
ds = _get_descriptor(client, coin, account, script_type, show_display)
|
|
|
|
|
click.echo()
|
|
|
|
|
for d in ds:
|
|
|
|
|
click.echo(d)
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
raise click.ClickException(e.msg)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Signing functions
|
|
|
|
|
#
|
|
|
|
|