mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
feat(python/trezorctl): detect script type from path (fixes #2159)
This commit is contained in:
parent
60648c903f
commit
aaa224a4f7
1
python/.changelog.d/2159.added
Normal file
1
python/.changelog.d/2159.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
trezorctl: Bitcoin commands can detect script type from derivation path.
|
@ -49,6 +49,19 @@ OUTPUT_SCRIPTS = {
|
|||||||
"tr": messages.OutputScriptType.PAYTOTAPROOT,
|
"tr": messages.OutputScriptType.PAYTOTAPROOT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIP_PURPOSE_TO_SCRIPT_TYPE = {
|
||||||
|
tools.H_(44): messages.InputScriptType.SPENDADDRESS,
|
||||||
|
tools.H_(49): messages.InputScriptType.SPENDP2SHWITNESS,
|
||||||
|
tools.H_(84): messages.InputScriptType.SPENDWITNESS,
|
||||||
|
tools.H_(86): messages.InputScriptType.SPENDTAPROOT,
|
||||||
|
}
|
||||||
|
|
||||||
|
BIP48_SCRIPT_TYPES = {
|
||||||
|
tools.H_(0): messages.InputScriptType.SPENDMULTISIG,
|
||||||
|
tools.H_(1): messages.InputScriptType.SPENDP2SHWITNESS,
|
||||||
|
tools.H_(2): messages.InputScriptType.SPENDWITNESS,
|
||||||
|
}
|
||||||
|
|
||||||
DEFAULT_COIN = "Bitcoin"
|
DEFAULT_COIN = "Bitcoin"
|
||||||
|
|
||||||
|
|
||||||
@ -85,6 +98,22 @@ def xpub_deserialize(xpubstr: str) -> Tuple[str, messages.HDNodeType]:
|
|||||||
return data.version, node
|
return data.version, node
|
||||||
|
|
||||||
|
|
||||||
|
def guess_script_type_from_path(address_n: List[int]) -> messages.InputScriptType:
|
||||||
|
if len(address_n) < 1:
|
||||||
|
return messages.InputScriptType.SPENDADDRESS
|
||||||
|
|
||||||
|
purpose = address_n[0]
|
||||||
|
if purpose in BIP_PURPOSE_TO_SCRIPT_TYPE:
|
||||||
|
return BIP_PURPOSE_TO_SCRIPT_TYPE[purpose]
|
||||||
|
|
||||||
|
if purpose == tools.H_(48) and len(address_n) >= 4:
|
||||||
|
script_type_field = address_n[3]
|
||||||
|
if script_type_field in BIP48_SCRIPT_TYPES:
|
||||||
|
return BIP48_SCRIPT_TYPES[script_type_field]
|
||||||
|
|
||||||
|
return messages.InputScriptType.SPENDADDRESS
|
||||||
|
|
||||||
|
|
||||||
@click.group(name="btc")
|
@click.group(name="btc")
|
||||||
def cli() -> None:
|
def cli() -> None:
|
||||||
"""Bitcoin and Bitcoin-like coins commands."""
|
"""Bitcoin and Bitcoin-like coins commands."""
|
||||||
@ -98,7 +127,7 @@ def cli() -> None:
|
|||||||
@cli.command()
|
@cli.command()
|
||||||
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
||||||
@click.option("-n", "--address", required=True, help="BIP-32 path")
|
@click.option("-n", "--address", required=True, help="BIP-32 path")
|
||||||
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS), default="address")
|
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS))
|
||||||
@click.option("-d", "--show-display", is_flag=True)
|
@click.option("-d", "--show-display", is_flag=True)
|
||||||
@click.option("-x", "--multisig-xpub", multiple=True, help="XPUBs of multisig owners")
|
@click.option("-x", "--multisig-xpub", multiple=True, help="XPUBs of multisig owners")
|
||||||
@click.option("-m", "--multisig-threshold", type=int, help="Number of signatures")
|
@click.option("-m", "--multisig-threshold", type=int, help="Number of signatures")
|
||||||
@ -114,7 +143,7 @@ def get_address(
|
|||||||
client: "TrezorClient",
|
client: "TrezorClient",
|
||||||
coin: str,
|
coin: str,
|
||||||
address: str,
|
address: str,
|
||||||
script_type: messages.InputScriptType,
|
script_type: Optional[messages.InputScriptType],
|
||||||
show_display: bool,
|
show_display: bool,
|
||||||
multisig_xpub: List[str],
|
multisig_xpub: List[str],
|
||||||
multisig_threshold: Optional[int],
|
multisig_threshold: Optional[int],
|
||||||
@ -141,6 +170,8 @@ def get_address(
|
|||||||
use final xpubs, specify '-N 0'.
|
use final xpubs, specify '-N 0'.
|
||||||
"""
|
"""
|
||||||
address_n = tools.parse_path(address)
|
address_n = tools.parse_path(address)
|
||||||
|
if script_type is None:
|
||||||
|
script_type = guess_script_type_from_path(address_n)
|
||||||
|
|
||||||
multisig: Optional[messages.MultisigRedeemScriptType]
|
multisig: Optional[messages.MultisigRedeemScriptType]
|
||||||
if multisig_xpub:
|
if multisig_xpub:
|
||||||
@ -171,7 +202,7 @@ def get_address(
|
|||||||
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
||||||
@click.option("-n", "--address", required=True, help="BIP-32 path, e.g. m/44'/0'/0'")
|
@click.option("-n", "--address", required=True, help="BIP-32 path, e.g. m/44'/0'/0'")
|
||||||
@click.option("-e", "--curve")
|
@click.option("-e", "--curve")
|
||||||
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS), default="address")
|
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS))
|
||||||
@click.option("-d", "--show-display", is_flag=True)
|
@click.option("-d", "--show-display", is_flag=True)
|
||||||
@with_client
|
@with_client
|
||||||
def get_public_node(
|
def get_public_node(
|
||||||
@ -179,11 +210,13 @@ def get_public_node(
|
|||||||
coin: str,
|
coin: str,
|
||||||
address: str,
|
address: str,
|
||||||
curve: Optional[str],
|
curve: Optional[str],
|
||||||
script_type: messages.InputScriptType,
|
script_type: Optional[messages.InputScriptType],
|
||||||
show_display: bool,
|
show_display: bool,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Get public node of given path."""
|
"""Get public node of given path."""
|
||||||
address_n = tools.parse_path(address)
|
address_n = tools.parse_path(address)
|
||||||
|
if script_type is None:
|
||||||
|
script_type = guess_script_type_from_path(address_n)
|
||||||
result = btc.get_public_node(
|
result = btc.get_public_node(
|
||||||
client,
|
client,
|
||||||
address_n,
|
address_n,
|
||||||
@ -332,7 +365,7 @@ def sign_tx(client: "TrezorClient", json_file: TextIO) -> None:
|
|||||||
@cli.command()
|
@cli.command()
|
||||||
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
||||||
@click.option("-n", "--address", required=True, help="BIP-32 path")
|
@click.option("-n", "--address", required=True, help="BIP-32 path")
|
||||||
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS), default="address")
|
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS))
|
||||||
@click.option(
|
@click.option(
|
||||||
"-e",
|
"-e",
|
||||||
"--electrum-compat",
|
"--electrum-compat",
|
||||||
@ -346,11 +379,13 @@ def sign_message(
|
|||||||
coin: str,
|
coin: str,
|
||||||
address: str,
|
address: str,
|
||||||
message: str,
|
message: str,
|
||||||
script_type: messages.InputScriptType,
|
script_type: Optional[messages.InputScriptType],
|
||||||
electrum_compat: bool,
|
electrum_compat: bool,
|
||||||
) -> Dict[str, str]:
|
) -> Dict[str, str]:
|
||||||
"""Sign message using address of given path."""
|
"""Sign message using address of given path."""
|
||||||
address_n = tools.parse_path(address)
|
address_n = tools.parse_path(address)
|
||||||
|
if script_type is None:
|
||||||
|
script_type = guess_script_type_from_path(address_n)
|
||||||
res = btc.sign_message(
|
res = btc.sign_message(
|
||||||
client, coin, address_n, message, script_type, electrum_compat
|
client, coin, address_n, message, script_type, electrum_compat
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user