Skip to content

Commit

Permalink
displayaddress: descriptor support, make --path a named argument
Browse files Browse the repository at this point in the history
  • Loading branch information
Sjors committed Feb 2, 2019
1 parent 1826049 commit c161d8f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
6 changes: 4 additions & 2 deletions hwilib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def backup_device_handler(args, client):
return backup_device(client, label=args.label, backup_passphrase=args.backup_passphrase)

def displayaddress_handler(args, client):
return displayaddress(client, path=args.path, sh_wpkh=args.sh_wpkh, wpkh=args.wpkh)
return displayaddress(client, desc=args.desc, path=args.path, sh_wpkh=args.sh_wpkh, wpkh=args.wpkh)

def enumerate_handler(args):
return enumerate(password=args.password)
Expand Down Expand Up @@ -95,7 +95,9 @@ def process_commands(args):
getkeypool_parser.set_defaults(func=getkeypool_handler)

displayaddr_parser = subparsers.add_parser('displayaddress', help='Display an address')
displayaddr_parser.add_argument('path', help='The BIP 32 derivation path of the key embedded in the address')
group = displayaddr_parser.add_mutually_exclusive_group()
group.add_argument('--desc', help='Descriptor request for which to return a descriptor with keys, e.g. wpkh([00000000/84h/1h/0h]/0/*). Alternatively, use --path with --sh_wpkh / --wpkh')
group.add_argument('--path', help='The BIP 32 derivation path of the key embedded in the address, default follows BIP43 convention, e.g. m/84h/0h/0h/1/*')
displayaddr_parser.add_argument('--sh_wpkh', action='store_true', help='Display the p2sh-nested segwit address associated with this key path')
displayaddr_parser.add_argument('--wpkh', action='store_true', help='Display the bech32 version of the address associated with this key path')
displayaddr_parser.set_defaults(func=displayaddress_handler)
Expand Down
22 changes: 18 additions & 4 deletions hwilib/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .base58 import xpub_to_address, xpub_to_pub_hex, get_xpub_fingerprint_as_id, get_xpub_fingerprint_hex
from os.path import dirname, basename, isfile
from .hwwclient import NoPasswordError, UnavailableActionError, DeviceAlreadyInitError, DeviceAlreadyUnlockedError
from .descriptor import Descriptor

# Error codes
NO_DEVICE_PATH = -1
Expand Down Expand Up @@ -184,10 +185,23 @@ def getkeypool(client, path, start, end, internal=False, keypool=False, account=
import_data.append(this_import)
return import_data

def displayaddress(client, path, sh_wpkh=False, wpkh=False):
if sh_wpkh == True and wpkh == True:
return {'error':'Both `--wpkh` and `--sh_wpkh` can not be selected at the same time.','code':BAD_ARGUMENT}
return client.display_address(path, sh_wpkh, wpkh)
def displayaddress(client, path=None, desc=None, sh_wpkh=False, wpkh=False):
if path is not None:
if sh_wpkh == True and wpkh == True:
return {'error':'Both `--wpkh` and `--sh_wpkh` can not be selected at the same time.','code':BAD_ARGUMENT}
client.display_address(path, sh_wpkh, wpkh)
elif desc is not None:
descriptor = Descriptor.parse(desc, client.is_testnet)
if descriptor is None:
return {'error':'Unable to parse descriptor: ' + desc,'code':BAD_ARGUMENT}
if descriptor.m_path is None:
return {'error':'Descriptor missing origin info: ' + desc,'code':BAD_ARGUMENT}
if descriptor.origin_fingerprint != client.fingerprint:
return {'error':'Descriptor fingerprint does not match device: ' + desc,'code':BAD_ARGUMENT}
xpub = client.get_pubkey_at_path(descriptor.m_path_base)['xpub']
if descriptor.base_key != xpub:
return {'error':'Key in descriptor does not match device: ' + desc,'code':BAD_ARGUMENT}
client.display_address(descriptor.m_path, descriptor.sh_wpkh, descriptor.wpkh)

def setup_device(client, label='', backup_passphrase=''):
try:
Expand Down
9 changes: 5 additions & 4 deletions test/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,16 @@ def tearDown(self):
self.emulator.stop()

def test_display_address_bad_args(self):
result = process_commands(self.dev_args + ['displayaddress', '--sh_wpkh', '--wpkh', 'm/49h/1h/0h/0/0'])
result = process_commands(self.dev_args + ['displayaddress', '--sh_wpkh', '--wpkh', '--path', 'm/49h/1h/0h/0/0'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['code'], -7)

def test_display_address(self):
process_commands(self.dev_args + ['displayaddress', 'm/44h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--sh_wpkh', 'm/49h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--wpkh', 'm/84h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--path', 'm/44h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--sh_wpkh', '--path', 'm/49h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--wpkh', '--path', 'm/84h/1h/0h/0/0'])
process_commands(self.dev_args + ['displayaddress', '--desc', 'wpkh(m/84h/1h/0h/0/0)'])

class TestSignMessage(DeviceTestCase):
def setUp(self):
Expand Down

0 comments on commit c161d8f

Please sign in to comment.