def _on_receive(self, item: CosignerItem, message: str) -> None:
        logger.debug("signal arrived for '%s'", item.keyhash_hex)
        window = item.window
        account = window._wallet.get_account(item.account_id)

        for keystore in account.get_keystores():
            if keystore.get_master_public_key() == item.xpub:
                break
        else:
            window.show_error(
                _('Message for non-existent non-watching cosigner'))
            return

        if isinstance(keystore, Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them incompatible with the current design of cosigner pool.'
                  ))
            self._listener.clear(item.keyhash_hex)
            return

        password = window.password_dialog(
            _('An encrypted transaction was retrieved from cosigning pool.') +
            '\n' + _('Please enter your password to decrypt it.'))
        if not password:
            return

        self._listener.clear(item.keyhash_hex)

        xprv = keystore.get_master_private_key(password)
        if not xprv:
            return
        privkey = bip32_key_from_string(xprv)
        try:
            message = privkey.decrypt_message(message).decode()
        except Exception as e:
            logger.exception("")
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        txdict = json.loads(message)
        tx = Transaction.from_dict(txdict)
        window.show_transaction(account, tx, prompt_if_unsaved=True)
 def test_dict_io(self, json_text: str) -> None:
     tx = Transaction.from_dict(json.loads(json_text))
     assert json.dumps(tx.to_dict()) == json_text