"""Demo client: python demo/client.py Connects to ws://127.0.0.1:8765, initiates the handshake, prompts for the out-of-band digest comparison, then relays stdin lines encrypted. Empty line quits. """ import asyncio from common import key_store, save_store, setup_logging from websockets import connect from websockets.exceptions import ConnectionClosed from quantumpipe import ProtocolError, SecSocket, Verification, sas log = setup_logging("client") async def confirm_digest(v: Verification) -> bool | None: print(f"\n*** compare these emojis with the server:\n{sas.format(v.sas)}") answer = await asyncio.to_thread(input, "*** match? [y]es / [n]o / [s]kip: ") return {"y": True, "n": False}.get(answer.strip().lower()[:1] or "s") async def main() -> None: store = key_store("client") async with connect("ws://127.0.0.1:8765") as ws: sock = SecSocket(ws, store, "peer", handlers={Verification: confirm_digest}) try: await sock.connect() except (ProtocolError, ConnectionClosed) as e: log.error("handshake failed: %s", e) return finally: save_store("client", store) # rotation, flag, burn, delete log.info( "handshake done (%s, verified=%s); type lines, empty line quits", sock.session.state, sock.session.verified, ) while line := await asyncio.to_thread(input, "> "): await sock.send(line) print("server:", await sock.receive()) if __name__ == "__main__": try: asyncio.run(main()) except (KeyboardInterrupt, EOFError): pass