diff --git a/hwilib/commands.py b/hwilib/commands.py index f927bed..08bc81e 100644 --- a/hwilib/commands.py +++ b/hwilib/commands.py @@ -14,7 +14,7 @@ import getpass from .serializations import PSBT, Base64ToHex, HexToBase64, hash160 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 +from .hwwclient import NoPasswordError, UnavailableActionError, DeviceAlreadyInitError # Error codes NO_DEVICE_PATH = -1 @@ -25,6 +25,8 @@ INVALID_TX = -5 NO_PASSWORD = -6 BAD_ARGUMENT = -7 NOT_IMPLEMENTED = -8 +UNAVAILABLE_ACTION = -9 +DEVICE_ALREADY_INIT = -10 class UnknownDeviceError(Exception): def __init__(self,*args,**kwargs): @@ -196,6 +198,16 @@ def displayaddress(args, client): return {'error':'Both `--wpkh` and `--sh_wpkh` can not be selected at the same time.','code':BAD_ARGUMENT} return client.display_address(args.path, args.sh_wpkh, args.wpkh) +def setup_device(args, client): + try: + return client.setup_device(args.label, args.backup_passphrase) + except UnavailableActionError as e: + return {'error': str(e), 'code': UNAVAILABLE_ACTION} + except DeviceAlreadyInitError as e: + return {'error': str(e), 'code': DEVICE_ALREADY_INIT} + except ValueError as e: + return {'error': str(e), 'code': BAD_ARGUMENT} + def process_commands(args): parser = argparse.ArgumentParser(description='Access and send commands to a hardware wallet device. Responses are in JSON format') parser.add_argument('--device-path', '-d', help='Specify the device path of the device to connect to') @@ -246,6 +258,11 @@ def process_commands(args): 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) + setupdev_parser = subparsers.add_parser('setup', help='Setup a device. Passphrase protection uses the password given by -p') + setupdev_parser.add_argument('--label', '-l', help='The name to give to the device', default='') + setupdev_parser.add_argument('--backup_passphrase', '-b', help='The passphrase to use for the backup, if applicable', default='') + setupdev_parser.set_defaults(func=setup_device) + args = parser.parse_args(args) device_path = args.device_path diff --git a/hwilib/devices/coldcard.py b/hwilib/devices/coldcard.py index ba99fa0..ea1fb04 100644 --- a/hwilib/devices/coldcard.py +++ b/hwilib/devices/coldcard.py @@ -101,7 +101,7 @@ class ColdcardClient(HardwareWalletClient): raise NotImplementedError('The Coldcard does not currently implement displayaddress') # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The Coldcard does not currently implement setup') # Wipe this device diff --git a/hwilib/devices/digitalbitbox.py b/hwilib/devices/digitalbitbox.py index ab36f7b..ca372da 100644 --- a/hwilib/devices/digitalbitbox.py +++ b/hwilib/devices/digitalbitbox.py @@ -355,7 +355,7 @@ class DigitalbitboxClient(HardwareWalletClient): raise NotImplementedError('The DigitalBitbox does not currently implement displayaddress') # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The DigitalBitbox does not currently implement setup') # Wipe this device diff --git a/hwilib/devices/keepkey.py b/hwilib/devices/keepkey.py index 76759d6..ee84da6 100644 --- a/hwilib/devices/keepkey.py +++ b/hwilib/devices/keepkey.py @@ -180,7 +180,7 @@ class KeepkeyClient(HardwareWalletClient): raise NotImplementedError('The KeepKey does not currently implement displayaddress') # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The KeepKey does not currently implement setup') # Wipe this device diff --git a/hwilib/devices/ledger.py b/hwilib/devices/ledger.py index 35bb60b..f406a01 100644 --- a/hwilib/devices/ledger.py +++ b/hwilib/devices/ledger.py @@ -248,7 +248,7 @@ class LedgerClient(HardwareWalletClient): self.app.getWalletPublicKey(keypath[2:], True, (p2sh_p2wpkh or bech32), bech32) # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The Ledger Nano S does not support software setup') # Wipe this device diff --git a/hwilib/devices/trezor.py b/hwilib/devices/trezor.py index 8036ad1..492af23 100644 --- a/hwilib/devices/trezor.py +++ b/hwilib/devices/trezor.py @@ -191,7 +191,7 @@ class TrezorClient(HardwareWalletClient): ) # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The Trezor does not currently implement setup') # Wipe this device diff --git a/hwilib/hwwclient.py b/hwilib/hwwclient.py index d93e4d7..bb8dbd2 100644 --- a/hwilib/hwwclient.py +++ b/hwilib/hwwclient.py @@ -32,7 +32,7 @@ class HardwareWalletClient(object): 'implement this method') # Setup a new device - def setup_device(self): + def setup_device(self, label='', passphrase=''): raise NotImplementedError('The HardwareWalletClient base class does not ' 'implement this method') @@ -49,3 +49,11 @@ class HardwareWalletClient(object): class NoPasswordError(Exception): def __init__(self,*args,**kwargs): Exception.__init__(self,*args,**kwargs) + +class UnavailableActionError(Exception): + def __init__(self,*args,**kwargs): + Exception.__init__(self,*args,**kwargs) + +class DeviceAlreadyInitError(Exception): + def __init__(self,*args,**kwargs): + Exception.__init__(self,*args,**kwargs)