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,
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@ -85,6 +98,22 @@ def xpub_deserialize(xpubstr: str) -> Tuple[str, messages.HDNodeType]:
|
||||
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")
|
||||
def cli() -> None:
|
||||
"""Bitcoin and Bitcoin-like coins commands."""
|
||||
@ -98,7 +127,7 @@ def cli() -> None:
|
||||
@cli.command()
|
||||
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
||||
@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("-x", "--multisig-xpub", multiple=True, help="XPUBs of multisig owners")
|
||||
@click.option("-m", "--multisig-threshold", type=int, help="Number of signatures")
|
||||
@ -114,7 +143,7 @@ def get_address(
|
||||
client: "TrezorClient",
|
||||
coin: str,
|
||||
address: str,
|
||||
script_type: messages.InputScriptType,
|
||||
script_type: Optional[messages.InputScriptType],
|
||||
show_display: bool,
|
||||
multisig_xpub: List[str],
|
||||
multisig_threshold: Optional[int],
|
||||
@ -141,6 +170,8 @@ def get_address(
|
||||
use final xpubs, specify '-N 0'.
|
||||
"""
|
||||
address_n = tools.parse_path(address)
|
||||
if script_type is None:
|
||||
script_type = guess_script_type_from_path(address_n)
|
||||
|
||||
multisig: Optional[messages.MultisigRedeemScriptType]
|
||||
if multisig_xpub:
|
||||
@ -171,7 +202,7 @@ def get_address(
|
||||
@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("-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)
|
||||
@with_client
|
||||
def get_public_node(
|
||||
@ -179,11 +210,13 @@ def get_public_node(
|
||||
coin: str,
|
||||
address: str,
|
||||
curve: Optional[str],
|
||||
script_type: messages.InputScriptType,
|
||||
script_type: Optional[messages.InputScriptType],
|
||||
show_display: bool,
|
||||
) -> dict:
|
||||
"""Get public node of given path."""
|
||||
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(
|
||||
client,
|
||||
address_n,
|
||||
@ -332,7 +365,7 @@ def sign_tx(client: "TrezorClient", json_file: TextIO) -> None:
|
||||
@cli.command()
|
||||
@click.option("-c", "--coin", default=DEFAULT_COIN)
|
||||
@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(
|
||||
"-e",
|
||||
"--electrum-compat",
|
||||
@ -346,11 +379,13 @@ def sign_message(
|
||||
coin: str,
|
||||
address: str,
|
||||
message: str,
|
||||
script_type: messages.InputScriptType,
|
||||
script_type: Optional[messages.InputScriptType],
|
||||
electrum_compat: bool,
|
||||
) -> Dict[str, str]:
|
||||
"""Sign message using address of given path."""
|
||||
address_n = tools.parse_path(address)
|
||||
if script_type is None:
|
||||
script_type = guess_script_type_from_path(address_n)
|
||||
res = btc.sign_message(
|
||||
client, coin, address_n, message, script_type, electrum_compat
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user