feat(python): add btc get-descriptor command

pull/1384/head
Pavol Rusnak 4 years ago
parent edb1243f64
commit 88889472eb

@ -66,6 +66,7 @@ def get_public_node(
show_display=False,
coin_name=None,
script_type=messages.InputScriptType.SPENDADDRESS,
ignore_xpub_magic=False,
):
return client.call(
messages.GetPublicKey(
@ -74,6 +75,7 @@ def get_public_node(
show_display=show_display,
coin_name=coin_name,
script_type=script_type,
ignore_xpub_magic=ignore_xpub_magic,
)
)

@ -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
#

Loading…
Cancel
Save