diff --git a/hwilib/__init__.py b/hwilib/__init__.py index 3d67cd6bb..4cb28cbd1 100644 --- a/hwilib/__init__.py +++ b/hwilib/__init__.py @@ -1 +1 @@ -__version__ = "2.4.0" +__version__ = "3.0.0-dev" diff --git a/hwilib/_cli.py b/hwilib/_cli.py index acd4b2578..e0afa7dd2 100644 --- a/hwilib/_cli.py +++ b/hwilib/_cli.py @@ -60,7 +60,7 @@ def displayaddress_handler(args: argparse.Namespace, client: HardwareWalletClien return displayaddress(client, desc=args.desc, path=args.path, addr_type=args.addr_type) def enumerate_handler(args: argparse.Namespace) -> List[Dict[str, Any]]: - return enumerate(password=args.password, expert=args.expert, chain=args.chain) + return enumerate(password=args.password, expert=args.expert, chain=args.chain, allow_emulators=args.allow_emulators) def getmasterxpub_handler(args: argparse.Namespace, client: HardwareWalletClient) -> Dict[str, str]: return getmasterxpub(client, addrtype=args.addr_type, account=args.account) @@ -145,6 +145,7 @@ def get_parser() -> HWIArgumentParser: parser.add_argument('--stdin', help='Enter commands and arguments via stdin', action='store_true') parser.add_argument('--interactive', '-i', help='Use some commands interactively. Currently required for all device configuration commands', action='store_true') parser.add_argument('--expert', help='Do advanced things and get more detailed information returned from some commands. Use at your own risk.', action='store_true') + parser.add_argument("--emulators", help="Enable enumeration and detection of device emulators", action="store_true", dest="allow_emulators") subparsers = parser.add_subparsers(description='Commands', dest='command') # work-around to make subparser required @@ -277,9 +278,9 @@ def process_commands(cli_args: List[str]) -> Any: # Auto detect if we are using fingerprint or type to identify device if args.fingerprint or (args.device_type and not args.device_path): - client = find_device(args.password, args.device_type, args.fingerprint, args.expert, args.chain) + client = find_device(args.password, args.device_type, args.fingerprint, args.expert, args.chain, args.allow_emulators) if not client: - return {'error': 'Could not find device with specified fingerprint', 'code': DEVICE_CONN_ERROR} + return {'error': 'Could not find device with specified fingerprint or type', 'code': DEVICE_CONN_ERROR} elif args.device_type and args.device_path: with handle_errors(result=result, code=DEVICE_CONN_ERROR): client = get_client(device_type, device_path, password, args.expert, args.chain) diff --git a/hwilib/_gui.py b/hwilib/_gui.py index fcbd1ae5b..389a29e21 100644 --- a/hwilib/_gui.py +++ b/hwilib/_gui.py @@ -321,7 +321,7 @@ def attestation_check(self, result: bool) -> None: pass class HWIQt(QMainWindow): - def __init__(self, passphrase=None, chain=Chain.MAIN): + def __init__(self, passphrase=None, chain=Chain.MAIN, allow_emulators: bool = False): super(HWIQt, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) @@ -343,6 +343,7 @@ def __init__(self, passphrase=None, chain=Chain.MAIN): 'path': None, 'account_used': True } + self.allow_emulators = allow_emulators self.ui.enumerate_refresh_button.clicked.connect(self.refresh_clicked) self.ui.setpass_button.clicked.connect(self.show_setpassphrasedialog) @@ -372,7 +373,7 @@ def refresh_clicked(self): self.client.close() self.client = None - self.devices = commands.enumerate(self.passphrase) + self.devices = commands.enumerate(password=self.passphrase, expert=False, chain=self.chain, allow_emulators=self.allow_emulators) self.ui.enumerate_combobox.currentIndexChanged.disconnect() self.ui.enumerate_combobox.clear() self.ui.enumerate_combobox.addItem('') @@ -524,6 +525,7 @@ def process_gui_commands(cli_args): parser.add_argument('--chain', help='Select chain to work with', type=Chain.argparse, choices=list(Chain), default=Chain.MAIN) parser.add_argument('--debug', help='Print debug statements', action='store_true') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) + parser.add_argument("--emulators", help="Enable enumeration and detection of device emulators", action="store_true", dest="allow_emulators") # Parse arguments again for anything entered over stdin args = parser.parse_args(cli_args) @@ -536,7 +538,7 @@ def process_gui_commands(cli_args): # Qt setup app = QApplication() - window = HWIQt(args.password, args.chain) + window = HWIQt(args.password, args.chain, args.allow_emulators) window.refresh_clicked() diff --git a/hwilib/commands.py b/hwilib/commands.py index 92f8d9f45..6d192aa5f 100644 --- a/hwilib/commands.py +++ b/hwilib/commands.py @@ -101,7 +101,7 @@ def get_client(device_type: str, device_path: str, password: Optional[str] = Non return client # Get a list of all available hardware wallets -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: """ Enumerate all of the devices that HWI can potentially access. @@ -114,7 +114,7 @@ def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain for module in all_devs: try: imported_dev = importlib.import_module('.devices.' + module, __package__) - result.extend(imported_dev.enumerate(password, expert, chain)) + result.extend(imported_dev.enumerate(password, expert, chain, allow_emulators)) except ImportError as e: # Warn for ImportErrors, but largely ignore them to allow users not install # all device dependencies if only one or some devices are wanted. @@ -129,6 +129,7 @@ def find_device( fingerprint: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, + allow_emulators: bool = False, ) -> Optional[HardwareWalletClient]: """ Find a device from the device type or fingerprint and get a client to access it. @@ -145,7 +146,7 @@ def find_device( :return: A client to interact with the found device """ - devices = enumerate(password) + devices = enumerate(password, expert, chain, allow_emulators) for d in devices: if device_type is not None and d['type'] != device_type and d['model'] != device_type: continue diff --git a/hwilib/devices/bitbox02.py b/hwilib/devices/bitbox02.py index 3e32517cb..173f9997d 100644 --- a/hwilib/devices/bitbox02.py +++ b/hwilib/devices/bitbox02.py @@ -173,7 +173,7 @@ def _xpubs_equal_ignoring_version(xpub1: bytes, xpub2: bytes) -> bool: return xpub1[4:] == xpub2[4:] -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: """ Enumerate all BitBox02 devices. Bootloaders excluded. """ diff --git a/hwilib/devices/coldcard.py b/hwilib/devices/coldcard.py index c3c9d0269..e64f3619c 100644 --- a/hwilib/devices/coldcard.py +++ b/hwilib/devices/coldcard.py @@ -399,10 +399,11 @@ def can_sign_taproot(self) -> bool: return False -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = True) -> List[Dict[str, Any]]: results = [] devices = hid.enumerate(COINKITE_VID, CKCC_PID) - devices.append({'path': CC_SIMULATOR_SOCK.encode()}) + if allow_emulators: + devices.append({'path': CC_SIMULATOR_SOCK.encode()}) for d in devices: d_data: Dict[str, Any] = {} diff --git a/hwilib/devices/digitalbitbox.py b/hwilib/devices/digitalbitbox.py index a3693b7b9..2733d0a2e 100644 --- a/hwilib/devices/digitalbitbox.py +++ b/hwilib/devices/digitalbitbox.py @@ -679,17 +679,18 @@ def can_sign_taproot(self) -> bool: return False -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: results = [] devices = hid.enumerate(DBB_VENDOR_ID, DBB_DEVICE_ID) # Try connecting to simulator - try: - dev = BitboxSimulator('127.0.0.1', 35345) - dev.send_recv(b'{"device" : "info"}') - devices.append({'path': b'udp:127.0.0.1:35345', 'interface_number': 0}) - dev.close() - except Exception: - pass + if allow_emulators: + try: + dev = BitboxSimulator('127.0.0.1', 35345) + dev.send_recv(b'{"device" : "info"}') + devices.append({'path': b'udp:127.0.0.1:35345', 'interface_number': 0}) + dev.close() + except Exception: + pass for d in devices: if ('interface_number' in d and d['interface_number'] == 0 or ('usage_page' in d and d['usage_page'] == 0xffff)): diff --git a/hwilib/devices/jade.py b/hwilib/devices/jade.py index fdfeed29c..6d471f6fc 100644 --- a/hwilib/devices/jade.py +++ b/hwilib/devices/jade.py @@ -508,7 +508,7 @@ def can_sign_taproot(self) -> bool: return False -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: results = [] def _get_device_entry(device_model: str, device_path: str) -> Dict[str, Any]: @@ -537,16 +537,17 @@ def _get_device_entry(device_model: str, device_path: str) -> Dict[str, Any]: results.append(_get_device_entry('jade', devinfo.device)) # If we can connect to the simulator, add it too - try: - with JadeAPI.create_serial(SIMULATOR_PATH, timeout=1) as jade: - verinfo = jade.get_version_info() + if allow_emulators: + try: + with JadeAPI.create_serial(SIMULATOR_PATH, timeout=1) as jade: + verinfo = jade.get_version_info() - if verinfo is not None: - results.append(_get_device_entry('jade_simulator', SIMULATOR_PATH)) + if verinfo is not None: + results.append(_get_device_entry('jade_simulator', SIMULATOR_PATH)) - except Exception as e: - # If we get any sort of error do not add the simulator - logging.debug(f'Failed to connect to Jade simulator at {SIMULATOR_PATH}') - logging.debug(e) + except Exception as e: + # If we get any sort of error do not add the simulator + logging.debug(f'Failed to connect to Jade simulator at {SIMULATOR_PATH}') + logging.debug(e) return results diff --git a/hwilib/devices/keepkey.py b/hwilib/devices/keepkey.py index 4412a8d95..21845e955 100644 --- a/hwilib/devices/keepkey.py +++ b/hwilib/devices/keepkey.py @@ -172,11 +172,12 @@ def can_sign_taproot(self) -> bool: return False -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: results = [] devs = hid.HidTransport.enumerate(usb_ids=KEEPKEY_HID_IDS) devs.extend(webusb.WebUsbTransport.enumerate(usb_ids=KEEPKEY_WEBUSB_IDS)) - devs.extend(udp.UdpTransport.enumerate(KEEPKEY_SIMULATOR_PATH)) + if allow_emulators: + devs.extend(udp.UdpTransport.enumerate(KEEPKEY_SIMULATOR_PATH)) for dev in devs: d_data: Dict[str, Any] = {} diff --git a/hwilib/devices/ledger.py b/hwilib/devices/ledger.py index d0620e77d..45dd5c2ca 100644 --- a/hwilib/devices/ledger.py +++ b/hwilib/devices/ledger.py @@ -546,11 +546,12 @@ def can_sign_taproot(self) -> bool: return isinstance(self.client, NewClient) -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: results = [] devices = [] devices.extend(hid.enumerate(LEDGER_VENDOR_ID, 0)) - devices.append({'path': SIMULATOR_PATH.encode(), 'interface_number': 0, 'product_id': 0x1000}) + if allow_emulators: + devices.append({'path': SIMULATOR_PATH.encode(), 'interface_number': 0, 'product_id': 0x1000}) for d in devices: if ('interface_number' in d and d['interface_number'] == 0 diff --git a/hwilib/devices/trezor.py b/hwilib/devices/trezor.py index d3412d43d..bd5a79733 100644 --- a/hwilib/devices/trezor.py +++ b/hwilib/devices/trezor.py @@ -851,11 +851,12 @@ def can_sign_taproot(self) -> bool: return True -def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: +def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN, allow_emulators: bool = False) -> List[Dict[str, Any]]: results = [] devs = hid.HidTransport.enumerate() devs.extend(webusb.WebUsbTransport.enumerate()) - devs.extend(udp.UdpTransport.enumerate()) + if allow_emulators: + devs.extend(udp.UdpTransport.enumerate()) for dev in devs: d_data: Dict[str, Any] = {} diff --git a/pyproject.toml b/pyproject.toml index 8b341f94e..40dd17499 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hwi" -version = "2.4.0" +version = "3.0.0-dev" description = "A library for working with Bitcoin hardware wallets" authors = ["Ava Chow "] license = "MIT" diff --git a/setup.py b/setup.py index 37075cc00..7d0253756 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ setup_kwargs = { 'name': 'hwi', - 'version': '2.4.0', + 'version': '3.0.0.dev0', 'description': 'A library for working with Bitcoin hardware wallets', 'long_description': "# Bitcoin Hardware Wallet Interface\n\n[![Build Status](https://api.cirrus-ci.com/github/bitcoin-core/HWI.svg)](https://cirrus-ci.com/github/bitcoin-core/HWI)\n[![Documentation Status](https://readthedocs.org/projects/hwi/badge/?version=latest)](https://hwi.readthedocs.io/en/latest/?badge=latest)\n\nThe Bitcoin Hardware Wallet Interface is a Python library and command line tool for interacting with hardware wallets.\nIt provides a standard way for software to work with hardware wallets without needing to implement device specific drivers.\nPython software can use the provided library (`hwilib`). Software in other languages can execute the `hwi` tool.\n\nCaveat emptor: Inclusion of a specific hardware wallet vendor does not imply any endorsement of quality or security.\n\n## Prerequisites\n\nPython 3 is required. The libraries and [udev rules](hwilib/udev/README.md) for each device must also be installed. Some libraries will need to be installed\n\nFor Ubuntu/Debian:\n```\nsudo apt install libusb-1.0-0-dev libudev-dev python3-dev\n```\n\nFor Centos:\n```\nsudo yum -y install python3-devel libusbx-devel systemd-devel\n```\n\nFor macOS:\n```\nbrew install libusb\n```\n\n## Install\n\n```\ngit clone https://github.com/bitcoin-core/HWI.git\ncd HWI\npoetry install # or 'pip3 install .' or 'python3 setup.py install'\n```\n\nThis project uses the [Poetry](https://github.com/sdispater/poetry) dependency manager. HWI and its dependencies can be installed via poetry by executing the following in the root source directory:\n\n```\npoetry install\n```\n\nPip can also be used to automatically install HWI and its dependencies using the `setup.py` file (which is usually in sync with `pyproject.toml`):\n\n```\npip3 install .\n```\n\nThe `setup.py` file can be used to install HWI and its dependencies so long as `setuptools` is also installed:\n\n```\npip3 install -U setuptools\npython3 setup.py install\n```\n\n## Dependencies\n\nSee `pyproject.toml` for all dependencies. Dependencies under `[tool.poetry.dependencies]` are user dependencies, and `[tool.poetry.dev-dependencies]` for development based dependencies. These dependencies will be installed with any of the three above installation methods.\n\n## Usage\n\nTo use, first enumerate all devices and find the one that you want to use with\n\n```\n./hwi.py enumerate\n```\n\nOnce the device type and device path are known, issue commands to it like so:\n\n```\n./hwi.py -t -d \n```\n\nAll output will be in JSON form and sent to `stdout`.\nAdditional information or prompts will be sent to `stderr` and will not necessarily be in JSON.\nThis additional information is for debugging purposes.\n\nTo see a complete list of available commands and global parameters, run\n`./hwi.py --help`. To see options specific to a particular command,\npass the `--help` parameter after the command name; for example:\n\n```\n./hwi.py getdescriptors --help\n```\n\n## Documentation\n\nDocumentation for HWI can be found on [readthedocs.io](https://hwi.readthedocs.io/).\n\n### Device Support\n\nFor documentation on devices supported and how they are supported, please check the [device support page](https://hwi.readthedocs.io/en/latest/devices/index.html#support-matrix)\n\n### Using with Bitcoin Core\n\nSee [Using Bitcoin Core with Hardware Wallets](https://hwi.readthedocs.io/en/latest/examples/bitcoin-core-usage.html).\n\n## License\n\nThis project is available under the MIT License, Copyright Andrew Chow.\n", 'author': 'Ava Chow', diff --git a/test/test_coldcard.py b/test/test_coldcard.py index d049647b3..56ac8ea5a 100755 --- a/test/test_coldcard.py +++ b/test/test_coldcard.py @@ -61,7 +61,7 @@ def start(self): # Wait for simulator to be up while True: try: - enum_res = process_commands(["enumerate"]) + enum_res = process_commands(["--emulators", "enumerate"]) found = False for dev in enum_res: if dev["type"] == "coldcard" and "error" not in dev: diff --git a/test/test_device.py b/test/test_device.py index 0b52aa916..d87fc6017 100644 --- a/test/test_device.py +++ b/test/test_device.py @@ -201,7 +201,7 @@ def __init__(self, *args, detect_type, **kwargs): self.detect_type = detect_type def test_enumerate(self): - enum_res = self.do_command(self.get_password_args() + ['enumerate']) + enum_res = self.do_command(self.get_password_args() + ["--emulators", "enumerate"]) found = False for device in enum_res: if (device['type'] == self.detect_type or device['model'] == self.detect_type) and device['path'] == self.emulator.path and device['fingerprint'] == self.emulator.fingerprint: @@ -215,32 +215,42 @@ def test_enumerate(self): found = True self.assertTrue(found) + def test_no_emus(self): + res = self.do_command(self.get_password_args() + ["enumerate"]) + self.assertEqual(len(res), 0) + res = self.do_command(self.get_password_args() + ["-f", self.emulator.fingerprint, "--chain", "test", "getmasterxpub", "--addr-type", "legacy"]) + self.assertEqual(res['error'], 'Could not find device with specified fingerprint or type') + self.assertEqual(res['code'], -3) + res = self.do_command(self.get_password_args() + ["-t", self.detect_type, "--chain", "test", "getmasterxpub", "--addr-type", "legacy"]) + self.assertEqual(res['error'], 'Could not find device with specified fingerprint or type') + self.assertEqual(res['code'], -3) + def test_no_type(self): - gmxp_res = self.do_command(["--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(["--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertIn('error', gmxp_res) self.assertEqual(gmxp_res['error'], 'You must specify a device type or fingerprint for all commands except enumerate') self.assertIn('code', gmxp_res) self.assertEqual(gmxp_res['code'], -1) def test_path_type(self): - gmxp_res = self.do_command(self.get_password_args() + ['-t', self.detect_type, '-d', self.emulator.path, "--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(self.get_password_args() + ["-t", self.detect_type, "-d", self.emulator.path, "--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['xpub'], self.emulator.master_xpub) def test_fingerprint_autodetect(self): - gmxp_res = self.do_command(self.get_password_args() + ['-f', self.emulator.fingerprint, "--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(self.get_password_args() + ["-f", self.emulator.fingerprint, "--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['xpub'], self.emulator.master_xpub) # Nonexistent fingerprint - gmxp_res = self.do_command(self.get_password_args() + ['-f', '0000ffff', "--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) - self.assertEqual(gmxp_res['error'], 'Could not find device with specified fingerprint') + gmxp_res = self.do_command(self.get_password_args() + ["-f", "0000ffff", "--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) + self.assertEqual(gmxp_res['error'], 'Could not find device with specified fingerprint or type') self.assertEqual(gmxp_res['code'], -3) def test_type_only_autodetect(self): - gmxp_res = self.do_command(self.get_password_args() + ['-t', self.detect_type, "--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(self.get_password_args() + ["-t", self.detect_type, "--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['xpub'], self.emulator.master_xpub) # Unknown device type - gmxp_res = self.do_command(['-t', 'fakedev', '-d', 'fakepath', "--chain", "test", 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(["-t", "fakedev", "-d", "fakepath", "--chain", "test", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['error'], 'Unknown device type specified') self.assertEqual(gmxp_res['code'], -4) diff --git a/test/test_keepkey.py b/test/test_keepkey.py index 679e11128..45ccba21f 100755 --- a/test/test_keepkey.py +++ b/test/test_keepkey.py @@ -181,16 +181,16 @@ def test_getxpub(self): load_device_by_mnemonic(client=self.client, mnemonic=vec['mnemonic'], pin='', passphrase_protection=False, label='test', language='english') # Test getmasterxpub - gmxp_res = self.do_command(['-t', 'keepkey', '-d', 'udp:127.0.0.1:11044', 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(["-t", "keepkey", "-d", "udp:127.0.0.1:11044", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['xpub'], vec['master_xpub']) # Test the path derivs for path_vec in vec['vectors']: - gxp_res = self.do_command(['-t', 'keepkey', '-d', 'udp:127.0.0.1:11044', 'getxpub', path_vec['path']]) + gxp_res = self.do_command(["-t", "keepkey", "-d", "udp:127.0.0.1:11044", "--emulators", "getxpub", path_vec["path"]]) self.assertEqual(gxp_res['xpub'], path_vec['xpub']) def test_expert_getxpub(self): - result = self.do_command(['-t', 'keepkey', '-d', 'udp:127.0.0.1:11044', '--expert', 'getxpub', 'm/44h/0h/0h/3']) + result = self.do_command(["-t", "keepkey", "-d", "udp:127.0.0.1:11044", "--expert", "--emulators", "getxpub", "m/44h/0h/0h/3"]) self.assertEqual(result['xpub'], 'xpub6FMafWAi3n3ET2rU5yQr16UhRD1Zx4dELmcEw3NaYeBaNnipcr2zjzYp1sNdwR3aTN37hxAqRWQ13AWUZr6L9jc617mU6EvgYXyBjXrEhgr') self.assertFalse(result['testnet']) self.assertFalse(result['private']) @@ -238,7 +238,7 @@ def test_label(self): result = t_client.setup_device(label='HWI Keepkey') self.assertTrue(result) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertEqual(dev['label'], 'HWI Keepkey') @@ -261,7 +261,7 @@ def test_pins(self): result = self.do_command(self.dev_args + ['sendpin', '1234']) self.assertEqual(result['error'], 'This device does not need a PIN') self.assertEqual(result['code'], -11) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_pin_sent']) @@ -273,7 +273,7 @@ def test_pins(self): device.wipe(self.client) load_device_by_mnemonic(client=self.client, mnemonic='alcohol woman abuse must during monitor noble actual mixed trade anger aisle', pin='1234', passphrase_protection=True, label='test') self.client.call(messages.LockDevice()) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators","enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertTrue(dev['needs_pin_sent']) @@ -307,7 +307,7 @@ def test_pins(self): result = self.do_command(self.dev_args + ["-p", "test", 'sendpin', pin]) self.assertTrue(result['success']) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_pin_sent']) @@ -328,14 +328,14 @@ def test_passphrase(self): self.do_command(self.dev_args + ['togglepassphrase']) # A passphrase will need to be sent - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertTrue(dev['needs_passphrase_sent']) break else: self.fail("Did not enumerate device") - result = self.do_command(self.dev_args + ['-p', 'pass', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_passphrase_sent']) @@ -344,7 +344,7 @@ def test_passphrase(self): else: self.fail("Did not enumerate device") # A different passphrase will change the fingerprint - result = self.do_command(self.dev_args + ['-p', 'pass2', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass2', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_passphrase_sent']) @@ -355,7 +355,7 @@ def test_passphrase(self): # Clearing the session and starting a new one with a new passphrase should change the passphrase self.client.call(messages.LockDevice()) - result = self.do_command(self.dev_args + ['-p', 'pass3', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass3', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_passphrase_sent']) @@ -368,7 +368,7 @@ def test_passphrase(self): self.do_command(self.dev_args + ['togglepassphrase']) # There's no passphrase - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_passphrase_sent']) @@ -377,7 +377,7 @@ def test_passphrase(self): else: self.fail("Did not enumerate device") # Setting a passphrase won't change the fingerprint - result = self.do_command(self.dev_args + ['-p', 'pass', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'keepkey' and dev['path'] == 'udp:127.0.0.1:11044': self.assertFalse(dev['needs_passphrase_sent']) diff --git a/test/test_ledger.py b/test/test_ledger.py index 0cf6444f7..a9a5030af 100755 --- a/test/test_ledger.py +++ b/test/test_ledger.py @@ -79,7 +79,7 @@ def start(self): # Wait for simulator to be up while True: try: - enum_res = process_commands(['enumerate']) + enum_res = process_commands(["--emulators", "enumerate"]) found = False for dev in enum_res: if dev['type'] == 'ledger' and 'error' not in dev: diff --git a/test/test_trezor.py b/test/test_trezor.py index 7b5034596..0b70e0ee4 100755 --- a/test/test_trezor.py +++ b/test/test_trezor.py @@ -175,16 +175,16 @@ def test_getxpub(self): load_device_by_mnemonic(client=self.client, mnemonic=vec['mnemonic'], pin='', passphrase_protection=False, label='test', language='english') # Test getmasterxpub - gmxp_res = self.do_command(['-t', 'trezor', '-d', 'udp:127.0.0.1:21324', 'getmasterxpub', "--addr-type", "legacy"]) + gmxp_res = self.do_command(["-t", "trezor", "-d", "udp:127.0.0.1:21324", "--emulators", "getmasterxpub", "--addr-type", "legacy"]) self.assertEqual(gmxp_res['xpub'], vec['master_xpub']) # Test the path derivs for path_vec in vec['vectors']: - gxp_res = self.do_command(['-t', 'trezor', '-d', 'udp:127.0.0.1:21324', 'getxpub', path_vec['path']]) + gxp_res = self.do_command(["-t", "trezor", "-d", "udp:127.0.0.1:21324", "--emulators", "getxpub", path_vec["path"]]) self.assertEqual(gxp_res['xpub'], path_vec['xpub']) def test_expert_getxpub(self): - result = self.do_command(['-t', 'trezor', '-d', 'udp:127.0.0.1:21324', '--expert', 'getxpub', 'm/44h/0h/0h/3']) + result = self.do_command(["-t", "trezor", "-d", "udp:127.0.0.1:21324", "--expert", "--emulators", "getxpub", "m/44h/0h/0h/3"]) self.assertEqual(result['xpub'], 'xpub6FMafWAi3n3ET2rU5yQr16UhRD1Zx4dELmcEw3NaYeBaNnipcr2zjzYp1sNdwR3aTN37hxAqRWQ13AWUZr6L9jc617mU6EvgYXyBjXrEhgr') self.assertFalse(result['testnet']) self.assertFalse(result['private']) @@ -200,7 +200,7 @@ def setUp(self): self.dev_args = ['-t', 'trezor', '-d', 'udp:127.0.0.1:21324'] def test_label(self): - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertEqual(dev['label'], 'test') @@ -246,7 +246,7 @@ def test_label(self): result = t_client.setup_device(label='HWI Trezor') self.assertTrue(result) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertEqual(dev['label'], 'HWI Trezor') @@ -269,7 +269,7 @@ def test_pins(self): result = self.do_command(self.dev_args + ['sendpin', '1234']) self.assertEqual(result['error'], 'This device does not need a PIN') self.assertEqual(result['code'], -11) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_pin_sent']) @@ -282,7 +282,7 @@ def test_pins(self): load_device_by_mnemonic(client=self.client, mnemonic='alcohol woman abuse must during monitor noble actual mixed trade anger aisle', pin='1234', passphrase_protection=True, label='test') self.client.lock(_refresh_features=False) self.client.end_session() - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertTrue(dev['needs_pin_sent']) @@ -316,7 +316,7 @@ def test_pins(self): result = self.do_command(self.dev_args + ["-p", "asdf", 'sendpin', pin]) self.assertTrue(result['success']) - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_pin_sent']) @@ -337,14 +337,14 @@ def test_passphrase(self): self.do_command(self.dev_args + ['togglepassphrase']) # A passphrase will need to be sent - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertIn("warnings", dev) break else: self.fail("Did not enumerate device") - result = self.do_command(self.dev_args + ['-p', 'pass', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -352,7 +352,7 @@ def test_passphrase(self): break else: self.fail("Did not enumerate device") - result = self.do_command(self.dev_args + ['-p', '\"\"', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', '\"\"', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -363,7 +363,7 @@ def test_passphrase(self): if self.emulator.model == 't': # Trezor T: A different passphrase would not change the fingerprint - result = self.do_command(self.dev_args + ['-p', 'pass2', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass2', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -373,7 +373,7 @@ def test_passphrase(self): self.fail("Did not enumerate device") else: # Trezor 1: A different passphrase will change the fingerprint - result = self.do_command(self.dev_args + ['-p', 'pass2', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass2', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -384,7 +384,7 @@ def test_passphrase(self): # Clearing the session and starting a new one with a new passphrase should change the passphrase self.client.call(messages.Initialize()) - result = self.do_command(self.dev_args + ['-p', 'pass3', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass3', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -397,7 +397,7 @@ def test_passphrase(self): self.do_command(self.dev_args + ['togglepassphrase']) # There's no passphrase - result = self.do_command(self.dev_args + ['enumerate']) + result = self.do_command(self.dev_args + ["--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent']) @@ -406,7 +406,7 @@ def test_passphrase(self): else: self.fail("Did not enumerate device") # Setting a passphrase won't change the fingerprint - result = self.do_command(self.dev_args + ['-p', 'pass', 'enumerate']) + result = self.do_command(self.dev_args + ['-p', 'pass', "--emulators", "enumerate"]) for dev in result: if dev['type'] == 'trezor' and dev['path'] == 'udp:127.0.0.1:21324': self.assertFalse(dev['needs_passphrase_sent'])