From 000e5c5ac2b521aa1930cf359d507faefb3b2424 Mon Sep 17 00:00:00 2001 From: asi345 Date: Wed, 22 May 2024 11:14:27 +0200 Subject: [PATCH 1/2] bitbox02 library: Update to v6.3.0 Signed-off-by: asi345 --- .../devices/bitbox02_lib/bitbox02/__init__.py | 2 +- .../devices/bitbox02_lib/bitbox02/bitbox02.py | 157 ++++++++++++++---- .../communication/bitbox_api_protocol.py | 36 ++-- .../bitbox02_lib/communication/devices.py | 6 +- .../communication/generated/btc_pb2.py | 114 ++++++------- .../communication/generated/btc_pb2.pyi | 33 +++- .../communication/generated/common_pb2.py | 4 +- .../communication/generated/common_pb2.pyi | 20 +++ .../communication/generated/eth_pb2.py | 56 ++++--- .../communication/generated/eth_pb2.pyi | 65 +++++++- .../communication/generated/hww_pb2.py | 8 +- .../communication/generated/hww_pb2.pyi | 20 ++- .../communication/generated/keystore_pb2.py | 17 +- .../communication/generated/keystore_pb2.pyi | 46 +++++ 14 files changed, 428 insertions(+), 156 deletions(-) diff --git a/hwilib/devices/bitbox02_lib/bitbox02/__init__.py b/hwilib/devices/bitbox02_lib/bitbox02/__init__.py index 046ff978b..598ed110a 100644 --- a/hwilib/devices/bitbox02_lib/bitbox02/__init__.py +++ b/hwilib/devices/bitbox02_lib/bitbox02/__init__.py @@ -16,7 +16,7 @@ from __future__ import print_function import sys -__version__ = "6.2.0" +__version__ = "6.3.0" if sys.version_info.major != 3 or sys.version_info.minor < 6: print( diff --git a/hwilib/devices/bitbox02_lib/bitbox02/bitbox02.py b/hwilib/devices/bitbox02_lib/bitbox02/bitbox02.py index a297fc206..91bc2fcc9 100644 --- a/hwilib/devices/bitbox02_lib/bitbox02/bitbox02.py +++ b/hwilib/devices/bitbox02_lib/bitbox02/bitbox02.py @@ -32,20 +32,25 @@ from .secp256k1 import antiklepto_host_commit, antiklepto_verify -from ..communication.generated import hww_pb2 as hww -from ..communication.generated import eth_pb2 as eth -from ..communication.generated import btc_pb2 as btc -from ..communication.generated import cardano_pb2 as cardano -from ..communication.generated import mnemonic_pb2 as mnemonic -from ..communication.generated import bitbox02_system_pb2 as bitbox02_system -from ..communication.generated import backup_commands_pb2 as backup -from ..communication.generated import common_pb2 as common -from ..communication.generated import keystore_pb2 as keystore -from ..communication.generated import antiklepto_pb2 as antiklepto - -# pylint: disable=unused-import -# We export it in __init__.py -from ..communication.generated import system_pb2 as system +try: + from ..communication.generated import hww_pb2 as hww + from ..communication.generated import eth_pb2 as eth + from ..communication.generated import btc_pb2 as btc + from ..communication.generated import cardano_pb2 as cardano + from ..communication.generated import mnemonic_pb2 as mnemonic + from ..communication.generated import bitbox02_system_pb2 as bitbox02_system + from ..communication.generated import backup_commands_pb2 as backup + from ..communication.generated import common_pb2 as common + from ..communication.generated import keystore_pb2 as keystore + from ..communication.generated import antiklepto_pb2 as antiklepto + import google.protobuf.empty_pb2 + + # pylint: disable=unused-import + # We export it in __init__.py + from ..communication.generated import system_pb2 as system +except ModuleNotFoundError: + print("Run `make py` to generate the protobuf messages") + sys.exit() try: # Optional rlp dependency only needed to sign ethereum transactions. @@ -674,6 +679,40 @@ def electrum_encryption_key(self, keypath: Sequence[int]) -> str: ) return self._msg_query(request).electrum_encryption_key.key + def bip85_bip39(self) -> None: + """Invokes the BIP85-BIP39 workflow on the device""" + self._require_atleast(semver.VersionInfo(9, 18, 0)) + + # pylint: disable=no-member + request = hww.Request() + request.bip85.CopyFrom( + keystore.BIP85Request( + bip39=google.protobuf.empty_pb2.Empty(), + ) + ) + response = self._msg_query(request, expected_response="bip85").bip85 + assert response.WhichOneof("app") == "bip39" + + def bip85_ln(self) -> bytes: + """ + Generates and returns a mnemonic for a hot Lightning wallet from the device using BIP-85. + """ + self._require_atleast(semver.VersionInfo(9, 17, 0)) + + # Only account_number=0 is allowed for now. + account_number = 0 + + # pylint: disable=no-member + request = hww.Request() + request.bip85.CopyFrom( + keystore.BIP85Request( + ln=keystore.BIP85Request.AppLn(account_number=account_number), + ) + ) + response = self._msg_query(request, expected_response="bip85").bip85 + assert response.WhichOneof("app") == "ln" + return response.ln + def enable_mnemonic_passphrase(self) -> None: """ Enable the bip39 passphrase. @@ -753,28 +792,17 @@ def eth_sign(self, transaction: bytes, keypath: Sequence[int], chain_id: int = 1 """ transaction should be given as a full rlp encoded eth transaction. """ - nonce, gas_price, gas_limit, recipient, value, data, _, _, _ = rlp.decode(transaction) - request = eth.ETHRequest() - # pylint: disable=no-member - request.sign.CopyFrom( - eth.ETHSignRequest( - coin=self._eth_coin(chain_id), - chain_id=chain_id, - keypath=keypath, - nonce=nonce, - gas_price=gas_price, - gas_limit=gas_limit, - recipient=recipient, - value=value, - data=data, - ) - ) + is_eip1559 = transaction.startswith(b"\x02") - supports_antiklepto = self.version >= semver.VersionInfo(9, 5, 0) - if supports_antiklepto: + def handle_antiklepto(request: eth.ETHRequest) -> bytes: host_nonce = os.urandom(32) + if is_eip1559: + request.sign_eip1559.host_nonce_commitment.commitment = antiklepto_host_commit( + host_nonce + ) + else: + request.sign.host_nonce_commitment.commitment = antiklepto_host_commit(host_nonce) - request.sign.host_nonce_commitment.commitment = antiklepto_host_commit(host_nonce) signer_commitment = self._eth_msg_query( request, expected_response="antiklepto_signer_commitment" ).antiklepto_signer_commitment.commitment @@ -792,6 +820,64 @@ def eth_sign(self, transaction: bytes, keypath: Sequence[int], chain_id: int = 1 return signature + if is_eip1559: + self._require_atleast(semver.VersionInfo(9, 16, 0)) + ( + decoded_chain_id, + nonce, + priority_fee, + max_fee, + gas_limit, + recipient, + value, + data, + _, + _, + _, + ) = rlp.decode(transaction[1:]) + decoded_chain_id_int = int.from_bytes(decoded_chain_id, byteorder="big") + if decoded_chain_id_int != chain_id: + raise Exception( + f"chainID argument ({chain_id}) does not match chainID encoded in transaction ({decoded_chain_id_int})" + ) + request = eth.ETHRequest() + # pylint: disable=no-member + request.sign_eip1559.CopyFrom( + eth.ETHSignEIP1559Request( + chain_id=chain_id, + keypath=keypath, + nonce=nonce, + max_priority_fee_per_gas=priority_fee, + max_fee_per_gas=max_fee, + gas_limit=gas_limit, + recipient=recipient, + value=value, + data=data, + ) + ) + return handle_antiklepto(request) + + nonce, gas_price, gas_limit, recipient, value, data, _, _, _ = rlp.decode(transaction) + request = eth.ETHRequest() + # pylint: disable=no-member + request.sign.CopyFrom( + eth.ETHSignRequest( + coin=self._eth_coin(chain_id), + chain_id=chain_id, + keypath=keypath, + nonce=nonce, + gas_price=gas_price, + gas_limit=gas_limit, + recipient=recipient, + value=value, + data=data, + ) + ) + + supports_antiklepto = self.version >= semver.VersionInfo(9, 5, 0) + if supports_antiklepto: + return handle_antiklepto(request) + return self._eth_msg_query(request, expected_response="sign").sign.signature def eth_sign_msg(self, msg: bytes, keypath: Sequence[int], chain_id: int = 1) -> bytes: @@ -945,7 +1031,10 @@ def get_value( return value if typ.type == eth.ETHSignTypedMessageRequest.DataType.UINT: if isinstance(value, str): - value = int(value) + if value[:2].lower() == "0x": + value = int(value[2:], 16) + else: + value = int(value) assert isinstance(value, int) return value.to_bytes(typ.size, "big") if typ.type == eth.ETHSignTypedMessageRequest.DataType.INT: diff --git a/hwilib/devices/bitbox02_lib/communication/bitbox_api_protocol.py b/hwilib/devices/bitbox02_lib/communication/bitbox_api_protocol.py index b12974657..48eb9e2b3 100644 --- a/hwilib/devices/bitbox02_lib/communication/bitbox_api_protocol.py +++ b/hwilib/devices/bitbox02_lib/communication/bitbox_api_protocol.py @@ -33,8 +33,12 @@ from .communication import TransportLayer from .devices import BITBOX02MULTI, BITBOX02BTC -from .generated import hww_pb2 as hww -from .generated import system_pb2 as system +try: + from .generated import hww_pb2 as hww + from .generated import system_pb2 as system +except ModuleNotFoundError: + print("Run `make py` to generate the protobuf messages") + sys.exit() HWW_CMD = 0x80 + 0x40 + 0x01 @@ -522,24 +526,34 @@ class BitBoxCommonAPI: # pylint: disable=too-many-public-methods,too-many-arguments def __init__( - self, transport: TransportLayer, device_info: DeviceInfo, noise_config: BitBoxNoiseConfig + self, + transport: TransportLayer, + device_info: Optional[DeviceInfo], + noise_config: BitBoxNoiseConfig, ): """ Can raise LibraryVersionOutdatedException. check_min_version() should be called following the instantiation. + If device_info is None, it is infered using the OP_INFO API call, available since + firmware version v5.0.0. """ self.debug = False - serial_number = device_info["serial_number"] - if device_info["product_string"] == BITBOX02MULTI: - self.edition = BitBox02Edition.MULTI - elif device_info["product_string"] == BITBOX02BTC: - self.edition = BitBox02Edition.BTCONLY + if device_info is not None: + version = device_info["serial_number"] + if device_info["product_string"] == BITBOX02MULTI: + edition = BitBox02Edition.MULTI + elif device_info["product_string"] == BITBOX02BTC: + edition = BitBox02Edition.BTCONLY + else: + version, _, edition, _ = self.get_info(transport) - self.version = parse_device_version(serial_number) - if self.version is None: + self.edition = edition + try: + self.version = parse_device_version(version) + except: transport.close() - raise ValueError(f"Could not parse version from {serial_number}") + raise # Delete the prelease part, as it messes with the comparison (e.g. 3.0.0-pre < 3.0.0 is # True, but the 3.0.0-pre has already the same API breaking changes like 3.0.0...). diff --git a/hwilib/devices/bitbox02_lib/communication/devices.py b/hwilib/devices/bitbox02_lib/communication/devices.py index 383bf7728..027121f8d 100644 --- a/hwilib/devices/bitbox02_lib/communication/devices.py +++ b/hwilib/devices/bitbox02_lib/communication/devices.py @@ -157,9 +157,9 @@ def get_any_bitbox02_bootloader() -> DeviceInfo: return devices[0] -def parse_device_version(serial_number: str) -> semver.VersionInfo: - match = re.search(r"v([0-9]+\.[0-9]+\.[0-9]+.*)", serial_number) +def parse_device_version(version: str) -> semver.VersionInfo: + match = re.search(r"v([0-9]+\.[0-9]+\.[0-9]+.*)", version) if match is None: - raise Exception(f"Could not parse version string from serial_number: {serial_number}") + raise ValueError(f"Could not parse version string from string: {version}") return semver.VersionInfo.parse(match.group(1)) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.py b/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.py index 73a1e179e..f94d03b35 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.py +++ b/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.py @@ -15,67 +15,69 @@ from . import antiklepto_pb2 as antiklepto__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tbtc.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x10\x61ntiklepto.proto\"\xb9\x03\n\x0f\x42TCScriptConfig\x12G\n\x0bsimple_type\x18\x01 \x01(\x0e\x32\x30.shiftcrypto.bitbox02.BTCScriptConfig.SimpleTypeH\x00\x12\x42\n\x08multisig\x18\x02 \x01(\x0b\x32..shiftcrypto.bitbox02.BTCScriptConfig.MultisigH\x00\x1a\xd9\x01\n\x08Multisig\x12\x11\n\tthreshold\x18\x01 \x01(\r\x12)\n\x05xpubs\x18\x02 \x03(\x0b\x32\x1a.shiftcrypto.bitbox02.XPub\x12\x16\n\x0eour_xpub_index\x18\x03 \x01(\r\x12N\n\x0bscript_type\x18\x04 \x01(\x0e\x32\x39.shiftcrypto.bitbox02.BTCScriptConfig.Multisig.ScriptType\"\'\n\nScriptType\x12\t\n\x05P2WSH\x10\x00\x12\x0e\n\nP2WSH_P2SH\x10\x01\"3\n\nSimpleType\x12\x0f\n\x0bP2WPKH_P2SH\x10\x00\x12\n\n\x06P2WPKH\x10\x01\x12\x08\n\x04P2TR\x10\x02\x42\x08\n\x06\x63onfig\"\xfc\x02\n\rBTCPubRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\x41\n\txpub_type\x18\x03 \x01(\x0e\x32,.shiftcrypto.bitbox02.BTCPubRequest.XPubTypeH\x00\x12>\n\rscript_config\x18\x04 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfigH\x00\x12\x0f\n\x07\x64isplay\x18\x05 \x01(\x08\"\x8e\x01\n\x08XPubType\x12\x08\n\x04TPUB\x10\x00\x12\x08\n\x04XPUB\x10\x01\x12\x08\n\x04YPUB\x10\x02\x12\x08\n\x04ZPUB\x10\x03\x12\x08\n\x04VPUB\x10\x04\x12\x08\n\x04UPUB\x10\x05\x12\x10\n\x0c\x43\x41PITAL_VPUB\x10\x06\x12\x10\n\x0c\x43\x41PITAL_ZPUB\x10\x07\x12\x10\n\x0c\x43\x41PITAL_UPUB\x10\x08\x12\x10\n\x0c\x43\x41PITAL_YPUB\x10\tB\x08\n\x06output\"k\n\x1a\x42TCScriptConfigWithKeypath\x12<\n\rscript_config\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfig\x12\x0f\n\x07keypath\x18\x03 \x03(\r\"\xc5\x02\n\x12\x42TCSignInitRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12H\n\x0escript_configs\x18\x02 \x03(\x0b\x32\x30.shiftcrypto.bitbox02.BTCScriptConfigWithKeypath\x12\x0f\n\x07version\x18\x04 \x01(\r\x12\x12\n\nnum_inputs\x18\x05 \x01(\r\x12\x13\n\x0bnum_outputs\x18\x06 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12H\n\x0b\x66ormat_unit\x18\x08 \x01(\x0e\x32\x33.shiftcrypto.bitbox02.BTCSignInitRequest.FormatUnit\"\"\n\nFormatUnit\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x07\n\x03SAT\x10\x01\"\xe8\x02\n\x13\x42TCSignNextResponse\x12<\n\x04type\x18\x01 \x01(\x0e\x32..shiftcrypto.bitbox02.BTCSignNextResponse.Type\x12\r\n\x05index\x18\x02 \x01(\r\x12\x15\n\rhas_signature\x18\x03 \x01(\x08\x12\x11\n\tsignature\x18\x04 \x01(\x0c\x12\x12\n\nprev_index\x18\x05 \x01(\r\x12W\n\x1d\x61nti_klepto_signer_commitment\x18\x06 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitment\"m\n\x04Type\x12\t\n\x05INPUT\x10\x00\x12\n\n\x06OUTPUT\x10\x01\x12\x08\n\x04\x44ONE\x10\x02\x12\x0f\n\x0bPREVTX_INIT\x10\x03\x12\x10\n\x0cPREVTX_INPUT\x10\x04\x12\x11\n\rPREVTX_OUTPUT\x10\x05\x12\x0e\n\nHOST_NONCE\x10\x06\"\xea\x01\n\x13\x42TCSignInputRequest\x12\x13\n\x0bprevOutHash\x18\x01 \x01(\x0c\x12\x14\n\x0cprevOutIndex\x18\x02 \x01(\r\x12\x14\n\x0cprevOutValue\x18\x03 \x01(\x04\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x0f\n\x07keypath\x18\x06 \x03(\r\x12\x1b\n\x13script_config_index\x18\x07 \x01(\r\x12R\n\x15host_nonce_commitment\x18\x08 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\"\xa5\x01\n\x14\x42TCSignOutputRequest\x12\x0c\n\x04ours\x18\x01 \x01(\x08\x12\x31\n\x04type\x18\x02 \x01(\x0e\x32#.shiftcrypto.bitbox02.BTCOutputType\x12\r\n\x05value\x18\x03 \x01(\x04\x12\x0f\n\x07payload\x18\x04 \x01(\x0c\x12\x0f\n\x07keypath\x18\x05 \x03(\r\x12\x1b\n\x13script_config_index\x18\x06 \x01(\r\"\x99\x01\n\x1b\x42TCScriptConfigRegistration\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12<\n\rscript_config\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfig\x12\x0f\n\x07keypath\x18\x03 \x03(\r\"\x0c\n\nBTCSuccess\"m\n\"BTCIsScriptConfigRegisteredRequest\x12G\n\x0cregistration\x18\x01 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.BTCScriptConfigRegistration\"<\n#BTCIsScriptConfigRegisteredResponse\x12\x15\n\ris_registered\x18\x01 \x01(\x08\"\xfc\x01\n\x1e\x42TCRegisterScriptConfigRequest\x12G\n\x0cregistration\x18\x01 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.BTCScriptConfigRegistration\x12\x0c\n\x04name\x18\x02 \x01(\t\x12P\n\txpub_type\x18\x03 \x01(\x0e\x32=.shiftcrypto.bitbox02.BTCRegisterScriptConfigRequest.XPubType\"1\n\x08XPubType\x12\x11\n\rAUTO_ELECTRUM\x10\x00\x12\x12\n\x0e\x41UTO_XPUB_TPUB\x10\x01\"b\n\x14\x42TCPrevTxInitRequest\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x12\n\nnum_inputs\x18\x02 \x01(\r\x12\x13\n\x0bnum_outputs\x18\x03 \x01(\r\x12\x10\n\x08locktime\x18\x04 \x01(\r\"r\n\x15\x42TCPrevTxInputRequest\x12\x15\n\rprev_out_hash\x18\x01 \x01(\x0c\x12\x16\n\x0eprev_out_index\x18\x02 \x01(\r\x12\x18\n\x10signature_script\x18\x03 \x01(\x0c\x12\x10\n\x08sequence\x18\x04 \x01(\r\">\n\x16\x42TCPrevTxOutputRequest\x12\r\n\x05value\x18\x01 \x01(\x04\x12\x15\n\rpubkey_script\x18\x02 \x01(\x0c\"\xee\x01\n\x15\x42TCSignMessageRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12G\n\rscript_config\x18\x02 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.BTCScriptConfigWithKeypath\x12\x0b\n\x03msg\x18\x03 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\x04 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\"+\n\x16\x42TCSignMessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\"\xb6\x04\n\nBTCRequest\x12_\n\x1bis_script_config_registered\x18\x01 \x01(\x0b\x32\x38.shiftcrypto.bitbox02.BTCIsScriptConfigRegisteredRequestH\x00\x12V\n\x16register_script_config\x18\x02 \x01(\x0b\x32\x34.shiftcrypto.bitbox02.BTCRegisterScriptConfigRequestH\x00\x12\x41\n\x0bprevtx_init\x18\x03 \x01(\x0b\x32*.shiftcrypto.bitbox02.BTCPrevTxInitRequestH\x00\x12\x43\n\x0cprevtx_input\x18\x04 \x01(\x0b\x32+.shiftcrypto.bitbox02.BTCPrevTxInputRequestH\x00\x12\x45\n\rprevtx_output\x18\x05 \x01(\x0b\x32,.shiftcrypto.bitbox02.BTCPrevTxOutputRequestH\x00\x12\x43\n\x0csign_message\x18\x06 \x01(\x0b\x32+.shiftcrypto.bitbox02.BTCSignMessageRequestH\x00\x12P\n\x14\x61ntiklepto_signature\x18\x07 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignatureRequestH\x00\x42\t\n\x07request\"\x90\x03\n\x0b\x42TCResponse\x12\x33\n\x07success\x18\x01 \x01(\x0b\x32 .shiftcrypto.bitbox02.BTCSuccessH\x00\x12`\n\x1bis_script_config_registered\x18\x02 \x01(\x0b\x32\x39.shiftcrypto.bitbox02.BTCIsScriptConfigRegisteredResponseH\x00\x12>\n\tsign_next\x18\x03 \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignNextResponseH\x00\x12\x44\n\x0csign_message\x18\x04 \x01(\x0b\x32,.shiftcrypto.bitbox02.BTCSignMessageResponseH\x00\x12X\n\x1c\x61ntiklepto_signer_commitment\x18\x05 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitmentH\x00\x42\n\n\x08response*/\n\x07\x42TCCoin\x12\x07\n\x03\x42TC\x10\x00\x12\x08\n\x04TBTC\x10\x01\x12\x07\n\x03LTC\x10\x02\x12\x08\n\x04TLTC\x10\x03*R\n\rBTCOutputType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05P2PKH\x10\x01\x12\x08\n\x04P2SH\x10\x02\x12\n\n\x06P2WPKH\x10\x03\x12\t\n\x05P2WSH\x10\x04\x12\x08\n\x04P2TR\x10\x05\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tbtc.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x10\x61ntiklepto.proto\"\xc6\x04\n\x0f\x42TCScriptConfig\x12G\n\x0bsimple_type\x18\x01 \x01(\x0e\x32\x30.shiftcrypto.bitbox02.BTCScriptConfig.SimpleTypeH\x00\x12\x42\n\x08multisig\x18\x02 \x01(\x0b\x32..shiftcrypto.bitbox02.BTCScriptConfig.MultisigH\x00\x12>\n\x06policy\x18\x03 \x01(\x0b\x32,.shiftcrypto.bitbox02.BTCScriptConfig.PolicyH\x00\x1a\xd9\x01\n\x08Multisig\x12\x11\n\tthreshold\x18\x01 \x01(\r\x12)\n\x05xpubs\x18\x02 \x03(\x0b\x32\x1a.shiftcrypto.bitbox02.XPub\x12\x16\n\x0eour_xpub_index\x18\x03 \x01(\r\x12N\n\x0bscript_type\x18\x04 \x01(\x0e\x32\x39.shiftcrypto.bitbox02.BTCScriptConfig.Multisig.ScriptType\"\'\n\nScriptType\x12\t\n\x05P2WSH\x10\x00\x12\x0e\n\nP2WSH_P2SH\x10\x01\x1aK\n\x06Policy\x12\x0e\n\x06policy\x18\x01 \x01(\t\x12\x31\n\x04keys\x18\x02 \x03(\x0b\x32#.shiftcrypto.bitbox02.KeyOriginInfo\"3\n\nSimpleType\x12\x0f\n\x0bP2WPKH_P2SH\x10\x00\x12\n\n\x06P2WPKH\x10\x01\x12\x08\n\x04P2TR\x10\x02\x42\x08\n\x06\x63onfig\"\xfc\x02\n\rBTCPubRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\x41\n\txpub_type\x18\x03 \x01(\x0e\x32,.shiftcrypto.bitbox02.BTCPubRequest.XPubTypeH\x00\x12>\n\rscript_config\x18\x04 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfigH\x00\x12\x0f\n\x07\x64isplay\x18\x05 \x01(\x08\"\x8e\x01\n\x08XPubType\x12\x08\n\x04TPUB\x10\x00\x12\x08\n\x04XPUB\x10\x01\x12\x08\n\x04YPUB\x10\x02\x12\x08\n\x04ZPUB\x10\x03\x12\x08\n\x04VPUB\x10\x04\x12\x08\n\x04UPUB\x10\x05\x12\x10\n\x0c\x43\x41PITAL_VPUB\x10\x06\x12\x10\n\x0c\x43\x41PITAL_ZPUB\x10\x07\x12\x10\n\x0c\x43\x41PITAL_UPUB\x10\x08\x12\x10\n\x0c\x43\x41PITAL_YPUB\x10\tB\x08\n\x06output\"k\n\x1a\x42TCScriptConfigWithKeypath\x12<\n\rscript_config\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfig\x12\x0f\n\x07keypath\x18\x03 \x03(\r\"\xc5\x02\n\x12\x42TCSignInitRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12H\n\x0escript_configs\x18\x02 \x03(\x0b\x32\x30.shiftcrypto.bitbox02.BTCScriptConfigWithKeypath\x12\x0f\n\x07version\x18\x04 \x01(\r\x12\x12\n\nnum_inputs\x18\x05 \x01(\r\x12\x13\n\x0bnum_outputs\x18\x06 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12H\n\x0b\x66ormat_unit\x18\x08 \x01(\x0e\x32\x33.shiftcrypto.bitbox02.BTCSignInitRequest.FormatUnit\"\"\n\nFormatUnit\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x07\n\x03SAT\x10\x01\"\xe8\x02\n\x13\x42TCSignNextResponse\x12<\n\x04type\x18\x01 \x01(\x0e\x32..shiftcrypto.bitbox02.BTCSignNextResponse.Type\x12\r\n\x05index\x18\x02 \x01(\r\x12\x15\n\rhas_signature\x18\x03 \x01(\x08\x12\x11\n\tsignature\x18\x04 \x01(\x0c\x12\x12\n\nprev_index\x18\x05 \x01(\r\x12W\n\x1d\x61nti_klepto_signer_commitment\x18\x06 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitment\"m\n\x04Type\x12\t\n\x05INPUT\x10\x00\x12\n\n\x06OUTPUT\x10\x01\x12\x08\n\x04\x44ONE\x10\x02\x12\x0f\n\x0bPREVTX_INIT\x10\x03\x12\x10\n\x0cPREVTX_INPUT\x10\x04\x12\x11\n\rPREVTX_OUTPUT\x10\x05\x12\x0e\n\nHOST_NONCE\x10\x06\"\xea\x01\n\x13\x42TCSignInputRequest\x12\x13\n\x0bprevOutHash\x18\x01 \x01(\x0c\x12\x14\n\x0cprevOutIndex\x18\x02 \x01(\r\x12\x14\n\x0cprevOutValue\x18\x03 \x01(\x04\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x0f\n\x07keypath\x18\x06 \x03(\r\x12\x1b\n\x13script_config_index\x18\x07 \x01(\r\x12R\n\x15host_nonce_commitment\x18\x08 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\"\xa5\x01\n\x14\x42TCSignOutputRequest\x12\x0c\n\x04ours\x18\x01 \x01(\x08\x12\x31\n\x04type\x18\x02 \x01(\x0e\x32#.shiftcrypto.bitbox02.BTCOutputType\x12\r\n\x05value\x18\x03 \x01(\x04\x12\x0f\n\x07payload\x18\x04 \x01(\x0c\x12\x0f\n\x07keypath\x18\x05 \x03(\r\x12\x1b\n\x13script_config_index\x18\x06 \x01(\r\"\x99\x01\n\x1b\x42TCScriptConfigRegistration\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12<\n\rscript_config\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.BTCScriptConfig\x12\x0f\n\x07keypath\x18\x03 \x03(\r\"\x0c\n\nBTCSuccess\"m\n\"BTCIsScriptConfigRegisteredRequest\x12G\n\x0cregistration\x18\x01 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.BTCScriptConfigRegistration\"<\n#BTCIsScriptConfigRegisteredResponse\x12\x15\n\ris_registered\x18\x01 \x01(\x08\"\xfc\x01\n\x1e\x42TCRegisterScriptConfigRequest\x12G\n\x0cregistration\x18\x01 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.BTCScriptConfigRegistration\x12\x0c\n\x04name\x18\x02 \x01(\t\x12P\n\txpub_type\x18\x03 \x01(\x0e\x32=.shiftcrypto.bitbox02.BTCRegisterScriptConfigRequest.XPubType\"1\n\x08XPubType\x12\x11\n\rAUTO_ELECTRUM\x10\x00\x12\x12\n\x0e\x41UTO_XPUB_TPUB\x10\x01\"b\n\x14\x42TCPrevTxInitRequest\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x12\n\nnum_inputs\x18\x02 \x01(\r\x12\x13\n\x0bnum_outputs\x18\x03 \x01(\r\x12\x10\n\x08locktime\x18\x04 \x01(\r\"r\n\x15\x42TCPrevTxInputRequest\x12\x15\n\rprev_out_hash\x18\x01 \x01(\x0c\x12\x16\n\x0eprev_out_index\x18\x02 \x01(\r\x12\x18\n\x10signature_script\x18\x03 \x01(\x0c\x12\x10\n\x08sequence\x18\x04 \x01(\r\">\n\x16\x42TCPrevTxOutputRequest\x12\r\n\x05value\x18\x01 \x01(\x04\x12\x15\n\rpubkey_script\x18\x02 \x01(\x0c\"\xee\x01\n\x15\x42TCSignMessageRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.BTCCoin\x12G\n\rscript_config\x18\x02 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.BTCScriptConfigWithKeypath\x12\x0b\n\x03msg\x18\x03 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\x04 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\"+\n\x16\x42TCSignMessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\"\xb6\x04\n\nBTCRequest\x12_\n\x1bis_script_config_registered\x18\x01 \x01(\x0b\x32\x38.shiftcrypto.bitbox02.BTCIsScriptConfigRegisteredRequestH\x00\x12V\n\x16register_script_config\x18\x02 \x01(\x0b\x32\x34.shiftcrypto.bitbox02.BTCRegisterScriptConfigRequestH\x00\x12\x41\n\x0bprevtx_init\x18\x03 \x01(\x0b\x32*.shiftcrypto.bitbox02.BTCPrevTxInitRequestH\x00\x12\x43\n\x0cprevtx_input\x18\x04 \x01(\x0b\x32+.shiftcrypto.bitbox02.BTCPrevTxInputRequestH\x00\x12\x45\n\rprevtx_output\x18\x05 \x01(\x0b\x32,.shiftcrypto.bitbox02.BTCPrevTxOutputRequestH\x00\x12\x43\n\x0csign_message\x18\x06 \x01(\x0b\x32+.shiftcrypto.bitbox02.BTCSignMessageRequestH\x00\x12P\n\x14\x61ntiklepto_signature\x18\x07 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignatureRequestH\x00\x42\t\n\x07request\"\x90\x03\n\x0b\x42TCResponse\x12\x33\n\x07success\x18\x01 \x01(\x0b\x32 .shiftcrypto.bitbox02.BTCSuccessH\x00\x12`\n\x1bis_script_config_registered\x18\x02 \x01(\x0b\x32\x39.shiftcrypto.bitbox02.BTCIsScriptConfigRegisteredResponseH\x00\x12>\n\tsign_next\x18\x03 \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignNextResponseH\x00\x12\x44\n\x0csign_message\x18\x04 \x01(\x0b\x32,.shiftcrypto.bitbox02.BTCSignMessageResponseH\x00\x12X\n\x1c\x61ntiklepto_signer_commitment\x18\x05 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitmentH\x00\x42\n\n\x08response*/\n\x07\x42TCCoin\x12\x07\n\x03\x42TC\x10\x00\x12\x08\n\x04TBTC\x10\x01\x12\x07\n\x03LTC\x10\x02\x12\x08\n\x04TLTC\x10\x03*R\n\rBTCOutputType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05P2PKH\x10\x01\x12\x08\n\x04P2SH\x10\x02\x12\n\n\x06P2WPKH\x10\x03\x12\t\n\x05P2WSH\x10\x04\x12\x08\n\x04P2TR\x10\x05\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'btc_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _BTCCOIN._serialized_start=4235 - _BTCCOIN._serialized_end=4282 - _BTCOUTPUTTYPE._serialized_start=4284 - _BTCOUTPUTTYPE._serialized_end=4366 + _BTCCOIN._serialized_start=4376 + _BTCCOIN._serialized_end=4423 + _BTCOUTPUTTYPE._serialized_start=4425 + _BTCOUTPUTTYPE._serialized_end=4507 _BTCSCRIPTCONFIG._serialized_start=68 - _BTCSCRIPTCONFIG._serialized_end=509 - _BTCSCRIPTCONFIG_MULTISIG._serialized_start=229 - _BTCSCRIPTCONFIG_MULTISIG._serialized_end=446 - _BTCSCRIPTCONFIG_MULTISIG_SCRIPTTYPE._serialized_start=407 - _BTCSCRIPTCONFIG_MULTISIG_SCRIPTTYPE._serialized_end=446 - _BTCSCRIPTCONFIG_SIMPLETYPE._serialized_start=448 - _BTCSCRIPTCONFIG_SIMPLETYPE._serialized_end=499 - _BTCPUBREQUEST._serialized_start=512 - _BTCPUBREQUEST._serialized_end=892 - _BTCPUBREQUEST_XPUBTYPE._serialized_start=740 - _BTCPUBREQUEST_XPUBTYPE._serialized_end=882 - _BTCSCRIPTCONFIGWITHKEYPATH._serialized_start=894 - _BTCSCRIPTCONFIGWITHKEYPATH._serialized_end=1001 - _BTCSIGNINITREQUEST._serialized_start=1004 - _BTCSIGNINITREQUEST._serialized_end=1329 - _BTCSIGNINITREQUEST_FORMATUNIT._serialized_start=1295 - _BTCSIGNINITREQUEST_FORMATUNIT._serialized_end=1329 - _BTCSIGNNEXTRESPONSE._serialized_start=1332 - _BTCSIGNNEXTRESPONSE._serialized_end=1692 - _BTCSIGNNEXTRESPONSE_TYPE._serialized_start=1583 - _BTCSIGNNEXTRESPONSE_TYPE._serialized_end=1692 - _BTCSIGNINPUTREQUEST._serialized_start=1695 - _BTCSIGNINPUTREQUEST._serialized_end=1929 - _BTCSIGNOUTPUTREQUEST._serialized_start=1932 - _BTCSIGNOUTPUTREQUEST._serialized_end=2097 - _BTCSCRIPTCONFIGREGISTRATION._serialized_start=2100 - _BTCSCRIPTCONFIGREGISTRATION._serialized_end=2253 - _BTCSUCCESS._serialized_start=2255 - _BTCSUCCESS._serialized_end=2267 - _BTCISSCRIPTCONFIGREGISTEREDREQUEST._serialized_start=2269 - _BTCISSCRIPTCONFIGREGISTEREDREQUEST._serialized_end=2378 - _BTCISSCRIPTCONFIGREGISTEREDRESPONSE._serialized_start=2380 - _BTCISSCRIPTCONFIGREGISTEREDRESPONSE._serialized_end=2440 - _BTCREGISTERSCRIPTCONFIGREQUEST._serialized_start=2443 - _BTCREGISTERSCRIPTCONFIGREQUEST._serialized_end=2695 - _BTCREGISTERSCRIPTCONFIGREQUEST_XPUBTYPE._serialized_start=2646 - _BTCREGISTERSCRIPTCONFIGREQUEST_XPUBTYPE._serialized_end=2695 - _BTCPREVTXINITREQUEST._serialized_start=2697 - _BTCPREVTXINITREQUEST._serialized_end=2795 - _BTCPREVTXINPUTREQUEST._serialized_start=2797 - _BTCPREVTXINPUTREQUEST._serialized_end=2911 - _BTCPREVTXOUTPUTREQUEST._serialized_start=2913 - _BTCPREVTXOUTPUTREQUEST._serialized_end=2975 - _BTCSIGNMESSAGEREQUEST._serialized_start=2978 - _BTCSIGNMESSAGEREQUEST._serialized_end=3216 - _BTCSIGNMESSAGERESPONSE._serialized_start=3218 - _BTCSIGNMESSAGERESPONSE._serialized_end=3261 - _BTCREQUEST._serialized_start=3264 - _BTCREQUEST._serialized_end=3830 - _BTCRESPONSE._serialized_start=3833 - _BTCRESPONSE._serialized_end=4233 + _BTCSCRIPTCONFIG._serialized_end=650 + _BTCSCRIPTCONFIG_MULTISIG._serialized_start=293 + _BTCSCRIPTCONFIG_MULTISIG._serialized_end=510 + _BTCSCRIPTCONFIG_MULTISIG_SCRIPTTYPE._serialized_start=471 + _BTCSCRIPTCONFIG_MULTISIG_SCRIPTTYPE._serialized_end=510 + _BTCSCRIPTCONFIG_POLICY._serialized_start=512 + _BTCSCRIPTCONFIG_POLICY._serialized_end=587 + _BTCSCRIPTCONFIG_SIMPLETYPE._serialized_start=589 + _BTCSCRIPTCONFIG_SIMPLETYPE._serialized_end=640 + _BTCPUBREQUEST._serialized_start=653 + _BTCPUBREQUEST._serialized_end=1033 + _BTCPUBREQUEST_XPUBTYPE._serialized_start=881 + _BTCPUBREQUEST_XPUBTYPE._serialized_end=1023 + _BTCSCRIPTCONFIGWITHKEYPATH._serialized_start=1035 + _BTCSCRIPTCONFIGWITHKEYPATH._serialized_end=1142 + _BTCSIGNINITREQUEST._serialized_start=1145 + _BTCSIGNINITREQUEST._serialized_end=1470 + _BTCSIGNINITREQUEST_FORMATUNIT._serialized_start=1436 + _BTCSIGNINITREQUEST_FORMATUNIT._serialized_end=1470 + _BTCSIGNNEXTRESPONSE._serialized_start=1473 + _BTCSIGNNEXTRESPONSE._serialized_end=1833 + _BTCSIGNNEXTRESPONSE_TYPE._serialized_start=1724 + _BTCSIGNNEXTRESPONSE_TYPE._serialized_end=1833 + _BTCSIGNINPUTREQUEST._serialized_start=1836 + _BTCSIGNINPUTREQUEST._serialized_end=2070 + _BTCSIGNOUTPUTREQUEST._serialized_start=2073 + _BTCSIGNOUTPUTREQUEST._serialized_end=2238 + _BTCSCRIPTCONFIGREGISTRATION._serialized_start=2241 + _BTCSCRIPTCONFIGREGISTRATION._serialized_end=2394 + _BTCSUCCESS._serialized_start=2396 + _BTCSUCCESS._serialized_end=2408 + _BTCISSCRIPTCONFIGREGISTEREDREQUEST._serialized_start=2410 + _BTCISSCRIPTCONFIGREGISTEREDREQUEST._serialized_end=2519 + _BTCISSCRIPTCONFIGREGISTEREDRESPONSE._serialized_start=2521 + _BTCISSCRIPTCONFIGREGISTEREDRESPONSE._serialized_end=2581 + _BTCREGISTERSCRIPTCONFIGREQUEST._serialized_start=2584 + _BTCREGISTERSCRIPTCONFIGREQUEST._serialized_end=2836 + _BTCREGISTERSCRIPTCONFIGREQUEST_XPUBTYPE._serialized_start=2787 + _BTCREGISTERSCRIPTCONFIGREQUEST_XPUBTYPE._serialized_end=2836 + _BTCPREVTXINITREQUEST._serialized_start=2838 + _BTCPREVTXINITREQUEST._serialized_end=2936 + _BTCPREVTXINPUTREQUEST._serialized_start=2938 + _BTCPREVTXINPUTREQUEST._serialized_end=3052 + _BTCPREVTXOUTPUTREQUEST._serialized_start=3054 + _BTCPREVTXOUTPUTREQUEST._serialized_end=3116 + _BTCSIGNMESSAGEREQUEST._serialized_start=3119 + _BTCSIGNMESSAGEREQUEST._serialized_end=3357 + _BTCSIGNMESSAGERESPONSE._serialized_start=3359 + _BTCSIGNMESSAGERESPONSE._serialized_end=3402 + _BTCREQUEST._serialized_start=3405 + _BTCREQUEST._serialized_end=3971 + _BTCRESPONSE._serialized_start=3974 + _BTCRESPONSE._serialized_end=4374 # @@protoc_insertion_point(module_scope) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.pyi b/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.pyi index a4e69cff2..4cb1dc3f9 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.pyi +++ b/hwilib/devices/bitbox02_lib/communication/generated/btc_pb2.pyi @@ -104,7 +104,7 @@ class BTCScriptConfig(google.protobuf.message.Message): threshold: builtins.int @property def xpubs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[common_pb2.XPub]: - """xpubs are acount-level xpubs. Addresses are going to be derived from it using: m//. + """xpubs are acount-level xpubs. Addresses are going to be derived from it using: `m//`. The number of xpubs defines the number of cosigners. """ pass @@ -123,19 +123,40 @@ class BTCScriptConfig(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["our_xpub_index",b"our_xpub_index","script_type",b"script_type","threshold",b"threshold","xpubs",b"xpubs"]) -> None: ... + class Policy(google.protobuf.message.Message): + """A policy as specified by 'Wallet policies': + https://github.com/bitcoin/bips/pull/1389 + """ + DESCRIPTOR: google.protobuf.descriptor.Descriptor + POLICY_FIELD_NUMBER: builtins.int + KEYS_FIELD_NUMBER: builtins.int + policy: typing.Text + @property + def keys(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[common_pb2.KeyOriginInfo]: ... + def __init__(self, + *, + policy: typing.Text = ..., + keys: typing.Optional[typing.Iterable[common_pb2.KeyOriginInfo]] = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["keys",b"keys","policy",b"policy"]) -> None: ... + SIMPLE_TYPE_FIELD_NUMBER: builtins.int MULTISIG_FIELD_NUMBER: builtins.int + POLICY_FIELD_NUMBER: builtins.int simple_type: global___BTCScriptConfig.SimpleType.ValueType @property def multisig(self) -> global___BTCScriptConfig.Multisig: ... + @property + def policy(self) -> global___BTCScriptConfig.Policy: ... def __init__(self, *, simple_type: global___BTCScriptConfig.SimpleType.ValueType = ..., multisig: typing.Optional[global___BTCScriptConfig.Multisig] = ..., + policy: typing.Optional[global___BTCScriptConfig.Policy] = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","simple_type",b"simple_type"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","simple_type",b"simple_type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["config",b"config"]) -> typing.Optional[typing_extensions.Literal["simple_type","multisig"]]: ... + def HasField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","policy",b"policy","simple_type",b"simple_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","policy",b"policy","simple_type",b"simple_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["config",b"config"]) -> typing.Optional[typing_extensions.Literal["simple_type","multisig","policy"]]: ... global___BTCScriptConfig = BTCScriptConfig class BTCPubRequest(google.protobuf.message.Message): @@ -439,7 +460,9 @@ class BTCScriptConfigRegistration(google.protobuf.message.Message): @property def script_config(self) -> global___BTCScriptConfig: ... @property - def keypath(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + def keypath(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """Unused for policy registrations.""" + pass def __init__(self, *, coin: global___BTCCoin.ValueType = ..., diff --git a/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.py b/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.py index 2da2b86d5..3109f6e38 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.py +++ b/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0c\x63ommon.proto\x12\x14shiftcrypto.bitbox02\"\x1a\n\x0bPubResponse\x12\x0b\n\x03pub\x18\x01 \x01(\t\"\x18\n\x16RootFingerprintRequest\".\n\x17RootFingerprintResponse\x12\x13\n\x0b\x66ingerprint\x18\x01 \x01(\x0c\"l\n\x04XPub\x12\r\n\x05\x64\x65pth\x18\x01 \x01(\x0c\x12\x1a\n\x12parent_fingerprint\x18\x02 \x01(\x0c\x12\x11\n\tchild_num\x18\x03 \x01(\r\x12\x12\n\nchain_code\x18\x04 \x01(\x0c\x12\x12\n\npublic_key\x18\x05 \x01(\x0c\"\x1a\n\x07Keypath\x12\x0f\n\x07keypath\x18\x01 \x03(\rb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0c\x63ommon.proto\x12\x14shiftcrypto.bitbox02\"\x1a\n\x0bPubResponse\x12\x0b\n\x03pub\x18\x01 \x01(\t\"\x18\n\x16RootFingerprintRequest\".\n\x17RootFingerprintResponse\x12\x13\n\x0b\x66ingerprint\x18\x01 \x01(\x0c\"l\n\x04XPub\x12\r\n\x05\x64\x65pth\x18\x01 \x01(\x0c\x12\x1a\n\x12parent_fingerprint\x18\x02 \x01(\x0c\x12\x11\n\tchild_num\x18\x03 \x01(\r\x12\x12\n\nchain_code\x18\x04 \x01(\x0c\x12\x12\n\npublic_key\x18\x05 \x01(\x0c\"\x1a\n\x07Keypath\x12\x0f\n\x07keypath\x18\x01 \x03(\r\"d\n\rKeyOriginInfo\x12\x18\n\x10root_fingerprint\x18\x01 \x01(\x0c\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12(\n\x04xpub\x18\x03 \x01(\x0b\x32\x1a.shiftcrypto.bitbox02.XPubb\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'common_pb2', globals()) @@ -30,4 +30,6 @@ _XPUB._serialized_end=248 _KEYPATH._serialized_start=250 _KEYPATH._serialized_end=276 + _KEYORIGININFO._serialized_start=278 + _KEYORIGININFO._serialized_end=378 # @@protoc_insertion_point(module_scope) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.pyi b/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.pyi index adda12f50..93864b54f 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.pyi +++ b/hwilib/devices/bitbox02_lib/communication/generated/common_pb2.pyi @@ -77,3 +77,23 @@ class Keypath(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["keypath",b"keypath"]) -> None: ... global___Keypath = Keypath + +class KeyOriginInfo(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + ROOT_FINGERPRINT_FIELD_NUMBER: builtins.int + KEYPATH_FIELD_NUMBER: builtins.int + XPUB_FIELD_NUMBER: builtins.int + root_fingerprint: builtins.bytes + @property + def keypath(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + @property + def xpub(self) -> global___XPub: ... + def __init__(self, + *, + root_fingerprint: builtins.bytes = ..., + keypath: typing.Optional[typing.Iterable[builtins.int]] = ..., + xpub: typing.Optional[global___XPub] = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["xpub",b"xpub"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["keypath",b"keypath","root_fingerprint",b"root_fingerprint","xpub",b"xpub"]) -> None: ... +global___KeyOriginInfo = KeyOriginInfo diff --git a/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.py b/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.py index dde46019d..c871b3589 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.py +++ b/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.py @@ -15,43 +15,45 @@ from . import antiklepto_pb2 as antiklepto__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\teth.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x10\x61ntiklepto.proto\"\xf4\x01\n\rETHPubRequest\x12\x0f\n\x07keypath\x18\x01 \x03(\r\x12+\n\x04\x63oin\x18\x02 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x43\n\x0boutput_type\x18\x03 \x01(\x0e\x32..shiftcrypto.bitbox02.ETHPubRequest.OutputType\x12\x0f\n\x07\x64isplay\x18\x04 \x01(\x08\x12\x18\n\x10\x63ontract_address\x18\x05 \x01(\x0c\x12\x10\n\x08\x63hain_id\x18\x06 \x01(\x04\"#\n\nOutputType\x12\x0b\n\x07\x41\x44\x44RESS\x10\x00\x12\x08\n\x04XPUB\x10\x01\"\x99\x02\n\x0e\x45THSignRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\r\n\x05nonce\x18\x03 \x01(\x0c\x12\x11\n\tgas_price\x18\x04 \x01(\x0c\x12\x11\n\tgas_limit\x18\x05 \x01(\x0c\x12\x11\n\trecipient\x18\x06 \x01(\x0c\x12\r\n\x05value\x18\x07 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x08 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\t \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x12\x10\n\x08\x63hain_id\x18\n \x01(\x04\"\xc8\x01\n\x15\x45THSignMessageRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\x0b\n\x03msg\x18\x03 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\x04 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x12\x10\n\x08\x63hain_id\x18\x05 \x01(\x04\"$\n\x0f\x45THSignResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\"\xfb\x05\n\x1a\x45THSignTypedMessageRequest\x12\x10\n\x08\x63hain_id\x18\x01 \x01(\x04\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12J\n\x05types\x18\x03 \x03(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.StructType\x12\x14\n\x0cprimary_type\x18\x04 \x01(\t\x12R\n\x15host_nonce_commitment\x18\x05 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x1a\xc9\x01\n\nMemberType\x12G\n\x04type\x18\x01 \x01(\x0e\x32\x39.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.DataType\x12\x0c\n\x04size\x18\x02 \x01(\r\x12\x13\n\x0bstruct_name\x18\x03 \x01(\t\x12O\n\narray_type\x18\x04 \x01(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.MemberType\x1a\x61\n\x06Member\x12\x0c\n\x04name\x18\x01 \x01(\t\x12I\n\x04type\x18\x02 \x01(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.MemberType\x1a\x64\n\nStructType\x12\x0c\n\x04name\x18\x01 \x01(\t\x12H\n\x07members\x18\x02 \x03(\x0b\x32\x37.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.Member\"o\n\x08\x44\x61taType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\x08\n\x04UINT\x10\x02\x12\x07\n\x03INT\x10\x03\x12\x08\n\x04\x42OOL\x10\x04\x12\x0b\n\x07\x41\x44\x44RESS\x10\x05\x12\n\n\x06STRING\x10\x06\x12\t\n\x05\x41RRAY\x10\x07\x12\n\n\x06STRUCT\x10\x08\"\xb4\x01\n\x1c\x45THTypedMessageValueResponse\x12R\n\x0broot_object\x18\x01 \x01(\x0e\x32=.shiftcrypto.bitbox02.ETHTypedMessageValueResponse.RootObject\x12\x0c\n\x04path\x18\x02 \x03(\r\"2\n\nRootObject\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x44OMAIN\x10\x01\x12\x0b\n\x07MESSAGE\x10\x02\",\n\x1b\x45THTypedMessageValueRequest\x12\r\n\x05value\x18\x01 \x01(\x0c\"\xae\x03\n\nETHRequest\x12\x32\n\x03pub\x18\x01 \x01(\x0b\x32#.shiftcrypto.bitbox02.ETHPubRequestH\x00\x12\x34\n\x04sign\x18\x02 \x01(\x0b\x32$.shiftcrypto.bitbox02.ETHSignRequestH\x00\x12?\n\x08sign_msg\x18\x03 \x01(\x0b\x32+.shiftcrypto.bitbox02.ETHSignMessageRequestH\x00\x12P\n\x14\x61ntiklepto_signature\x18\x04 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignatureRequestH\x00\x12J\n\x0esign_typed_msg\x18\x05 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.ETHSignTypedMessageRequestH\x00\x12L\n\x0ftyped_msg_value\x18\x06 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.ETHTypedMessageValueRequestH\x00\x42\t\n\x07request\"\xab\x02\n\x0b\x45THResponse\x12\x30\n\x03pub\x18\x01 \x01(\x0b\x32!.shiftcrypto.bitbox02.PubResponseH\x00\x12\x35\n\x04sign\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.ETHSignResponseH\x00\x12X\n\x1c\x61ntiklepto_signer_commitment\x18\x03 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitmentH\x00\x12M\n\x0ftyped_msg_value\x18\x04 \x01(\x0b\x32\x32.shiftcrypto.bitbox02.ETHTypedMessageValueResponseH\x00\x42\n\n\x08response*2\n\x07\x45THCoin\x12\x07\n\x03\x45TH\x10\x00\x12\x0e\n\nRopstenETH\x10\x01\x12\x0e\n\nRinkebyETH\x10\x02\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\teth.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x10\x61ntiklepto.proto\"\xf4\x01\n\rETHPubRequest\x12\x0f\n\x07keypath\x18\x01 \x03(\r\x12+\n\x04\x63oin\x18\x02 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x43\n\x0boutput_type\x18\x03 \x01(\x0e\x32..shiftcrypto.bitbox02.ETHPubRequest.OutputType\x12\x0f\n\x07\x64isplay\x18\x04 \x01(\x08\x12\x18\n\x10\x63ontract_address\x18\x05 \x01(\x0c\x12\x10\n\x08\x63hain_id\x18\x06 \x01(\x04\"#\n\nOutputType\x12\x0b\n\x07\x41\x44\x44RESS\x10\x00\x12\x08\n\x04XPUB\x10\x01\"\x99\x02\n\x0e\x45THSignRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\r\n\x05nonce\x18\x03 \x01(\x0c\x12\x11\n\tgas_price\x18\x04 \x01(\x0c\x12\x11\n\tgas_limit\x18\x05 \x01(\x0c\x12\x11\n\trecipient\x18\x06 \x01(\x0c\x12\r\n\x05value\x18\x07 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x08 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\t \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x12\x10\n\x08\x63hain_id\x18\n \x01(\x04\"\x9b\x02\n\x15\x45THSignEIP1559Request\x12\x10\n\x08\x63hain_id\x18\x01 \x01(\x04\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\r\n\x05nonce\x18\x03 \x01(\x0c\x12 \n\x18max_priority_fee_per_gas\x18\x04 \x01(\x0c\x12\x17\n\x0fmax_fee_per_gas\x18\x05 \x01(\x0c\x12\x11\n\tgas_limit\x18\x06 \x01(\x0c\x12\x11\n\trecipient\x18\x07 \x01(\x0c\x12\r\n\x05value\x18\x08 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\t \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\n \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\"\xc8\x01\n\x15\x45THSignMessageRequest\x12+\n\x04\x63oin\x18\x01 \x01(\x0e\x32\x1d.shiftcrypto.bitbox02.ETHCoin\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12\x0b\n\x03msg\x18\x03 \x01(\x0c\x12R\n\x15host_nonce_commitment\x18\x04 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x12\x10\n\x08\x63hain_id\x18\x05 \x01(\x04\"$\n\x0f\x45THSignResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\"\xfb\x05\n\x1a\x45THSignTypedMessageRequest\x12\x10\n\x08\x63hain_id\x18\x01 \x01(\x04\x12\x0f\n\x07keypath\x18\x02 \x03(\r\x12J\n\x05types\x18\x03 \x03(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.StructType\x12\x14\n\x0cprimary_type\x18\x04 \x01(\t\x12R\n\x15host_nonce_commitment\x18\x05 \x01(\x0b\x32\x33.shiftcrypto.bitbox02.AntiKleptoHostNonceCommitment\x1a\xc9\x01\n\nMemberType\x12G\n\x04type\x18\x01 \x01(\x0e\x32\x39.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.DataType\x12\x0c\n\x04size\x18\x02 \x01(\r\x12\x13\n\x0bstruct_name\x18\x03 \x01(\t\x12O\n\narray_type\x18\x04 \x01(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.MemberType\x1a\x61\n\x06Member\x12\x0c\n\x04name\x18\x01 \x01(\t\x12I\n\x04type\x18\x02 \x01(\x0b\x32;.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.MemberType\x1a\x64\n\nStructType\x12\x0c\n\x04name\x18\x01 \x01(\t\x12H\n\x07members\x18\x02 \x03(\x0b\x32\x37.shiftcrypto.bitbox02.ETHSignTypedMessageRequest.Member\"o\n\x08\x44\x61taType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\x08\n\x04UINT\x10\x02\x12\x07\n\x03INT\x10\x03\x12\x08\n\x04\x42OOL\x10\x04\x12\x0b\n\x07\x41\x44\x44RESS\x10\x05\x12\n\n\x06STRING\x10\x06\x12\t\n\x05\x41RRAY\x10\x07\x12\n\n\x06STRUCT\x10\x08\"\xb4\x01\n\x1c\x45THTypedMessageValueResponse\x12R\n\x0broot_object\x18\x01 \x01(\x0e\x32=.shiftcrypto.bitbox02.ETHTypedMessageValueResponse.RootObject\x12\x0c\n\x04path\x18\x02 \x03(\r\"2\n\nRootObject\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x44OMAIN\x10\x01\x12\x0b\n\x07MESSAGE\x10\x02\",\n\x1b\x45THTypedMessageValueRequest\x12\r\n\x05value\x18\x01 \x01(\x0c\"\xf3\x03\n\nETHRequest\x12\x32\n\x03pub\x18\x01 \x01(\x0b\x32#.shiftcrypto.bitbox02.ETHPubRequestH\x00\x12\x34\n\x04sign\x18\x02 \x01(\x0b\x32$.shiftcrypto.bitbox02.ETHSignRequestH\x00\x12?\n\x08sign_msg\x18\x03 \x01(\x0b\x32+.shiftcrypto.bitbox02.ETHSignMessageRequestH\x00\x12P\n\x14\x61ntiklepto_signature\x18\x04 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignatureRequestH\x00\x12J\n\x0esign_typed_msg\x18\x05 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.ETHSignTypedMessageRequestH\x00\x12L\n\x0ftyped_msg_value\x18\x06 \x01(\x0b\x32\x31.shiftcrypto.bitbox02.ETHTypedMessageValueRequestH\x00\x12\x43\n\x0csign_eip1559\x18\x07 \x01(\x0b\x32+.shiftcrypto.bitbox02.ETHSignEIP1559RequestH\x00\x42\t\n\x07request\"\xab\x02\n\x0b\x45THResponse\x12\x30\n\x03pub\x18\x01 \x01(\x0b\x32!.shiftcrypto.bitbox02.PubResponseH\x00\x12\x35\n\x04sign\x18\x02 \x01(\x0b\x32%.shiftcrypto.bitbox02.ETHSignResponseH\x00\x12X\n\x1c\x61ntiklepto_signer_commitment\x18\x03 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.AntiKleptoSignerCommitmentH\x00\x12M\n\x0ftyped_msg_value\x18\x04 \x01(\x0b\x32\x32.shiftcrypto.bitbox02.ETHTypedMessageValueResponseH\x00\x42\n\n\x08response*2\n\x07\x45THCoin\x12\x07\n\x03\x45TH\x10\x00\x12\x0e\n\nRopstenETH\x10\x01\x12\x0e\n\nRinkebyETH\x10\x02\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'eth_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _ETHCOIN._serialized_start=2569 - _ETHCOIN._serialized_end=2619 + _ETHCOIN._serialized_start=2924 + _ETHCOIN._serialized_end=2974 _ETHPUBREQUEST._serialized_start=68 _ETHPUBREQUEST._serialized_end=312 _ETHPUBREQUEST_OUTPUTTYPE._serialized_start=277 _ETHPUBREQUEST_OUTPUTTYPE._serialized_end=312 _ETHSIGNREQUEST._serialized_start=315 _ETHSIGNREQUEST._serialized_end=596 - _ETHSIGNMESSAGEREQUEST._serialized_start=599 - _ETHSIGNMESSAGEREQUEST._serialized_end=799 - _ETHSIGNRESPONSE._serialized_start=801 - _ETHSIGNRESPONSE._serialized_end=837 - _ETHSIGNTYPEDMESSAGEREQUEST._serialized_start=840 - _ETHSIGNTYPEDMESSAGEREQUEST._serialized_end=1603 - _ETHSIGNTYPEDMESSAGEREQUEST_MEMBERTYPE._serialized_start=1088 - _ETHSIGNTYPEDMESSAGEREQUEST_MEMBERTYPE._serialized_end=1289 - _ETHSIGNTYPEDMESSAGEREQUEST_MEMBER._serialized_start=1291 - _ETHSIGNTYPEDMESSAGEREQUEST_MEMBER._serialized_end=1388 - _ETHSIGNTYPEDMESSAGEREQUEST_STRUCTTYPE._serialized_start=1390 - _ETHSIGNTYPEDMESSAGEREQUEST_STRUCTTYPE._serialized_end=1490 - _ETHSIGNTYPEDMESSAGEREQUEST_DATATYPE._serialized_start=1492 - _ETHSIGNTYPEDMESSAGEREQUEST_DATATYPE._serialized_end=1603 - _ETHTYPEDMESSAGEVALUERESPONSE._serialized_start=1606 - _ETHTYPEDMESSAGEVALUERESPONSE._serialized_end=1786 - _ETHTYPEDMESSAGEVALUERESPONSE_ROOTOBJECT._serialized_start=1736 - _ETHTYPEDMESSAGEVALUERESPONSE_ROOTOBJECT._serialized_end=1786 - _ETHTYPEDMESSAGEVALUEREQUEST._serialized_start=1788 - _ETHTYPEDMESSAGEVALUEREQUEST._serialized_end=1832 - _ETHREQUEST._serialized_start=1835 - _ETHREQUEST._serialized_end=2265 - _ETHRESPONSE._serialized_start=2268 - _ETHRESPONSE._serialized_end=2567 + _ETHSIGNEIP1559REQUEST._serialized_start=599 + _ETHSIGNEIP1559REQUEST._serialized_end=882 + _ETHSIGNMESSAGEREQUEST._serialized_start=885 + _ETHSIGNMESSAGEREQUEST._serialized_end=1085 + _ETHSIGNRESPONSE._serialized_start=1087 + _ETHSIGNRESPONSE._serialized_end=1123 + _ETHSIGNTYPEDMESSAGEREQUEST._serialized_start=1126 + _ETHSIGNTYPEDMESSAGEREQUEST._serialized_end=1889 + _ETHSIGNTYPEDMESSAGEREQUEST_MEMBERTYPE._serialized_start=1374 + _ETHSIGNTYPEDMESSAGEREQUEST_MEMBERTYPE._serialized_end=1575 + _ETHSIGNTYPEDMESSAGEREQUEST_MEMBER._serialized_start=1577 + _ETHSIGNTYPEDMESSAGEREQUEST_MEMBER._serialized_end=1674 + _ETHSIGNTYPEDMESSAGEREQUEST_STRUCTTYPE._serialized_start=1676 + _ETHSIGNTYPEDMESSAGEREQUEST_STRUCTTYPE._serialized_end=1776 + _ETHSIGNTYPEDMESSAGEREQUEST_DATATYPE._serialized_start=1778 + _ETHSIGNTYPEDMESSAGEREQUEST_DATATYPE._serialized_end=1889 + _ETHTYPEDMESSAGEVALUERESPONSE._serialized_start=1892 + _ETHTYPEDMESSAGEVALUERESPONSE._serialized_end=2072 + _ETHTYPEDMESSAGEVALUERESPONSE_ROOTOBJECT._serialized_start=2022 + _ETHTYPEDMESSAGEVALUERESPONSE_ROOTOBJECT._serialized_end=2072 + _ETHTYPEDMESSAGEVALUEREQUEST._serialized_start=2074 + _ETHTYPEDMESSAGEVALUEREQUEST._serialized_end=2118 + _ETHREQUEST._serialized_start=2121 + _ETHREQUEST._serialized_end=2620 + _ETHRESPONSE._serialized_start=2623 + _ETHRESPONSE._serialized_end=2922 # @@protoc_insertion_point(module_scope) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.pyi b/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.pyi index b1498cf73..e29bbbad7 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.pyi +++ b/hwilib/devices/bitbox02_lib/communication/generated/eth_pb2.pyi @@ -85,6 +85,7 @@ class ETHPubRequest(google.protobuf.message.Message): global___ETHPubRequest = ETHPubRequest class ETHSignRequest(google.protobuf.message.Message): + """TX payload for "legacy" (EIP-155) transactions: https://eips.ethereum.org/EIPS/eip-155""" DESCRIPTOR: google.protobuf.descriptor.Descriptor COIN_FIELD_NUMBER: builtins.int KEYPATH_FIELD_NUMBER: builtins.int @@ -139,6 +140,60 @@ class ETHSignRequest(google.protobuf.message.Message): def ClearField(self, field_name: typing_extensions.Literal["chain_id",b"chain_id","coin",b"coin","data",b"data","gas_limit",b"gas_limit","gas_price",b"gas_price","host_nonce_commitment",b"host_nonce_commitment","keypath",b"keypath","nonce",b"nonce","recipient",b"recipient","value",b"value"]) -> None: ... global___ETHSignRequest = ETHSignRequest +class ETHSignEIP1559Request(google.protobuf.message.Message): + """TX payload for an EIP-1559 (type 2) transaction: https://eips.ethereum.org/EIPS/eip-1559""" + DESCRIPTOR: google.protobuf.descriptor.Descriptor + CHAIN_ID_FIELD_NUMBER: builtins.int + KEYPATH_FIELD_NUMBER: builtins.int + NONCE_FIELD_NUMBER: builtins.int + MAX_PRIORITY_FEE_PER_GAS_FIELD_NUMBER: builtins.int + MAX_FEE_PER_GAS_FIELD_NUMBER: builtins.int + GAS_LIMIT_FIELD_NUMBER: builtins.int + RECIPIENT_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + HOST_NONCE_COMMITMENT_FIELD_NUMBER: builtins.int + chain_id: builtins.int + @property + def keypath(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + nonce: builtins.bytes + """smallest big endian serialization, max. 16 bytes""" + + max_priority_fee_per_gas: builtins.bytes + """smallest big endian serialization, max. 16 bytes""" + + max_fee_per_gas: builtins.bytes + """smallest big endian serialization, max. 16 bytes""" + + gas_limit: builtins.bytes + """smallest big endian serialization, max. 16 bytes""" + + recipient: builtins.bytes + """20 byte recipient""" + + value: builtins.bytes + """smallest big endian serialization, max. 32 bytes""" + + data: builtins.bytes + @property + def host_nonce_commitment(self) -> antiklepto_pb2.AntiKleptoHostNonceCommitment: ... + def __init__(self, + *, + chain_id: builtins.int = ..., + keypath: typing.Optional[typing.Iterable[builtins.int]] = ..., + nonce: builtins.bytes = ..., + max_priority_fee_per_gas: builtins.bytes = ..., + max_fee_per_gas: builtins.bytes = ..., + gas_limit: builtins.bytes = ..., + recipient: builtins.bytes = ..., + value: builtins.bytes = ..., + data: builtins.bytes = ..., + host_nonce_commitment: typing.Optional[antiklepto_pb2.AntiKleptoHostNonceCommitment] = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["host_nonce_commitment",b"host_nonce_commitment"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["chain_id",b"chain_id","data",b"data","gas_limit",b"gas_limit","host_nonce_commitment",b"host_nonce_commitment","keypath",b"keypath","max_fee_per_gas",b"max_fee_per_gas","max_priority_fee_per_gas",b"max_priority_fee_per_gas","nonce",b"nonce","recipient",b"recipient","value",b"value"]) -> None: ... +global___ETHSignEIP1559Request = ETHSignEIP1559Request + class ETHSignMessageRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor COIN_FIELD_NUMBER: builtins.int @@ -339,6 +394,7 @@ class ETHRequest(google.protobuf.message.Message): ANTIKLEPTO_SIGNATURE_FIELD_NUMBER: builtins.int SIGN_TYPED_MSG_FIELD_NUMBER: builtins.int TYPED_MSG_VALUE_FIELD_NUMBER: builtins.int + SIGN_EIP1559_FIELD_NUMBER: builtins.int @property def pub(self) -> global___ETHPubRequest: ... @property @@ -351,6 +407,8 @@ class ETHRequest(google.protobuf.message.Message): def sign_typed_msg(self) -> global___ETHSignTypedMessageRequest: ... @property def typed_msg_value(self) -> global___ETHTypedMessageValueRequest: ... + @property + def sign_eip1559(self) -> global___ETHSignEIP1559Request: ... def __init__(self, *, pub: typing.Optional[global___ETHPubRequest] = ..., @@ -359,10 +417,11 @@ class ETHRequest(google.protobuf.message.Message): antiklepto_signature: typing.Optional[antiklepto_pb2.AntiKleptoSignatureRequest] = ..., sign_typed_msg: typing.Optional[global___ETHSignTypedMessageRequest] = ..., typed_msg_value: typing.Optional[global___ETHTypedMessageValueRequest] = ..., + sign_eip1559: typing.Optional[global___ETHSignEIP1559Request] = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["antiklepto_signature",b"antiklepto_signature","pub",b"pub","request",b"request","sign",b"sign","sign_msg",b"sign_msg","sign_typed_msg",b"sign_typed_msg","typed_msg_value",b"typed_msg_value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["antiklepto_signature",b"antiklepto_signature","pub",b"pub","request",b"request","sign",b"sign","sign_msg",b"sign_msg","sign_typed_msg",b"sign_typed_msg","typed_msg_value",b"typed_msg_value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["request",b"request"]) -> typing.Optional[typing_extensions.Literal["pub","sign","sign_msg","antiklepto_signature","sign_typed_msg","typed_msg_value"]]: ... + def HasField(self, field_name: typing_extensions.Literal["antiklepto_signature",b"antiklepto_signature","pub",b"pub","request",b"request","sign",b"sign","sign_eip1559",b"sign_eip1559","sign_msg",b"sign_msg","sign_typed_msg",b"sign_typed_msg","typed_msg_value",b"typed_msg_value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["antiklepto_signature",b"antiklepto_signature","pub",b"pub","request",b"request","sign",b"sign","sign_eip1559",b"sign_eip1559","sign_msg",b"sign_msg","sign_typed_msg",b"sign_typed_msg","typed_msg_value",b"typed_msg_value"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["request",b"request"]) -> typing.Optional[typing_extensions.Literal["pub","sign","sign_msg","antiklepto_signature","sign_typed_msg","typed_msg_value","sign_eip1559"]]: ... global___ETHRequest = ETHRequest class ETHResponse(google.protobuf.message.Message): diff --git a/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.py b/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.py index 8d6efa0a2..4606d1d94 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.py +++ b/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.py @@ -23,7 +23,7 @@ from . import perform_attestation_pb2 as perform__attestation__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\thww.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x15\x62\x61\x63kup_commands.proto\x1a\x15\x62itbox02_system.proto\x1a\tbtc.proto\x1a\rcardano.proto\x1a\teth.proto\x1a\x0ekeystore.proto\x1a\x0emnemonic.proto\x1a\x0csystem.proto\x1a\x19perform_attestation.proto\"&\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\"\t\n\x07Success\"\xc8\r\n\x07Request\x12\x41\n\x0b\x64\x65vice_name\x18\x02 \x01(\x0b\x32*.shiftcrypto.bitbox02.SetDeviceNameRequestH\x00\x12I\n\x0f\x64\x65vice_language\x18\x03 \x01(\x0b\x32..shiftcrypto.bitbox02.SetDeviceLanguageRequestH\x00\x12>\n\x0b\x64\x65vice_info\x18\x04 \x01(\x0b\x32\'.shiftcrypto.bitbox02.DeviceInfoRequestH\x00\x12@\n\x0cset_password\x18\x05 \x01(\x0b\x32(.shiftcrypto.bitbox02.SetPasswordRequestH\x00\x12\x42\n\rcreate_backup\x18\x06 \x01(\x0b\x32).shiftcrypto.bitbox02.CreateBackupRequestH\x00\x12\x42\n\rshow_mnemonic\x18\x07 \x01(\x0b\x32).shiftcrypto.bitbox02.ShowMnemonicRequestH\x00\x12\x36\n\x07\x62tc_pub\x18\x08 \x01(\x0b\x32#.shiftcrypto.bitbox02.BTCPubRequestH\x00\x12\x41\n\rbtc_sign_init\x18\t \x01(\x0b\x32(.shiftcrypto.bitbox02.BTCSignInitRequestH\x00\x12\x43\n\x0e\x62tc_sign_input\x18\n \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignInputRequestH\x00\x12\x45\n\x0f\x62tc_sign_output\x18\x0b \x01(\x0b\x32*.shiftcrypto.bitbox02.BTCSignOutputRequestH\x00\x12O\n\x14insert_remove_sdcard\x18\x0c \x01(\x0b\x32/.shiftcrypto.bitbox02.InsertRemoveSDCardRequestH\x00\x12@\n\x0c\x63heck_sdcard\x18\r \x01(\x0b\x32(.shiftcrypto.bitbox02.CheckSDCardRequestH\x00\x12\x64\n\x1fset_mnemonic_passphrase_enabled\x18\x0e \x01(\x0b\x32\x39.shiftcrypto.bitbox02.SetMnemonicPassphraseEnabledRequestH\x00\x12@\n\x0clist_backups\x18\x0f \x01(\x0b\x32(.shiftcrypto.bitbox02.ListBackupsRequestH\x00\x12\x44\n\x0erestore_backup\x18\x10 \x01(\x0b\x32*.shiftcrypto.bitbox02.RestoreBackupRequestH\x00\x12N\n\x13perform_attestation\x18\x11 \x01(\x0b\x32/.shiftcrypto.bitbox02.PerformAttestationRequestH\x00\x12\x35\n\x06reboot\x18\x12 \x01(\x0b\x32#.shiftcrypto.bitbox02.RebootRequestH\x00\x12@\n\x0c\x63heck_backup\x18\x13 \x01(\x0b\x32(.shiftcrypto.bitbox02.CheckBackupRequestH\x00\x12/\n\x03\x65th\x18\x14 \x01(\x0b\x32 .shiftcrypto.bitbox02.ETHRequestH\x00\x12\x33\n\x05reset\x18\x15 \x01(\x0b\x32\".shiftcrypto.bitbox02.ResetRequestH\x00\x12Q\n\x15restore_from_mnemonic\x18\x16 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.RestoreFromMnemonicRequestH\x00\x12\x43\n\x0b\x66ingerprint\x18\x18 \x01(\x0b\x32,.shiftcrypto.bitbox02.RootFingerprintRequestH\x00\x12/\n\x03\x62tc\x18\x19 \x01(\x0b\x32 .shiftcrypto.bitbox02.BTCRequestH\x00\x12U\n\x17\x65lectrum_encryption_key\x18\x1a \x01(\x0b\x32\x32.shiftcrypto.bitbox02.ElectrumEncryptionKeyRequestH\x00\x12\x37\n\x07\x63\x61rdano\x18\x1b \x01(\x0b\x32$.shiftcrypto.bitbox02.CardanoRequestH\x00\x42\t\n\x07requestJ\x04\x08\x01\x10\x02J\x04\x08\x17\x10\x18\"\x89\x07\n\x08Response\x12\x30\n\x07success\x18\x01 \x01(\x0b\x32\x1d.shiftcrypto.bitbox02.SuccessH\x00\x12,\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x1b.shiftcrypto.bitbox02.ErrorH\x00\x12?\n\x0b\x64\x65vice_info\x18\x04 \x01(\x0b\x32(.shiftcrypto.bitbox02.DeviceInfoResponseH\x00\x12\x30\n\x03pub\x18\x05 \x01(\x0b\x32!.shiftcrypto.bitbox02.PubResponseH\x00\x12\x42\n\rbtc_sign_next\x18\x06 \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignNextResponseH\x00\x12\x41\n\x0clist_backups\x18\x07 \x01(\x0b\x32).shiftcrypto.bitbox02.ListBackupsResponseH\x00\x12\x41\n\x0c\x63heck_backup\x18\x08 \x01(\x0b\x32).shiftcrypto.bitbox02.CheckBackupResponseH\x00\x12O\n\x13perform_attestation\x18\t \x01(\x0b\x32\x30.shiftcrypto.bitbox02.PerformAttestationResponseH\x00\x12\x41\n\x0c\x63heck_sdcard\x18\n \x01(\x0b\x32).shiftcrypto.bitbox02.CheckSDCardResponseH\x00\x12\x30\n\x03\x65th\x18\x0b \x01(\x0b\x32!.shiftcrypto.bitbox02.ETHResponseH\x00\x12\x44\n\x0b\x66ingerprint\x18\x0c \x01(\x0b\x32-.shiftcrypto.bitbox02.RootFingerprintResponseH\x00\x12\x30\n\x03\x62tc\x18\r \x01(\x0b\x32!.shiftcrypto.bitbox02.BTCResponseH\x00\x12V\n\x17\x65lectrum_encryption_key\x18\x0e \x01(\x0b\x32\x33.shiftcrypto.bitbox02.ElectrumEncryptionKeyResponseH\x00\x12\x38\n\x07\x63\x61rdano\x18\x0f \x01(\x0b\x32%.shiftcrypto.bitbox02.CardanoResponseH\x00\x42\n\n\x08responseJ\x04\x08\x03\x10\x04\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\thww.proto\x12\x14shiftcrypto.bitbox02\x1a\x0c\x63ommon.proto\x1a\x15\x62\x61\x63kup_commands.proto\x1a\x15\x62itbox02_system.proto\x1a\tbtc.proto\x1a\rcardano.proto\x1a\teth.proto\x1a\x0ekeystore.proto\x1a\x0emnemonic.proto\x1a\x0csystem.proto\x1a\x19perform_attestation.proto\"&\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\"\t\n\x07Success\"\xfd\r\n\x07Request\x12\x41\n\x0b\x64\x65vice_name\x18\x02 \x01(\x0b\x32*.shiftcrypto.bitbox02.SetDeviceNameRequestH\x00\x12I\n\x0f\x64\x65vice_language\x18\x03 \x01(\x0b\x32..shiftcrypto.bitbox02.SetDeviceLanguageRequestH\x00\x12>\n\x0b\x64\x65vice_info\x18\x04 \x01(\x0b\x32\'.shiftcrypto.bitbox02.DeviceInfoRequestH\x00\x12@\n\x0cset_password\x18\x05 \x01(\x0b\x32(.shiftcrypto.bitbox02.SetPasswordRequestH\x00\x12\x42\n\rcreate_backup\x18\x06 \x01(\x0b\x32).shiftcrypto.bitbox02.CreateBackupRequestH\x00\x12\x42\n\rshow_mnemonic\x18\x07 \x01(\x0b\x32).shiftcrypto.bitbox02.ShowMnemonicRequestH\x00\x12\x36\n\x07\x62tc_pub\x18\x08 \x01(\x0b\x32#.shiftcrypto.bitbox02.BTCPubRequestH\x00\x12\x41\n\rbtc_sign_init\x18\t \x01(\x0b\x32(.shiftcrypto.bitbox02.BTCSignInitRequestH\x00\x12\x43\n\x0e\x62tc_sign_input\x18\n \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignInputRequestH\x00\x12\x45\n\x0f\x62tc_sign_output\x18\x0b \x01(\x0b\x32*.shiftcrypto.bitbox02.BTCSignOutputRequestH\x00\x12O\n\x14insert_remove_sdcard\x18\x0c \x01(\x0b\x32/.shiftcrypto.bitbox02.InsertRemoveSDCardRequestH\x00\x12@\n\x0c\x63heck_sdcard\x18\r \x01(\x0b\x32(.shiftcrypto.bitbox02.CheckSDCardRequestH\x00\x12\x64\n\x1fset_mnemonic_passphrase_enabled\x18\x0e \x01(\x0b\x32\x39.shiftcrypto.bitbox02.SetMnemonicPassphraseEnabledRequestH\x00\x12@\n\x0clist_backups\x18\x0f \x01(\x0b\x32(.shiftcrypto.bitbox02.ListBackupsRequestH\x00\x12\x44\n\x0erestore_backup\x18\x10 \x01(\x0b\x32*.shiftcrypto.bitbox02.RestoreBackupRequestH\x00\x12N\n\x13perform_attestation\x18\x11 \x01(\x0b\x32/.shiftcrypto.bitbox02.PerformAttestationRequestH\x00\x12\x35\n\x06reboot\x18\x12 \x01(\x0b\x32#.shiftcrypto.bitbox02.RebootRequestH\x00\x12@\n\x0c\x63heck_backup\x18\x13 \x01(\x0b\x32(.shiftcrypto.bitbox02.CheckBackupRequestH\x00\x12/\n\x03\x65th\x18\x14 \x01(\x0b\x32 .shiftcrypto.bitbox02.ETHRequestH\x00\x12\x33\n\x05reset\x18\x15 \x01(\x0b\x32\".shiftcrypto.bitbox02.ResetRequestH\x00\x12Q\n\x15restore_from_mnemonic\x18\x16 \x01(\x0b\x32\x30.shiftcrypto.bitbox02.RestoreFromMnemonicRequestH\x00\x12\x43\n\x0b\x66ingerprint\x18\x18 \x01(\x0b\x32,.shiftcrypto.bitbox02.RootFingerprintRequestH\x00\x12/\n\x03\x62tc\x18\x19 \x01(\x0b\x32 .shiftcrypto.bitbox02.BTCRequestH\x00\x12U\n\x17\x65lectrum_encryption_key\x18\x1a \x01(\x0b\x32\x32.shiftcrypto.bitbox02.ElectrumEncryptionKeyRequestH\x00\x12\x37\n\x07\x63\x61rdano\x18\x1b \x01(\x0b\x32$.shiftcrypto.bitbox02.CardanoRequestH\x00\x12\x33\n\x05\x62ip85\x18\x1c \x01(\x0b\x32\".shiftcrypto.bitbox02.BIP85RequestH\x00\x42\t\n\x07requestJ\x04\x08\x01\x10\x02J\x04\x08\x17\x10\x18\"\xbf\x07\n\x08Response\x12\x30\n\x07success\x18\x01 \x01(\x0b\x32\x1d.shiftcrypto.bitbox02.SuccessH\x00\x12,\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x1b.shiftcrypto.bitbox02.ErrorH\x00\x12?\n\x0b\x64\x65vice_info\x18\x04 \x01(\x0b\x32(.shiftcrypto.bitbox02.DeviceInfoResponseH\x00\x12\x30\n\x03pub\x18\x05 \x01(\x0b\x32!.shiftcrypto.bitbox02.PubResponseH\x00\x12\x42\n\rbtc_sign_next\x18\x06 \x01(\x0b\x32).shiftcrypto.bitbox02.BTCSignNextResponseH\x00\x12\x41\n\x0clist_backups\x18\x07 \x01(\x0b\x32).shiftcrypto.bitbox02.ListBackupsResponseH\x00\x12\x41\n\x0c\x63heck_backup\x18\x08 \x01(\x0b\x32).shiftcrypto.bitbox02.CheckBackupResponseH\x00\x12O\n\x13perform_attestation\x18\t \x01(\x0b\x32\x30.shiftcrypto.bitbox02.PerformAttestationResponseH\x00\x12\x41\n\x0c\x63heck_sdcard\x18\n \x01(\x0b\x32).shiftcrypto.bitbox02.CheckSDCardResponseH\x00\x12\x30\n\x03\x65th\x18\x0b \x01(\x0b\x32!.shiftcrypto.bitbox02.ETHResponseH\x00\x12\x44\n\x0b\x66ingerprint\x18\x0c \x01(\x0b\x32-.shiftcrypto.bitbox02.RootFingerprintResponseH\x00\x12\x30\n\x03\x62tc\x18\r \x01(\x0b\x32!.shiftcrypto.bitbox02.BTCResponseH\x00\x12V\n\x17\x65lectrum_encryption_key\x18\x0e \x01(\x0b\x32\x33.shiftcrypto.bitbox02.ElectrumEncryptionKeyResponseH\x00\x12\x38\n\x07\x63\x61rdano\x18\x0f \x01(\x0b\x32%.shiftcrypto.bitbox02.CardanoResponseH\x00\x12\x34\n\x05\x62ip85\x18\x10 \x01(\x0b\x32#.shiftcrypto.bitbox02.BIP85ResponseH\x00\x42\n\n\x08responseJ\x04\x08\x03\x10\x04\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'hww_pb2', globals()) @@ -35,7 +35,7 @@ _SUCCESS._serialized_start=245 _SUCCESS._serialized_end=254 _REQUEST._serialized_start=257 - _REQUEST._serialized_end=1993 - _RESPONSE._serialized_start=1996 - _RESPONSE._serialized_end=2901 + _REQUEST._serialized_end=2046 + _RESPONSE._serialized_start=2049 + _RESPONSE._serialized_end=3008 # @@protoc_insertion_point(module_scope) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.pyi b/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.pyi index 2244acb8e..df9aeacf1 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.pyi +++ b/hwilib/devices/bitbox02_lib/communication/generated/hww_pb2.pyi @@ -67,6 +67,7 @@ class Request(google.protobuf.message.Message): BTC_FIELD_NUMBER: builtins.int ELECTRUM_ENCRYPTION_KEY_FIELD_NUMBER: builtins.int CARDANO_FIELD_NUMBER: builtins.int + BIP85_FIELD_NUMBER: builtins.int @property def device_name(self) -> bitbox02_system_pb2.SetDeviceNameRequest: """removed: RandomNumberRequest random_number = 1;""" @@ -121,6 +122,8 @@ class Request(google.protobuf.message.Message): def electrum_encryption_key(self) -> keystore_pb2.ElectrumEncryptionKeyRequest: ... @property def cardano(self) -> cardano_pb2.CardanoRequest: ... + @property + def bip85(self) -> keystore_pb2.BIP85Request: ... def __init__(self, *, device_name: typing.Optional[bitbox02_system_pb2.SetDeviceNameRequest] = ..., @@ -148,10 +151,11 @@ class Request(google.protobuf.message.Message): btc: typing.Optional[btc_pb2.BTCRequest] = ..., electrum_encryption_key: typing.Optional[keystore_pb2.ElectrumEncryptionKeyRequest] = ..., cardano: typing.Optional[cardano_pb2.CardanoRequest] = ..., + bip85: typing.Optional[keystore_pb2.BIP85Request] = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["btc",b"btc","btc_pub",b"btc_pub","btc_sign_init",b"btc_sign_init","btc_sign_input",b"btc_sign_input","btc_sign_output",b"btc_sign_output","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","create_backup",b"create_backup","device_info",b"device_info","device_language",b"device_language","device_name",b"device_name","electrum_encryption_key",b"electrum_encryption_key","eth",b"eth","fingerprint",b"fingerprint","insert_remove_sdcard",b"insert_remove_sdcard","list_backups",b"list_backups","perform_attestation",b"perform_attestation","reboot",b"reboot","request",b"request","reset",b"reset","restore_backup",b"restore_backup","restore_from_mnemonic",b"restore_from_mnemonic","set_mnemonic_passphrase_enabled",b"set_mnemonic_passphrase_enabled","set_password",b"set_password","show_mnemonic",b"show_mnemonic"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["btc",b"btc","btc_pub",b"btc_pub","btc_sign_init",b"btc_sign_init","btc_sign_input",b"btc_sign_input","btc_sign_output",b"btc_sign_output","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","create_backup",b"create_backup","device_info",b"device_info","device_language",b"device_language","device_name",b"device_name","electrum_encryption_key",b"electrum_encryption_key","eth",b"eth","fingerprint",b"fingerprint","insert_remove_sdcard",b"insert_remove_sdcard","list_backups",b"list_backups","perform_attestation",b"perform_attestation","reboot",b"reboot","request",b"request","reset",b"reset","restore_backup",b"restore_backup","restore_from_mnemonic",b"restore_from_mnemonic","set_mnemonic_passphrase_enabled",b"set_mnemonic_passphrase_enabled","set_password",b"set_password","show_mnemonic",b"show_mnemonic"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["request",b"request"]) -> typing.Optional[typing_extensions.Literal["device_name","device_language","device_info","set_password","create_backup","show_mnemonic","btc_pub","btc_sign_init","btc_sign_input","btc_sign_output","insert_remove_sdcard","check_sdcard","set_mnemonic_passphrase_enabled","list_backups","restore_backup","perform_attestation","reboot","check_backup","eth","reset","restore_from_mnemonic","fingerprint","btc","electrum_encryption_key","cardano"]]: ... + def HasField(self, field_name: typing_extensions.Literal["bip85",b"bip85","btc",b"btc","btc_pub",b"btc_pub","btc_sign_init",b"btc_sign_init","btc_sign_input",b"btc_sign_input","btc_sign_output",b"btc_sign_output","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","create_backup",b"create_backup","device_info",b"device_info","device_language",b"device_language","device_name",b"device_name","electrum_encryption_key",b"electrum_encryption_key","eth",b"eth","fingerprint",b"fingerprint","insert_remove_sdcard",b"insert_remove_sdcard","list_backups",b"list_backups","perform_attestation",b"perform_attestation","reboot",b"reboot","request",b"request","reset",b"reset","restore_backup",b"restore_backup","restore_from_mnemonic",b"restore_from_mnemonic","set_mnemonic_passphrase_enabled",b"set_mnemonic_passphrase_enabled","set_password",b"set_password","show_mnemonic",b"show_mnemonic"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["bip85",b"bip85","btc",b"btc","btc_pub",b"btc_pub","btc_sign_init",b"btc_sign_init","btc_sign_input",b"btc_sign_input","btc_sign_output",b"btc_sign_output","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","create_backup",b"create_backup","device_info",b"device_info","device_language",b"device_language","device_name",b"device_name","electrum_encryption_key",b"electrum_encryption_key","eth",b"eth","fingerprint",b"fingerprint","insert_remove_sdcard",b"insert_remove_sdcard","list_backups",b"list_backups","perform_attestation",b"perform_attestation","reboot",b"reboot","request",b"request","reset",b"reset","restore_backup",b"restore_backup","restore_from_mnemonic",b"restore_from_mnemonic","set_mnemonic_passphrase_enabled",b"set_mnemonic_passphrase_enabled","set_password",b"set_password","show_mnemonic",b"show_mnemonic"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["request",b"request"]) -> typing.Optional[typing_extensions.Literal["device_name","device_language","device_info","set_password","create_backup","show_mnemonic","btc_pub","btc_sign_init","btc_sign_input","btc_sign_output","insert_remove_sdcard","check_sdcard","set_mnemonic_passphrase_enabled","list_backups","restore_backup","perform_attestation","reboot","check_backup","eth","reset","restore_from_mnemonic","fingerprint","btc","electrum_encryption_key","cardano","bip85"]]: ... global___Request = Request class Response(google.protobuf.message.Message): @@ -170,6 +174,7 @@ class Response(google.protobuf.message.Message): BTC_FIELD_NUMBER: builtins.int ELECTRUM_ENCRYPTION_KEY_FIELD_NUMBER: builtins.int CARDANO_FIELD_NUMBER: builtins.int + BIP85_FIELD_NUMBER: builtins.int @property def success(self) -> global___Success: ... @property @@ -200,6 +205,8 @@ class Response(google.protobuf.message.Message): def electrum_encryption_key(self) -> keystore_pb2.ElectrumEncryptionKeyResponse: ... @property def cardano(self) -> cardano_pb2.CardanoResponse: ... + @property + def bip85(self) -> keystore_pb2.BIP85Response: ... def __init__(self, *, success: typing.Optional[global___Success] = ..., @@ -216,8 +223,9 @@ class Response(google.protobuf.message.Message): btc: typing.Optional[btc_pb2.BTCResponse] = ..., electrum_encryption_key: typing.Optional[keystore_pb2.ElectrumEncryptionKeyResponse] = ..., cardano: typing.Optional[cardano_pb2.CardanoResponse] = ..., + bip85: typing.Optional[keystore_pb2.BIP85Response] = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["btc",b"btc","btc_sign_next",b"btc_sign_next","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","device_info",b"device_info","electrum_encryption_key",b"electrum_encryption_key","error",b"error","eth",b"eth","fingerprint",b"fingerprint","list_backups",b"list_backups","perform_attestation",b"perform_attestation","pub",b"pub","response",b"response","success",b"success"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["btc",b"btc","btc_sign_next",b"btc_sign_next","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","device_info",b"device_info","electrum_encryption_key",b"electrum_encryption_key","error",b"error","eth",b"eth","fingerprint",b"fingerprint","list_backups",b"list_backups","perform_attestation",b"perform_attestation","pub",b"pub","response",b"response","success",b"success"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["response",b"response"]) -> typing.Optional[typing_extensions.Literal["success","error","device_info","pub","btc_sign_next","list_backups","check_backup","perform_attestation","check_sdcard","eth","fingerprint","btc","electrum_encryption_key","cardano"]]: ... + def HasField(self, field_name: typing_extensions.Literal["bip85",b"bip85","btc",b"btc","btc_sign_next",b"btc_sign_next","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","device_info",b"device_info","electrum_encryption_key",b"electrum_encryption_key","error",b"error","eth",b"eth","fingerprint",b"fingerprint","list_backups",b"list_backups","perform_attestation",b"perform_attestation","pub",b"pub","response",b"response","success",b"success"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["bip85",b"bip85","btc",b"btc","btc_sign_next",b"btc_sign_next","cardano",b"cardano","check_backup",b"check_backup","check_sdcard",b"check_sdcard","device_info",b"device_info","electrum_encryption_key",b"electrum_encryption_key","error",b"error","eth",b"eth","fingerprint",b"fingerprint","list_backups",b"list_backups","perform_attestation",b"perform_attestation","pub",b"pub","response",b"response","success",b"success"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["response",b"response"]) -> typing.Optional[typing_extensions.Literal["success","error","device_info","pub","btc_sign_next","list_backups","check_backup","perform_attestation","check_sdcard","eth","fingerprint","btc","electrum_encryption_key","cardano","bip85"]]: ... global___Response = Response diff --git a/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.py b/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.py index ec262caf7..ba14a68d7 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.py +++ b/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.py @@ -11,17 +11,24 @@ _sym_db = _symbol_database.Default() +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ekeystore.proto\x12\x14shiftcrypto.bitbox02\"/\n\x1c\x45lectrumEncryptionKeyRequest\x12\x0f\n\x07keypath\x18\x01 \x03(\r\",\n\x1d\x45lectrumEncryptionKeyResponse\x12\x0b\n\x03key\x18\x01 \x01(\tb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ekeystore.proto\x12\x14shiftcrypto.bitbox02\x1a\x1bgoogle/protobuf/empty.proto\"/\n\x1c\x45lectrumEncryptionKeyRequest\x12\x0f\n\x07keypath\x18\x01 \x03(\r\",\n\x1d\x45lectrumEncryptionKeyResponse\x12\x0b\n\x03key\x18\x01 \x01(\t\"\x97\x01\n\x0c\x42IP85Request\x12\'\n\x05\x62ip39\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x02ln\x18\x02 \x01(\x0b\x32(.shiftcrypto.bitbox02.BIP85Request.AppLnH\x00\x1a\x1f\n\x05\x41ppLn\x12\x16\n\x0e\x61\x63\x63ount_number\x18\x01 \x01(\rB\x05\n\x03\x61pp\"M\n\rBIP85Response\x12\'\n\x05\x62ip39\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x0c\n\x02ln\x18\x02 \x01(\x0cH\x00\x42\x05\n\x03\x61ppb\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'keystore_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _ELECTRUMENCRYPTIONKEYREQUEST._serialized_start=40 - _ELECTRUMENCRYPTIONKEYREQUEST._serialized_end=87 - _ELECTRUMENCRYPTIONKEYRESPONSE._serialized_start=89 - _ELECTRUMENCRYPTIONKEYRESPONSE._serialized_end=133 + _ELECTRUMENCRYPTIONKEYREQUEST._serialized_start=69 + _ELECTRUMENCRYPTIONKEYREQUEST._serialized_end=116 + _ELECTRUMENCRYPTIONKEYRESPONSE._serialized_start=118 + _ELECTRUMENCRYPTIONKEYRESPONSE._serialized_end=162 + _BIP85REQUEST._serialized_start=165 + _BIP85REQUEST._serialized_end=316 + _BIP85REQUEST_APPLN._serialized_start=278 + _BIP85REQUEST_APPLN._serialized_end=309 + _BIP85RESPONSE._serialized_start=318 + _BIP85RESPONSE._serialized_end=395 # @@protoc_insertion_point(module_scope) diff --git a/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.pyi b/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.pyi index 3296d1162..8159aee00 100644 --- a/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.pyi +++ b/hwilib/devices/bitbox02_lib/communication/generated/keystore_pb2.pyi @@ -4,6 +4,7 @@ isort:skip_file """ import builtins import google.protobuf.descriptor +import google.protobuf.empty_pb2 import google.protobuf.internal.containers import google.protobuf.message import typing @@ -33,3 +34,48 @@ class ElectrumEncryptionKeyResponse(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key",b"key"]) -> None: ... global___ElectrumEncryptionKeyResponse = ElectrumEncryptionKeyResponse + +class BIP85Request(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + class AppLn(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + ACCOUNT_NUMBER_FIELD_NUMBER: builtins.int + account_number: builtins.int + def __init__(self, + *, + account_number: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["account_number",b"account_number"]) -> None: ... + + BIP39_FIELD_NUMBER: builtins.int + LN_FIELD_NUMBER: builtins.int + @property + def bip39(self) -> google.protobuf.empty_pb2.Empty: ... + @property + def ln(self) -> global___BIP85Request.AppLn: ... + def __init__(self, + *, + bip39: typing.Optional[google.protobuf.empty_pb2.Empty] = ..., + ln: typing.Optional[global___BIP85Request.AppLn] = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39","ln",b"ln"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39","ln",b"ln"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["app",b"app"]) -> typing.Optional[typing_extensions.Literal["bip39","ln"]]: ... +global___BIP85Request = BIP85Request + +class BIP85Response(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + BIP39_FIELD_NUMBER: builtins.int + LN_FIELD_NUMBER: builtins.int + @property + def bip39(self) -> google.protobuf.empty_pb2.Empty: ... + ln: builtins.bytes + def __init__(self, + *, + bip39: typing.Optional[google.protobuf.empty_pb2.Empty] = ..., + ln: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39","ln",b"ln"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39","ln",b"ln"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["app",b"app"]) -> typing.Optional[typing_extensions.Literal["bip39","ln"]]: ... +global___BIP85Response = BIP85Response From 3c3a185200fb92281128d0d84e0697da21f7dc09 Mon Sep 17 00:00:00 2001 From: asi345 Date: Wed, 22 May 2024 11:17:24 +0200 Subject: [PATCH 2/2] bitbox02: add bitbox02 simulator and tests Signed-off-by: asi345 --- .github/actions/install-sim/action.yml | 7 ++ .github/workflows/ci.yml | 3 + ci/build_bitbox02.sh | 9 ++ ci/cirrus.Dockerfile | 5 ++ hwilib/devices/bitbox02.py | 120 ++++++++++++++++--------- test/README.md | 45 ++++++++-- test/run_tests.py | 14 ++- test/setup_environment.sh | 35 ++++++++ test/test_bitbox02.py | 109 ++++++++++++++++++++++ test/test_coldcard.py | 1 + test/test_device.py | 32 ++++--- test/test_digitalbitbox.py | 1 + test/test_jade.py | 1 + test/test_keepkey.py | 1 + test/test_ledger.py | 1 + test/test_trezor.py | 1 + 16 files changed, 325 insertions(+), 60 deletions(-) create mode 100755 ci/build_bitbox02.sh create mode 100644 test/test_bitbox02.py diff --git a/.github/actions/install-sim/action.yml b/.github/actions/install-sim/action.yml index f9799f122..abfbded13 100644 --- a/.github/actions/install-sim/action.yml +++ b/.github/actions/install-sim/action.yml @@ -38,6 +38,13 @@ runs: apt-get install -y libusb-1.0-0 tar -xvf mcu.tar.gz + - if: inputs.device == 'bitbox02' + shell: bash + run: | + apt-get update + apt-get install -y libusb-1.0-0 docker.io + tar -xvf bitbox02.tar.gz + - if: inputs.device == 'jade' shell: bash run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96b2ed369..bbf858dea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,6 +153,7 @@ jobs: - { name: 'jade', archive: 'jade', paths: 'test/work/jade/simulator' } - { name: 'ledger', archive: 'speculos', paths: 'test/work/speculos' } - { name: 'keepkey', archive: 'keepkey-firmware', paths: 'test/work/keepkey-firmware/bin' } + - { name: 'bitbox02', archive: 'bitbox02', paths: 'test/work/bitbox02-firmware/build-build/bin/simulator' } steps: - uses: actions/checkout@v4 @@ -219,6 +220,7 @@ jobs: - 'ledger' - 'ledger-legacy' - 'keepkey' + - 'bitbox02' script: - name: 'Wheel' install: 'pip install dist/*.whl' @@ -289,6 +291,7 @@ jobs: - 'ledger' - 'ledger-legacy' - 'keepkey' + - 'bitbox02' interface: [ 'library', 'cli', 'stdin' ] container: python:${{ matrix.python-version }} diff --git a/ci/build_bitbox02.sh b/ci/build_bitbox02.sh new file mode 100755 index 000000000..29b8a0bb2 --- /dev/null +++ b/ci/build_bitbox02.sh @@ -0,0 +1,9 @@ +docker volume rm bitbox02_volume || true +docker volume create bitbox02_volume +CONTAINER_VERSION=$(curl https://raw.githubusercontent.com/BitBoxSwiss/bitbox02-firmware/master/.containerversion) +docker pull shiftcrypto/firmware_v2:$CONTAINER_VERSION +docker run -i --rm -v bitbox02_volume:/bitbox02-firmware shiftcrypto/firmware_v2:$CONTAINER_VERSION bash -c \ + "cd /bitbox02-firmware && \ + git clone --recursive https://github.com/BitBoxSwiss/bitbox02-firmware.git . && \ + git config --global --add safe.directory ./ && \ + make -j simulator" \ No newline at end of file diff --git a/ci/cirrus.Dockerfile b/ci/cirrus.Dockerfile index ab4c11b10..17d6752d8 100644 --- a/ci/cirrus.Dockerfile +++ b/ci/cirrus.Dockerfile @@ -59,6 +59,11 @@ RUN protoc --version # docker build -f ci/cirrus.Dockerfile -t hwi_test . # docker run -it --entrypoint /bin/bash hwi_test # cd test; poetry run ./run_tests.py --ledger --coldcard --interface=cli --device-only +# For BitBox02: +# docker build -f ci/cirrus.Dockerfile -t hwi_test . +# ./ci/build_bitbox02.sh +# docker run -it -v bitbox02_volume:/test/work/bitbox02-firmware --name hwi --entrypoint /bin/bash hwi_test +# cd test; poetry run ./run_tests.py --bitbox02 --interface=cli --device-only #################### #################### diff --git a/hwilib/devices/bitbox02.py b/hwilib/devices/bitbox02.py index 173f9997d..9484e0aae 100644 --- a/hwilib/devices/bitbox02.py +++ b/hwilib/devices/bitbox02.py @@ -19,6 +19,7 @@ import base64 import builtins import sys +import socket from functools import wraps from .._base58 import decode_check, encode_check @@ -79,6 +80,8 @@ BitBoxNoiseConfig, ) +SIMULATOR_PATH = "127.0.0.1:15423" + class BitBox02Error(UnavailableActionError): def __init__(self, msg: str): """ @@ -178,10 +181,15 @@ def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain Enumerate all BitBox02 devices. Bootloaders excluded. """ result = [] - for device_info in devices.get_any_bitbox02s(): - path = device_info["path"].decode() - client = Bitbox02Client(path) - client.set_noise_config(SilentNoiseConfig()) + devs = [device_info["path"].decode() for device_info in devices.get_any_bitbox02s()] + if allow_emulators: + devs.append(SIMULATOR_PATH) + for path in devs: + client = Bitbox02Client(path=path) + if allow_emulators and client.simulator and not client.simulator.connected: + continue + if path != SIMULATOR_PATH: + client.set_noise_config(SilentNoiseConfig()) d_data: Dict[str, object] = {} bb02 = None with handle_errors(common_err_msgs["enumerate"], d_data): @@ -252,9 +260,31 @@ def func(*args, **kwargs): # type: ignore raise exc except FirmwareVersionOutdatedException as exc: raise DeviceNotReadyError(str(exc)) + except ValueError as e: + raise BadArgumentError(str(e)) return cast(T, func) +class BitBox02Simulator(): + def __init__(self) -> None: + self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + ip, port = SIMULATOR_PATH.split(":") + self.connected = True + try: + self.client_socket.connect((ip, int(port))) + except: + self.connected = False + + def write(self, data: bytes) -> None: + # Messages from client are always prefixed with HID report ID(0x00), which is not expected by the simulator. + self.client_socket.send(data[1:]) + + def read(self, size: int, timeout_ms: int) -> bytes: + res = self.client_socket.recv(64) + return res + + def close(self) -> None: + self.client_socket.close() # This class extends the HardwareWalletClient for BitBox02 specific things class Bitbox02Client(HardwareWalletClient): @@ -267,17 +297,23 @@ def __init__(self, path: str, password: Optional[str] = None, expert: bool = Fal "The BitBox02 does not accept a passphrase from the host. Please enable the passphrase option and enter the passphrase on the device during unlock." ) super().__init__(path, password=password, expert=expert, chain=chain) - - hid_device = hid.device() - hid_device.open_path(path.encode()) - self.transport = u2fhid.U2FHid(hid_device) + self.simulator = None + self.noise_config: BitBoxNoiseConfig = BitBoxNoiseConfig() + + if path != SIMULATOR_PATH: + hid_device = hid.device() + hid_device.open_path(path.encode()) + self.transport = u2fhid.U2FHid(hid_device) + self.noise_config = CLINoiseConfig() + else: + self.simulator = BitBox02Simulator() + if self.simulator.connected: + self.transport = u2fhid.U2FHid(self.simulator) self.device_path = path # use self.init() to access self.bb02. self.bb02: Optional[bitbox02.BitBox02] = None - self.noise_config: BitBoxNoiseConfig = CLINoiseConfig() - def set_noise_config(self, noise_config: BitBoxNoiseConfig) -> None: self.noise_config = noise_config @@ -285,38 +321,32 @@ def init(self, expect_initialized: Optional[bool] = True) -> bitbox02.BitBox02: if self.bb02 is not None: return self.bb02 - for device_info in devices.get_any_bitbox02s(): - if device_info["path"].decode() != self.device_path: - continue - - bb02 = bitbox02.BitBox02( - transport=self.transport, - device_info=device_info, - noise_config=self.noise_config, - ) - try: - bb02.check_min_version() - except FirmwareVersionOutdatedException as exc: - sys.stderr.write("WARNING: {}\n".format(exc)) - raise - self.bb02 = bb02 - is_initialized = bb02.device_info()["initialized"] - if expect_initialized is not None: - if expect_initialized: - if not is_initialized: - raise HWWError( - "The BitBox02 must be initialized first.", - DEVICE_NOT_INITIALIZED, - ) - elif is_initialized: - raise UnavailableActionError( - "The BitBox02 must be wiped before setup." + bb02 = bitbox02.BitBox02( + transport=self.transport, + # Passing None as device_info means the device will be queried for the relevant device info. + device_info=None, + noise_config=self.noise_config, + ) + try: + bb02.check_min_version() + except FirmwareVersionOutdatedException as exc: + sys.stderr.write("WARNING: {}\n".format(exc)) + raise + self.bb02 = bb02 + is_initialized = bb02.device_info()["initialized"] + if expect_initialized is not None: + if expect_initialized: + if not is_initialized: + raise HWWError( + "The BitBox02 must be initialized first.", + DEVICE_NOT_INITIALIZED, ) + elif is_initialized: + raise UnavailableActionError( + "The BitBox02 must be wiped before setup." + ) - return bb02 - raise Exception( - "Could not find the hid device info for path {}".format(self.device_path) - ) + return bb02 def close(self) -> None: self.transport.close() @@ -883,9 +913,13 @@ def setup_device( if label: bb02.set_device_name(label) - if not bb02.set_password(): - return False - return bb02.create_backup() + if self.device_path != SIMULATOR_PATH: + if not bb02.set_password(): + return False + return bb02.create_backup() + else: + bb02.restore_from_mnemonic() + return True @bitbox02_exception def wipe_device(self) -> bool: diff --git a/test/README.md b/test/README.md index c064d8786..c3efb9262 100644 --- a/test/README.md +++ b/test/README.md @@ -20,16 +20,19 @@ It also tests usage with `bitcoind`. - `test_jade.py` tests the command line interface and Blockstream Jade implementation. It uses the [Espressif fork of the Qemu emulator](https://github.com/espressif/qemu.git). It also tests usage with `bitcoind`. +- `test_bitbox02.py` tests the command line interface and the BitBox02 implementation. +It uses the [BitBox02 simulator](https://github.com/BitBoxSwiss/bitbox02-firmware/tree/master/test/simulator). +It also tests usage with `bitcoind`. -`setup_environment.sh` will build the Trezor emulator, the Coldcard simulator, the Keepkey emulator, the Digital Bitbox simulator, the Jade emulator, and `bitcoind`. -if run in the `test/` directory, these will be built in `work/test/trezor-firmware`, `work/test/firmware`, `work/test/keepkey-firmware`, `work/test/mcu`, and `work/test/bitcoin` respectively. +`setup_environment.sh` will build the Trezor emulator, the Coldcard simulator, the Keepkey emulator, the Digital Bitbox simulator, the Jade emulator, the BitBox02 simulator and `bitcoind`. +if run in the `test/` directory, these will be built in `work/test/trezor-firmware`, `work/test/firmware`, `work/test/keepkey-firmware`, `work/test/mcu`, `work/test/bitbox02-firmware` and `work/test/bitcoin` respectively. In order to build each simulator/emulator, you will need to use command line arguments. -These are `--trezor-1`, `--trezor-t`, `--coldcard`, `--keepkey`, `--bitbox01`, `--jade`, and `--bitcoind`. +These are `--trezor-1`, `--trezor-t`, `--coldcard`, `--keepkey`, `--bitbox01`, `--jade`, `--bitbox02` and `--bitcoind`. If an environment variable is not present or not set, then the simulator/emulator or bitcoind that it guards will not be built. -`run_tests.py` runs the tests. If run from the `test/` directory, it will be able to find the Trezor emulator, Coldcard simulator, Keepkey emulator, Digital Bitbox simulator, Jade emulator, and bitcoind. +`run_tests.py` runs the tests. If run from the `test/` directory, it will be able to find the Trezor emulator, Coldcard simulator, Keepkey emulator, Digital Bitbox simulator, Jade emulator, BitBox02 simulator and bitcoind. Otherwise the paths to those will need to be specified on the command line. -`test_trezor.py`, `test_coldcard.py`, `test_keepkey.py`, `test_jade.py`, and `test/test_digitalbitbox.py` can be disabled. +`test_trezor.py`, `test_coldcard.py`, `test_keepkey.py`, `test_jade.py`, `test_bitbox02.py` and `test/test_digitalbitbox.py` can be disabled. If you are building the Trezor emulator, the Coldcard simulator, the Keepkey emulator, the Jade emulator, the Digital Bitbox simulator, and `bitcoind` without `setup_environment.sh`, then you will need to make `work/` inside of `test/`. @@ -329,6 +332,38 @@ You also have to install its python dependencies pip install -r requirements.txt ``` +## BitBox02 Simulator + +### Dependencies + +In order to build the BitBox02 simulator, the following packages will need to be installed: + +``` +apt install docker.io +``` + +### Building + +Clone the repository: + +``` +git clone --recursive https://github.com/BitBoxSwiss/bitbox02-firmware.git +``` + +Pull the BitBox02 firmware Docker image: + +``` +cd bitbox02-firmware +make dockerpull +``` + +Build the simulator: + +``` +make dockerdev +make simulator +``` + ## Bitcoin Core diff --git a/test/run_tests.py b/test/run_tests.py index 9bfcd364e..cd502a6c0 100755 --- a/test/run_tests.py +++ b/test/run_tests.py @@ -16,6 +16,7 @@ from test_digitalbitbox import digitalbitbox_test_suite from test_keepkey import keepkey_test_suite from test_jade import jade_test_suite +from test_bitbox02 import bitbox02_test_suite from test_udevrules import TestUdevRulesInstaller parser = argparse.ArgumentParser(description='Setup the testing environment and run automated tests') @@ -51,6 +52,10 @@ dbb_group.add_argument('--no_bitbox01', dest='bitbox01', help='Do not run Digital Bitbox test with simulator', action='store_false') dbb_group.add_argument('--bitbox01', dest='bitbox01', help='Run Digital Bitbox test with simulator', action='store_true') +dbb_group = parser.add_mutually_exclusive_group() +dbb_group.add_argument('--no_bitbox02', dest='bitbox02', help='Do not run BitBox02 test with simulator', action='store_false') +dbb_group.add_argument('--bitbox02', dest='bitbox02', help='Run BitBox02 test with simulator', action='store_true') + parser.add_argument('--trezor-1-path', dest='trezor_1_path', help='Path to Trezor 1 emulator', default='work/trezor-firmware/legacy/firmware/trezor.elf') parser.add_argument('--trezor-t-path', dest='trezor_t_path', help='Path to Trezor T emulator', default='work/trezor-firmware/core/emu.sh') parser.add_argument('--coldcard-path', dest='coldcard_path', help='Path to Coldcard simulator', default='work/firmware/unix/simulator.py') @@ -58,6 +63,7 @@ parser.add_argument('--bitbox01-path', dest='bitbox01_path', help='Path to Digital Bitbox simulator', default='work/mcu/build/bin/simulator') parser.add_argument('--ledger-path', dest='ledger_path', help='Path to Ledger emulator', default='work/speculos/speculos.py') parser.add_argument('--jade-path', dest='jade_path', help='Path to Jade qemu emulator', default='work/jade/simulator') +parser.add_argument('--bitbox02-path', dest='bitbox02_path', help='Path to BitBox02 simulator', default='work/bitbox02-firmware/build-build/bin/simulator') parser.add_argument('--all', help='Run tests on all existing simulators', default=False, action='store_true') parser.add_argument('--bitcoind', help='Path to bitcoind', default='work/bitcoin/build/src/bitcoind') @@ -65,7 +71,7 @@ parser.add_argument("--device-only", help="Only run device tests", action="store_true") -parser.set_defaults(trezor_1=None, trezor_t=None, coldcard=None, keepkey=None, bitbox01=None, ledger=None, ledger_legacy=None, jade=None) +parser.set_defaults(trezor_1=None, trezor_t=None, coldcard=None, keepkey=None, bitbox01=None, ledger=None, ledger_legacy=None, jade=None, bitbox02=None) args = parser.parse_args() @@ -92,6 +98,7 @@ args.ledger = True if args.ledger is None else args.ledger args.ledger_legacy = True if args.ledger_legacy is None else args.ledger_legacy args.jade = True if args.jade is None else args.jade + args.bitbox02 = True if args.bitbox02 is None else args.bitbox02 else: # Default all false unless overridden args.trezor_1 = False if args.trezor_1 is None else args.trezor_1 @@ -102,8 +109,9 @@ args.ledger = False if args.ledger is None else args.ledger args.ledger_legacy = False if args.ledger_legacy is None else args.ledger_legacy args.jade = False if args.jade is None else args.jade + args.bitbox02 = False if args.bitbox02 is None else args.bitbox02 -if args.trezor_1 or args.trezor_t or args.coldcard or args.ledger or args.ledger_legacy or args.keepkey or args.bitbox01 or args.jade: +if args.trezor_1 or args.trezor_t or args.coldcard or args.ledger or args.ledger_legacy or args.keepkey or args.bitbox01 or args.jade or args.bitbox02: # Start bitcoind bitcoind = Bitcoind.create(args.bitcoind) @@ -123,5 +131,7 @@ success &= ledger_test_suite(args.ledger_path, bitcoind, args.interface, True) if success and args.jade: success &= jade_test_suite(args.jade_path, bitcoind, args.interface) + if success and args.bitbox02: + success &= bitbox02_test_suite(args.bitbox02_path, bitcoind, args.interface) sys.exit(not success) diff --git a/test/setup_environment.sh b/test/setup_environment.sh index bbb69b68d..d4f1463d7 100755 --- a/test/setup_environment.sh +++ b/test/setup_environment.sh @@ -34,6 +34,10 @@ while [[ $# -gt 0 ]]; do build_jade=1 shift ;; + --bitbox02) + build_bitbox02=1 + shift + ;; --bitcoind) build_bitcoind=1 shift @@ -46,6 +50,7 @@ while [[ $# -gt 0 ]]; do build_ledger=1 build_keepkey=1 build_jade=1 + build_bitbox02=1 build_bitcoind=1 shift ;; @@ -416,6 +421,36 @@ if [[ -n ${build_jade} ]]; then cd .. fi +if [[ -n ${build_bitbox02} ]]; then + # Clone digital bitbox02 firmware if it doesn't exist, or update it if it does + if [ ! -d "bitbox02-firmware" ]; then + git clone --recursive https://github.com/BitBoxSwiss/bitbox02-firmware.git + cd bitbox02-firmware + else + cd bitbox02-firmware + git fetch + + # Determine if we need to pull. From https://stackoverflow.com/a/3278427 + UPSTREAM=${1:-'@{u}'} + LOCAL=$(git rev-parse @) + REMOTE=$(git rev-parse "$UPSTREAM") + BASE=$(git merge-base @ "$UPSTREAM") + + if [ $LOCAL = $REMOTE ]; then + echo "Up-to-date" + elif [ $LOCAL = $BASE ]; then + git pull + fi + fi + + # Build the simulator. This is cached, but it is also fast + CONTAINER_VERSION=$(cat .containerversion) + docker pull shiftcrypto/firmware_v2:$CONTAINER_VERSION + # The safe.directory config is so that git commands work. even though the repo folder mounted in + # Docker is owned by root, which can be different from the owner on the host. + docker run -i --rm --volume $(pwd):/bb02 shiftcrypto/firmware_v2:$CONTAINER_VERSION bash -c "git config --global --add safe.directory /bb02 && cd /bb02 && make -j simulator" +fi + if [[ -n ${build_bitcoind} ]]; then # Clone bitcoind if it doesn't exist, or update it if it does bitcoind_setup_needed=false diff --git a/test/test_bitbox02.py b/test/test_bitbox02.py new file mode 100644 index 000000000..fb9cf8490 --- /dev/null +++ b/test/test_bitbox02.py @@ -0,0 +1,109 @@ +#! /usr/bin/env python3 + +import atexit +import os +import subprocess +import time +import unittest +import sys +import argparse + +from hwilib.devices.bitbox02 import Bitbox02Client + +from test_device import ( + DeviceEmulator, + DeviceTestCase, + TestDeviceConnect, + TestDisplayAddress, + TestGetKeypool, + TestGetDescriptors, + TestSignTx, +) + +# Class for emulator control +class BitBox02Emulator(DeviceEmulator): + def __init__(self, simulator): + self.simulator = simulator + self.path = "127.0.0.1:15423" + self.type = "bitbox02" + self.fingerprint = "4c00739d" + self.master_xpub = "tpubDDoFYQF4zAhrW8LRtCxePR8bJsAh5SXU6PwPNi2oRfeh67qhmxZawJ4m3V76P8AYSEueKmwvNyiSPAGYtynGfzJNvTHyzj2FJTbp729jmYM" + self.password = None + self.supports_ms_display = False + self.supports_xpub_ms_display = False + self.supports_unsorted_ms = False + self.supports_taproot = False + self.strict_bip48 = False + self.include_xpubs = True + self.supports_device_multiple_multisig = True + self.supports_legacy = False + + def start(self): + super().start() + self.log = open('bitbox02-simulator.stderr', 'a') + # Start the Bitbox02 simulator + self.simulator_proc = subprocess.Popen( + [ + './' + os.path.basename(self.simulator) + ], + cwd=os.path.dirname(self.simulator), + stderr=self.log + ) + time.sleep(1) + + self.setup_client = Bitbox02Client(self.path) + self.setup_bb02 = self.setup_client.restore_device() + self.setup_client.close() + + atexit.register(self.stop) + + def stop(self): + super().stop() + self.simulator_proc.terminate() + self.simulator_proc.wait() + self.log.close() + atexit.unregister(self.stop) + +class TestBitbox02GetXpub(DeviceTestCase): + def test_getxpub(self): + self.dev_args.remove('--chain') + self.dev_args.remove('test') + result = self.do_command(self.dev_args + ['--expert', 'getxpub', 'm/84h/0h/0h/3']) + self.assertEqual(result['xpub'], 'xpub6F8W4c3nJf6vWyEQPW9rofRgKf9LUWrbLc6fh2GUgofxXzuMwNEXw9dUuAeHuNiu2MebTmLX1CY2wxN1pgUuQtsWa9x8QBk7J51nD86vann') + self.assertFalse(result['testnet']) + self.assertFalse(result['private']) + self.assertEqual(result['depth'], 4) + self.assertEqual(result['parent_fingerprint'], 'd934efde') + self.assertEqual(result['child_num'], 3) + self.assertEqual(result['chaincode'], '03b0d37df586659fb87145e1d28506e4e2d42777586568d61ecdf6c9e041a0a1') + self.assertEqual(result['pubkey'], '03290b94a942a317c3846244f1eb6d67214326c8cfc6d940c823ace57ab818dbbd') + +def bitbox02_test_suite(simulator, bitcoind, interface): + dev_emulator = BitBox02Emulator(simulator) + + signtx_cases = [ + (["segwit"], [], False, False) + ] + + # Generic Device tests + suite = unittest.TestSuite() + suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, bitcoind, emulator=dev_emulator, interface=interface, detect_type=dev_emulator.type)) + suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, bitcoind, emulator=dev_emulator, interface=interface)) + suite.addTest(DeviceTestCase.parameterize(TestGetDescriptors, bitcoind, emulator=dev_emulator, interface=interface)) + suite.addTest(DeviceTestCase.parameterize(TestSignTx, bitcoind, emulator=dev_emulator, interface=interface, signtx_cases=signtx_cases)) + suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, bitcoind, emulator=dev_emulator, interface=interface)) + # TestSignMessage is removed, since its only testcase is for legacy p2pkh, which is not supported by BitBox02 + # suite.addTest(DeviceTestCase.parameterize(TestSignMessage, bitcoind, emulator=dev_emulator, interface=interface)) + suite.addTest(DeviceTestCase.parameterize(TestBitbox02GetXpub, bitcoind, emulator=dev_emulator, interface=interface)) + + result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite) + return result.wasSuccessful() + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Test BitBox02 implementation') + parser.add_argument('simulator', help='Path to simulator binary') + parser.add_argument('bitcoind', help='Path to bitcoind binary') + parser.add_argument('--interface', help='Which interface to send commands over', choices=['library', 'cli', 'bindist'], default='library') + args = parser.parse_args() + + sys.exit(not bitbox02_test_suite(args.simulator, args.bitcoind, args.interface)) diff --git a/test/test_coldcard.py b/test/test_coldcard.py index 56ac8ea5a..9eb90f379 100755 --- a/test/test_coldcard.py +++ b/test/test_coldcard.py @@ -44,6 +44,7 @@ def __init__(self, simulator): self.strict_bip48 = False self.include_xpubs = False self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start() diff --git a/test/test_device.py b/test/test_device.py index eb7fe501c..887a6ea65 100644 --- a/test/test_device.py +++ b/test/test_device.py @@ -35,6 +35,7 @@ def __init__(self): self.strict_bip48 = None self.include_xpubs = None self.supports_device_multiple_multisig = None + self.supports_legacy = None def start(self): assert self.type is not None @@ -49,6 +50,7 @@ def start(self): assert self.strict_bip48 is not None assert self.include_xpubs is not None assert self.supports_device_multiple_multisig is not None + assert self.supports_legacy is not None def stop(self): pass @@ -584,21 +586,21 @@ def test_signtx(self): # Make a huge transaction which might cause some problems with different interfaces def test_big_tx(self): # make a huge transaction - keypool_desc = self.do_command(self.dev_args + ["getkeypool", "--account", "10", "--addr-type", "legacy", "0", "100"]) + keypool_desc = self.do_command(self.dev_args + ["getkeypool", "--account", "10", "--addr-type", "sh_wit", "0", "100"]) import_result = self.wrpc.importdescriptors(keypool_desc) self.assertTrue(import_result[0]['success']) outputs = [] num_inputs = 60 for i in range(0, num_inputs): - outputs.append({self.wrpc.getnewaddress('', 'legacy'): 0.001}) - outputs.append({self.wrpc.getnewaddress("", "legacy"): 10}) + outputs.append({self.wrpc.getnewaddress('', "p2sh-segwit"): 0.001}) + outputs.append({self.wrpc.getnewaddress("", "p2sh-segwit"): 10}) psbt = self.wpk_rpc.walletcreatefundedpsbt([], outputs, 0, {}, True)['psbt'] psbt = self.wpk_rpc.walletprocesspsbt(psbt)['psbt'] tx = self.wpk_rpc.finalizepsbt(psbt)['hex'] self.wpk_rpc.sendrawtransaction(tx) self.wpk_rpc.generatetoaddress(10, self.wpk_rpc.getnewaddress()) inputs = self.wrpc.listunspent() - psbt = self.wrpc.walletcreatefundedpsbt(inputs, [{self.wpk_rpc.getnewaddress('', 'legacy'): 0.001 * num_inputs}])['psbt'] + psbt = self.wrpc.walletcreatefundedpsbt(inputs, [{self.wpk_rpc.getnewaddress('', "p2sh-segwit"): 0.001 * num_inputs}])['psbt'] # For cli, this should throw an exception try: result = self.do_command(self.dev_args + ['signtx', psbt]) @@ -614,9 +616,14 @@ def test_big_tx(self): class TestDisplayAddress(DeviceTestCase): def test_display_address_path(self): result = self.do_command(self.dev_args + ['displayaddress', "--addr-type", "legacy", '--path', 'm/44h/1h/0h/0/0']) - self.assertNotIn('error', result) - self.assertNotIn('code', result) - self.assertIn('address', result) + if self.emulator.supports_legacy: + self.assertNotIn('error', result) + self.assertNotIn('code', result) + self.assertIn('address', result) + else: + self.assertIn('error', result) + self.assertIn('code', result) + self.assertEqual(result['code'], -9) result = self.do_command(self.dev_args + ['displayaddress', "--addr-type", "sh_wit", '--path', 'm/49h/1h/0h/0/0']) self.assertNotIn('error', result) @@ -657,9 +664,14 @@ def test_display_address_descriptor(self): # Legacy address result = self.do_command(self.dev_args + ['displayaddress', '--desc', 'pkh([' + self.emulator.fingerprint + '/44h/1h/0h]' + legacy_account_xpub + '/0/0)']) - self.assertNotIn('error', result) - self.assertNotIn('code', result) - self.assertIn('address', result) + if self.emulator.supports_legacy: + self.assertNotIn('error', result) + self.assertNotIn('code', result) + self.assertIn('address', result) + else: + self.assertIn('error', result) + self.assertIn('code', result) + self.assertEqual(result['code'], -9) # Should check xpub result = self.do_command(self.dev_args + ['displayaddress', '--desc', 'wpkh([' + self.emulator.fingerprint + '/84h/1h/0h]' + "not_and_xpub" + '/0/0)']) diff --git a/test/test_digitalbitbox.py b/test/test_digitalbitbox.py index 297e01181..d43a9af65 100755 --- a/test/test_digitalbitbox.py +++ b/test/test_digitalbitbox.py @@ -42,6 +42,7 @@ def __init__(self, simulator): self.strict_bip48 = False self.include_xpubs = False self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start() diff --git a/test/test_jade.py b/test/test_jade.py index 1d57c4fc4..710bf914f 100755 --- a/test/test_jade.py +++ b/test/test_jade.py @@ -52,6 +52,7 @@ def __init__(self, jade_qemu_emulator_path): self.strict_bip48 = False self.include_xpubs = False self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start() diff --git a/test/test_keepkey.py b/test/test_keepkey.py index 45ccba21f..f926d9807 100755 --- a/test/test_keepkey.py +++ b/test/test_keepkey.py @@ -64,6 +64,7 @@ def __init__(self, path): self.strict_bip48 = False self.include_xpubs = False self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start() diff --git a/test/test_ledger.py b/test/test_ledger.py index a9a5030af..26876c0df 100755 --- a/test/test_ledger.py +++ b/test/test_ledger.py @@ -46,6 +46,7 @@ def __init__(self, path, legacy=False): self.strict_bip48 = True self.include_xpubs = True self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start() diff --git a/test/test_trezor.py b/test/test_trezor.py index 0b70e0ee4..f7424ce90 100755 --- a/test/test_trezor.py +++ b/test/test_trezor.py @@ -63,6 +63,7 @@ def __init__(self, path, model): self.strict_bip48 = True self.include_xpubs = False self.supports_device_multiple_multisig = True + self.supports_legacy = True def start(self): super().start()