mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 05:03:07 +00:00
python/trezorctl: support multisig addresses in get-address
This commit is contained in:
parent
cea634158a
commit
95f33a77c7
@ -12,6 +12,7 @@ _At the moment, the project does **not** adhere to [Semantic Versioning](https:/
|
||||
### Added
|
||||
|
||||
- `trezorctl set unsafe-prompts` controls the new "unsafe prompts" feature. [#1126]
|
||||
- `trezorctl btc get-address` can create multisig addresses.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -18,6 +18,7 @@ import base64
|
||||
import json
|
||||
|
||||
import click
|
||||
import construct as c
|
||||
|
||||
from .. import btc, messages, protobuf, tools
|
||||
from . import ChoiceType, with_client
|
||||
@ -37,6 +38,34 @@ OUTPUT_SCRIPTS = {
|
||||
DEFAULT_COIN = "Bitcoin"
|
||||
|
||||
|
||||
XpubStruct = c.Struct(
|
||||
"version" / c.Int32ub,
|
||||
"depth" / c.Int8ub,
|
||||
"fingerprint" / c.Int32ub,
|
||||
"child_num" / c.Int32ub,
|
||||
"chain_code" / c.Bytes(32),
|
||||
"key" / c.Bytes(33),
|
||||
c.Terminated,
|
||||
)
|
||||
|
||||
|
||||
def xpub_deserialize(xpubstr):
|
||||
xpub_bytes = tools.b58check_decode(xpubstr)
|
||||
data = XpubStruct.parse(xpub_bytes)
|
||||
node = messages.HDNodeType(
|
||||
depth=data.depth,
|
||||
fingerprint=data.fingerprint,
|
||||
child_num=data.child_num,
|
||||
chain_code=data.chain_code,
|
||||
)
|
||||
if data.key[0] == 0:
|
||||
node.private_key = data.key[1:]
|
||||
else:
|
||||
node.public_key = data.key
|
||||
|
||||
return data.version, node
|
||||
|
||||
|
||||
@click.group(name="btc")
|
||||
def cli():
|
||||
"""Bitcoin and Bitcoin-like coins commands."""
|
||||
@ -52,13 +81,66 @@ def cli():
|
||||
@click.option("-n", "--address", required=True, help="BIP-32 path")
|
||||
@click.option("-t", "--script-type", type=ChoiceType(INPUT_SCRIPTS), default="address")
|
||||
@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")
|
||||
@click.option(
|
||||
"-N",
|
||||
"--multisig-suffix-length",
|
||||
help="BIP-32 suffix length for multisig",
|
||||
type=int,
|
||||
default=2,
|
||||
)
|
||||
@with_client
|
||||
def get_address(client, coin, address, script_type, show_display):
|
||||
"""Get address for specified path."""
|
||||
def get_address(
|
||||
client,
|
||||
coin,
|
||||
address,
|
||||
script_type,
|
||||
show_display,
|
||||
multisig_xpub,
|
||||
multisig_threshold,
|
||||
multisig_suffix_length,
|
||||
):
|
||||
"""Get address for specified path.
|
||||
|
||||
To obtain a multisig address, provide XPUBs of all signers (including your own) in
|
||||
the intended order. All XPUBs should be on the same level. By default, it is assumed
|
||||
that the XPUBs are on the account level, and the last two components of --address
|
||||
should be derived from all of them.
|
||||
|
||||
For BIP-45 multisig:
|
||||
|
||||
$ trezorctl btc get-public-node -n m/45h/0
|
||||
xpub0101
|
||||
$ trezorctl btc get-address -n m/45h/0/0/7 -m 3 -x xpub0101 -x xpub0202 -x xpub0303
|
||||
|
||||
This assumes that the other signers also created xpubs at address "m/45h/i".
|
||||
For all the signers, the final keys will be derived with the "/0/7" suffix.
|
||||
|
||||
You can specify a different suffix length by using the -N option. For example, to
|
||||
use final xpubs, specify '-N 0'.
|
||||
"""
|
||||
coin = coin or DEFAULT_COIN
|
||||
address_n = tools.parse_path(address)
|
||||
|
||||
if multisig_xpub:
|
||||
if multisig_threshold is None:
|
||||
raise click.ClickException("Please specify signature threshold")
|
||||
|
||||
multisig_suffix = address_n[-multisig_suffix_length:]
|
||||
nodes = [xpub_deserialize(x)[1] for x in multisig_xpub]
|
||||
multisig = messages.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=multisig_suffix, m=multisig_threshold
|
||||
)
|
||||
if script_type == messages.InputScriptType.SPENDADDRESS:
|
||||
script_type = messages.InputScriptType.SPENDMULTISIG
|
||||
return btc.get_address(
|
||||
client, coin, address_n, show_display, script_type=script_type
|
||||
client,
|
||||
coin,
|
||||
address_n,
|
||||
show_display,
|
||||
script_type=script_type,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user