async def _state_changed(self, *args): change = args[0] if self.websocket is None: return None payloads: List[Dict] = await self.rpc_api._state_changed(*args) if change == "add_connection" or change == "close_connection": data = await self.get_connections({}) if data is not None: payload = create_payload_dict( "get_connections", data, self.service_name, "wallet_ui", ) payloads.append(payload) for payload in payloads: if "success" not in payload["data"]: payload["data"]["success"] = True try: await self.websocket.send_str(dict_to_json_str(payload)) except Exception: tb = traceback.format_exc() self.log.warning(f"Sending data failed. Exception {tb}.")
async def async_run_daemon(root_path: Path) -> int: chia_init(root_path) config = load_config(root_path, "config.yaml") setproctitle("chia_daemon") initialize_logging("daemon", config["logging"], root_path) lockfile = singleton(daemon_launch_lock_path(root_path)) crt_path = root_path / config["daemon_ssl"]["private_crt"] key_path = root_path / config["daemon_ssl"]["private_key"] ca_crt_path = root_path / config["private_ssl_ca"]["crt"] ca_key_path = root_path / config["private_ssl_ca"]["key"] sys.stdout.flush() json_msg = dict_to_json_str({ "message": "cert_path", "success": True, "cert": f"{crt_path}", "key": f"{key_path}", "ca_crt": f"{ca_crt_path}", }) sys.stdout.write("\n" + json_msg + "\n") sys.stdout.flush() if lockfile is None: print("daemon: already launching") return 2 # TODO: clean this up, ensuring lockfile isn't removed until the listen port is open create_server_for_daemon(root_path) ws_server = WebSocketServer(root_path, ca_crt_path, ca_key_path, crt_path, key_path) await ws_server.start() assert ws_server.websocket_server is not None await ws_server.websocket_server.wait_closed() log.info("Daemon WebSocketServer closed") return 0
async def handle_message( self, websocket: WebSocketServerProtocol, message: WsRpcMessage) -> Tuple[Optional[str], List[Any]]: """ This function gets called when new message is received via websocket. """ command = message["command"] destination = message["destination"] if destination != "daemon": destination = message["destination"] if destination in self.connections: sockets = self.connections[destination] return dict_to_json_str(message), sockets return None, [] data = message["data"] commands_with_data = [ "start_service", "start_plotting", "stop_plotting", "stop_service", "is_running", "register_service", ] if len(data) == 0 and command in commands_with_data: response = { "success": False, "error": f'{command} requires "data"' } elif command == "ping": response = await ping() elif command == "start_service": response = await self.start_service(cast(Dict[str, Any], data)) elif command == "start_plotting": response = await self.start_plotting(cast(Dict[str, Any], data)) elif command == "stop_plotting": response = await self.stop_plotting(cast(Dict[str, Any], data)) elif command == "stop_service": response = await self.stop_service(cast(Dict[str, Any], data)) elif command == "is_running": response = await self.is_running(cast(Dict[str, Any], data)) elif command == "exit": response = await self.stop() elif command == "register_service": response = await self.register_service(websocket, cast(Dict[str, Any], data)) elif command == "get_status": response = self.get_status() else: self.log.error(f"UK>> {message}") response = { "success": False, "error": f"unknown_command {command}" } full_response = format_response(message, response) return full_response, [websocket]
def format_response(incoming_msg: WsRpcMessage, response_data: Dict[str, Any]) -> str: """ Formats the response into standard format. """ response = { "command": incoming_msg["command"], "ack": True, "data": response_data, "request_id": incoming_msg["request_id"], "destination": incoming_msg["origin"], "origin": incoming_msg["destination"], } json_str = dict_to_json_str(response) return json_str
async def coin_added(self, coin: Coin, header_hash: bytes32, removals: List[Coin], height: uint32): """Notification from wallet state manager that wallet has been received.""" self.log.info(f"CC wallet has been notified that {coin} was added") search_for_parent: bool = True inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash) lineage_proof = Program.to((1, [ coin.parent_coin_info, inner_puzzle.get_tree_hash(), coin.amount ])) await self.add_lineage(coin.name(), lineage_proof, True) for name, lineage_proofs in self.cc_info.lineage_proofs: if coin.parent_coin_info == name: search_for_parent = False break if search_for_parent: data: Dict[str, Any] = { "data": { "action_data": { "api_name": "request_puzzle_solution", "height": height, "coin_name": coin.parent_coin_info, "received_coin": coin.name(), } } } data_str = dict_to_json_str(data) await self.wallet_state_manager.create_action( name="request_puzzle_solution", wallet_id=self.id(), wallet_type=self.type(), callback="puzzle_solution_received", done=False, data=data_str, in_transaction=True, )
async def _get(self, request: WsRpcMessage) -> WsRpcMessage: request_id = request["request_id"] self._request_dict[request_id] = asyncio.Event() string = dict_to_json_str(request) asyncio.create_task(self.websocket.send(string)) async def timeout(): await asyncio.sleep(30) if request_id in self._request_dict: print("Error, timeout.") self._request_dict[request_id].set() asyncio.create_task(timeout()) await self._request_dict[request_id].wait() if request_id in self.response_dict: response = self.response_dict[request_id] self.response_dict.pop(request_id) else: response = None self._request_dict.pop(request_id) return response
async def async_run_daemon(root_path: Path, wait_for_unlock: bool = False) -> int: # When wait_for_unlock is true, we want to skip the check_keys() call in chia_init # since it might be necessary to wait for the GUI to unlock the keyring first. chia_init(root_path, should_check_keys=(not wait_for_unlock)) config = load_config(root_path, "config.yaml") setproctitle("chia_daemon") initialize_logging("daemon", config["logging"], root_path) lockfile = singleton(daemon_launch_lock_path(root_path)) crt_path = root_path / config["daemon_ssl"]["private_crt"] key_path = root_path / config["daemon_ssl"]["private_key"] ca_crt_path = root_path / config["private_ssl_ca"]["crt"] ca_key_path = root_path / config["private_ssl_ca"]["key"] sys.stdout.flush() json_msg = dict_to_json_str( { "message": "cert_path", "success": True, "cert": f"{crt_path}", "key": f"{key_path}", "ca_crt": f"{ca_crt_path}", } ) sys.stdout.write("\n" + json_msg + "\n") sys.stdout.flush() if lockfile is None: print("daemon: already launching") return 2 # TODO: clean this up, ensuring lockfile isn't removed until the listen port is open create_server_for_daemon(root_path) ws_server = WebSocketServer( root_path, ca_crt_path, ca_key_path, crt_path, key_path, run_check_keys_on_unlock=wait_for_unlock ) await ws_server.start() assert ws_server.websocket_server is not None await ws_server.websocket_server.wait_closed() log.info("Daemon WebSocketServer closed") # sys.stdout.close() return 0
def create_payload(command: str, data: Dict[str, Any], origin: str, destination: str) -> str: response = create_payload_dict(command, data, origin, destination) return dict_to_json_str(response)