示例#1
0
 def remove_sdcard(self) -> None:
     # pylint: disable=no-member
     request = hww.Request()
     request.insert_remove_sdcard.CopyFrom(
         bitbox02_system.InsertRemoveSDCardRequest(
             action=bitbox02_system.InsertRemoveSDCardRequest.REMOVE_CARD))
     self._msg_query(request, expected_response="success")
示例#2
0
 def _bbb_query(self,
                request: bitboxbase.BitBoxBaseRequest,
                _expected_response: Optional[str] = None) -> hww.Response:
     # pylint: disable=no-member
     req = hww.Request()
     req.bitboxbase.CopyFrom(request)
     return self._msg_query(req)
示例#3
0
 def disable_mnemonic_passphrase(self) -> None:
     """
     Disable the bip39 passphrase.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.set_mnemonic_passphrase_enabled.enabled = False
     self._msg_query(request, expected_response="success")
示例#4
0
 def root_fingerprint(self) -> bytes:
     """
     Get the root fingerprint from the bitbox02
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.fingerprint.CopyFrom(common.RootFingerprintRequest())
     response = self._msg_query(request, expected_response="fingerprint")
     return response.fingerprint.fingerprint
示例#5
0
 def list_backups(self) -> Generator[Backup, None, None]:
     """
     Returns a pair of id and timestamp's strings that identify the backups.
     """
     # pylint: disable=no-member
     self.insert_sdcard()
     request = hww.Request()
     request.list_backups.CopyFrom(backup.ListBackupsRequest())
     response = self._msg_query(request, expected_response="list_backups")
     for info in response.list_backups.info:
         utcdate = datetime.utcfromtimestamp(info.timestamp)
         yield (info.id, info.name, utcdate)
示例#6
0
 def device_info(self) -> Dict[str, Any]:
     # pylint: disable=no-member
     request = hww.Request()
     device_info_request = bitbox02_system.DeviceInfoRequest()
     request.device_info.CopyFrom(device_info_request)
     response = self._msg_query(request, expected_response="device_info")
     return {
         "name": response.device_info.name,
         "version": response.device_info.version,
         "initialized": response.device_info.initialized,
         "mnemonic_passphrase_enabled": response.device_info.mnemonic_passphrase_enabled,
         "monotonic_increments_remaining": response.device_info.monotonic_increments_remaining,
     }
示例#7
0
 def show_mnemonic(self) -> bool:
     """
     Returns True if mnemonic was successfully shown and confirmed.
     Returns False otherwise.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.show_mnemonic.CopyFrom(mnemonic.ShowMnemonicRequest())
     try:
         self._msg_query(request, expected_response="success")
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#8
0
 def set_password(self) -> bool:
     """
     Returns True if the user entered the password correctly (passwords match).
     Returns False otherwise.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.set_password.entropy = os.urandom(32)
     try:
         self._msg_query(request, expected_response="success")
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#9
0
 def restore_backup(self, backup_id: str) -> bool:
     """
     Sends a restore API call to the BitBox.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.restore_backup.id = backup_id
     request.restore_backup.timestamp = int(time.time())
     request.restore_backup.timezone_offset = time.localtime().tm_gmtoff
     try:
         self._msg_query(request, expected_response="success")
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#10
0
 def create_backup(self) -> bool:
     """
     Returns True if the backup was created successfully.
     Returns False otherwise.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.create_backup.timestamp = int(time.time())
     request.create_backup.timezone_offset = time.localtime().tm_gmtoff
     try:
         self._msg_query(request, expected_response="success")
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#11
0
 def _eth_msg_query(
         self,
         eth_request: eth.ETHRequest,
         expected_response: Optional[str] = None) -> eth.ETHResponse:
     """
     Same as _msg_query, but one nesting deeper for ethereum messages.
     """
     # pylint: disable=no-member
     request = hww.Request()
     request.eth.CopyFrom(eth_request)
     eth_response = self._msg_query(request, expected_response="eth").eth
     if (expected_response is not None
             and eth_response.WhichOneof("response") != expected_response):
         raise Exception("Unexpected response: {}, expected: {}".format(
             eth_response.WhichOneof("response"), expected_response))
     return eth_response
示例#12
0
 def check_backup(self, silent: bool = False) -> Optional[str]:
     """
     Sends a check backup API call to the BitBox.
     Returns the backup ID if the backup was found and can be restored.
     Otherwise, returns None. If silent is True, the result won't be shown on the device screen.
     """
     # pylint: disable=no-member
     self.insert_sdcard()
     request = hww.Request()
     request.check_backup.CopyFrom(backup.CheckBackupRequest(silent=silent))
     try:
         response = self._msg_query(request, expected_response="check_backup")
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return None
         raise
     return response.check_backup.id
示例#13
0
 def restore_from_mnemonic(self) -> bool:
     """
     Restore from mnemonic. Returns True on success, False on failure or user abort.
     """
     request = hww.Request()
     # pylint: disable=no-member
     request.restore_from_mnemonic.CopyFrom(
         mnemonic.RestoreFromMnemonicRequest(
             timestamp=int(time.time()),
             timezone_offset=time.localtime().tm_gmtoff))
     try:
         self._msg_query(request)
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#14
0
 def reset(self) -> bool:
     """
     Factory reset the device. Returns True on success.
     """
     request = hww.Request()
     # pylint: disable=no-member
     request.reset.CopyFrom(bitbox02_system.ResetRequest())
     try:
         self._msg_query(request)
     except OSError:
         # In case of reboot we can't read the response.
         return True
     except Bitbox02Exception as err:
         if err.code == ERR_GENERIC:
             return False
         raise
     return True
示例#15
0
 def btc_pub(
     self,
     keypath: List[int],
     coin: btc.BTCCoin = btc.BTC,
     output_type: btc.BTCPubRequest.OutputType = btc.BTCPubRequest.XPUB,
     script_type: btc.BTCScriptType = btc.SCRIPT_UNKNOWN,
     display: bool = True,
 ) -> str:
     """
     keypath is a list of child derivation numbers.
     e.g. m/44'/0'/1'/5 corresponds to [44+HARDENED, 0+HARDENED, 1+HARDENED, 5].
     """
     # pylint: disable=no-member,too-many-arguments
     request = hww.Request()
     request.btc_pub.CopyFrom(
         btc.BTCPubRequest(
             coin=coin,
             keypath=keypath,
             output_type=output_type,
             script_type=script_type,
             display=display,
         ))
     return self._msg_query(request).pub.pub
示例#16
0
    def btc_sign(
        self,
        coin: btc.BTCCoin,
        script_type: btc.BTCScriptType,
        bip44_account: int,
        inputs: List[BTCInputType],
        outputs: List[BTCOutputType],
        version: int = 1,
        locktime: int = 0,
    ) -> List[Tuple[int, bytes]]:
        """
        coin: the first element of all provided keypaths must match the coin:
        - BTC: 0 + HARDENED
        - Testnets: 1 + HARDENED
        - LTC: 2 + HARDENED
        script_type: type of all inputs and change outputs. The first element of all provided
        keypaths must match this type:
        - SCRIPT_P2PKH: 44 + HARDENED
        - SCRIPT_P2WPKH_P2SH: 49 + HARDENED
        - SCRIPT_P2WPKH: 84 + HARDENED
        bip44_account: Starting at (0 + HARDENED), must be the third element of all provided
        keypaths.
        inputs: transaction inputs.
        outputs: transaction outputs. Can be an external output
        (BTCOutputExternal) or an internal output for change (BTCOutputInternal).
        version, locktime: reserved for future use.
        Returns: list of (input index, signature) tuples.
        Raises Bitbox02Exception with ERR_USER_ABORT on user abort.
        """
        # pylint: disable=too-many-locals,no-member

        # Reserved for future use.
        assert version in (1, 2)

        sigs: List[Tuple[int, bytes]] = []

        # Init request
        request = hww.Request()
        request.btc_sign_init.CopyFrom(
            btc.BTCSignInitRequest(
                coin=coin,
                script_type=script_type,
                bip44_account=bip44_account,
                version=version,
                num_inputs=len(inputs),
                num_outputs=len(outputs),
                locktime=locktime,
            ))
        next_response = self._msg_query(
            request, expected_response="btc_sign_next").btc_sign_next
        while True:
            if next_response.type == btc.BTCSignNextResponse.INPUT:
                input_index = next_response.index
                tx_input = inputs[input_index]

                request = hww.Request()
                request.btc_sign_input.CopyFrom(
                    btc.BTCSignInputRequest(
                        prevOutHash=tx_input["prev_out_hash"],
                        prevOutIndex=tx_input["prev_out_index"],
                        prevOutValue=tx_input["prev_out_value"],
                        sequence=tx_input["sequence"],
                        keypath=tx_input["keypath"],
                    ))
                next_response = self._msg_query(
                    request, expected_response="btc_sign_next").btc_sign_next
                if next_response.has_signature:
                    sigs.append((input_index, next_response.signature))
            elif next_response.type == btc.BTCSignNextResponse.OUTPUT:
                output_index = next_response.index
                tx_output = outputs[output_index]

                request = hww.Request()
                if isinstance(tx_output, BTCOutputInternal):
                    request.btc_sign_output.CopyFrom(
                        btc.BTCSignOutputRequest(ours=True,
                                                 value=tx_output.value,
                                                 keypath=tx_output.keypath))
                elif isinstance(tx_output, BTCOutputExternal):
                    request.btc_sign_output.CopyFrom(
                        btc.BTCSignOutputRequest(
                            ours=False,
                            type=tx_output.type,
                            hash=tx_output.hash,
                            value=tx_output.value,
                        ))
                next_response = self._msg_query(
                    request, expected_response="btc_sign_next").btc_sign_next
            elif next_response.type == btc.BTCSignNextResponse.DONE:
                break
            else:
                raise Exception("unexpected response")
        return sigs
示例#17
0
 def random_number(self) -> bytes:
     # pylint: disable=no-member
     request = hww.Request()
     request.random_number.CopyFrom(random_number.RandomNumberRequest())
     response = self._msg_query(request, expected_response="random_number")
     return response.random_number.number
示例#18
0
 def set_device_name(self, device_name: str) -> None:
     # pylint: disable=no-member
     request = hww.Request()
     request.device_name.name = device_name
     self._msg_query(request, expected_response="success")
示例#19
0
 def check_sdcard(self) -> bool:
     # pylint: disable=no-member
     request = hww.Request()
     request.check_sdcard.CopyFrom(bitbox02_system.CheckSDCardRequest())
     response = self._msg_query(request, expected_response="check_sdcard")
     return response.check_sdcard.inserted