Skip to content

Commit 1ec25ac

Browse files
committed
Add register command for BIP388 policies
1 parent a56fdad commit 1ec25ac

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

hwilib/_cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
getdescriptors,
1313
prompt_pin,
1414
toggle_passphrase,
15+
register,
1516
restore_device,
1617
send_pin,
1718
setup_device,
@@ -59,6 +60,9 @@ def backup_device_handler(args: argparse.Namespace, client: HardwareWalletClient
5960
def displayaddress_handler(args: argparse.Namespace, client: HardwareWalletClient) -> Dict[str, str]:
6061
return displayaddress(client, desc=args.desc, path=args.path, addr_type=args.addr_type)
6162

63+
def register_handler(args: argparse.Namespace, client: HardwareWalletClient) -> Dict[str, str]:
64+
return register(client, name=args.name, descriptor_template=args.desc, keys_info=args.key)
65+
6266
def enumerate_handler(args: argparse.Namespace) -> List[Dict[str, Any]]:
6367
return enumerate(password=args.password, expert=args.expert, chain=args.chain, allow_emulators=args.allow_emulators)
6468

@@ -202,6 +206,12 @@ def get_parser() -> HWIArgumentParser:
202206
displayaddr_parser.add_argument("--addr-type", help="The address type to display", type=AddressType.argparse, choices=list(AddressType), default=AddressType.WIT) # type: ignore
203207
displayaddr_parser.set_defaults(func=displayaddress_handler)
204208

209+
register_parser = subparsers.add_parser('register', help='Register a BIP388 wallet policy')
210+
register_parser.add_argument('--name', help='Name for the policy')
211+
register_parser.add_argument('--desc', help='Descriptor template, e.g. tr(musig(@0,@1)')
212+
register_parser.add_argument('--key', help='Key information, e.g. [00000000/84h/0h/0h]xpub...', action='append')
213+
register_parser.set_defaults(func=register_handler)
214+
205215
setupdev_parser = subparsers.add_parser('setup', help='Setup a device. Passphrase protection uses the password given by -p. Requires interactive mode')
206216
setupdev_parser.add_argument('--label', '-l', help='The name to give to the device', default='')
207217
setupdev_parser.add_argument('--backup_passphrase', '-b', help='The passphrase to use for the backup, if applicable', default='')

hwilib/commands.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,24 @@ def displayaddress(
499499
return {"address": client.display_singlesig_address(pubkey.get_full_derivation_path(0), addr_type)}
500500
raise BadArgumentError("Missing both path and descriptor")
501501

502+
def register(
503+
client: HardwareWalletClient,
504+
name: str,
505+
descriptor_template: str,
506+
keys_info: List[str],
507+
) -> Dict[str, str]:
508+
"""
509+
Register a BIP388 policy on the device for client.
510+
511+
:param name: Name for the policy
512+
:param desc: Descriptor template
513+
:return: A dictionary containing policy HMAC.
514+
Returned as ``{"hmac": <hex string>}``.
515+
:raises: BadArgumentError: if an argument is malformed, missing, or conflicts.
516+
"""
517+
518+
return {"hmac": client.register_bip388_policy(name, descriptor_template, keys_info)}
519+
502520
def setup_device(client: HardwareWalletClient, label: str = "", backup_passphrase: str = "") -> Dict[str, bool]:
503521
"""
504522
Setup a device that has not yet been initialized.

hwilib/devices/ledger.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,26 @@ def format_key_info(pubkey: PubkeyProvider) -> str:
525525

526526
return self.client.get_wallet_address(multisig_wallet, registered_hmac, change, address_index, True)
527527

528+
@ledger_exception
529+
def register_bip388_policy(
530+
self,
531+
name: str,
532+
descriptor_template: str,
533+
keys_info: List[str],
534+
) -> str:
535+
if isinstance(self.client, LegacyClient):
536+
raise BadArgumentError("Registering a BIP388 policy not supported by this version of the Bitcoin App")
537+
538+
wallet_policy = WalletPolicy(
539+
name=name,
540+
descriptor_template=descriptor_template,
541+
keys_info=keys_info
542+
)
543+
544+
_, registered_hmac = self.client.register_wallet(wallet_policy)
545+
546+
return registered_hmac.hex()
547+
528548
def setup_device(self, label: str = "", passphrase: str = "") -> bool:
529549
"""
530550
Ledgers do not support setup via software.

hwilib/hwwclient.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from typing import (
99
Dict,
10+
List,
1011
Optional,
1112
Union,
1213
)
@@ -139,6 +140,18 @@ def display_multisig_address(
139140
raise NotImplementedError("The HardwareWalletClient base class "
140141
"does not implement this method")
141142

143+
def register_bip388_policy(
144+
self,
145+
name: str,
146+
policy: str,
147+
keys_info: List[str]) -> str:
148+
"""
149+
Register a BIP388 policy.
150+
151+
:return: The policy HMAC
152+
"""
153+
raise NotImplementedError("This device does not support BIP388 policies or it's not yet implemented")
154+
142155
def wipe_device(self) -> bool:
143156
"""
144157
Wipe the device.

0 commit comments

Comments
 (0)