anchor.diff:        client = { pkgs, ... }: {
           environment.systemPackages = [
             (pkgs.writers.writePython3Bin "do_test"
  -            { libraries = [ pkgs.python3Packages.matrix-client ]; } ''
  +            { libraries = [ pkgs.python3Packages.matrix-nio ]; } ''
               import socket
  -            from matrix_client.client import MatrixClient
  +            from nio import AsyncClient, RoomMessageText
               from time import sleep
  -
  -            matrix = MatrixClient("${homeserverUrl}")
  -            matrix.register_with_password(username="alice", password="foobar")
  -
  -            irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  -            irc.connect(("ircd", 6667))
  -            irc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
  -            irc.send(b"USER bob bob bob :bob\n")
  -            irc.send(b"NICK bob\n")
  -
  -            m_room = matrix.join_room("#irc_#test:homeserver")
  -            irc.send(b"JOIN #test\n")
  -
  -            # plenty of time for the joins to happen
  -            sleep(10)
  -
  -            m_room.send_text("hi from matrix")
  -            irc.send(b"PRIVMSG #test :hi from irc \r\n")
  -
  -            print("Waiting for irc message...")
  -            while True:
  -                buf = irc.recv(10000)
  -                if b"hi from matrix" in buf:
  -                    break
  -
  -            print("Waiting for matrix message...")
  +            import asyncio
   
   
  -            def callback(room, e):
  -                if "hi from irc" in e['content']['body']:
  -                    exit(0)
  +            async def run():
  +                matrix = AsyncClient("${homeserverUrl}")
  +                await matrix.register("alice", "foobar")
   
  +                irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  +                irc.connect(("ircd", 6667))
  +                irc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
  +                irc.send(b"USER bob bob bob :bob\n")
  +                irc.send(b"NICK bob\n")
   
  -            m_room.add_listener(callback, "m.room.message")
  -            matrix.listen_forever()
  +                room_id = (await matrix.join("#irc_#test:homeserver")).room_id
  +                irc.send(b"JOIN #test\n")
  +
  +                # plenty of time for the joins to happen
  +                sleep(10)
  +
  +                # Exchange messages
  +                await matrix.room_send(
  +                    room_id=room_id,
  +                    message_type="m.room.message",
  +                    content={
  +                        "msgtype": "m.text",
  +                        "body": "hi from matrix"
  +                    }
  +                )
  +                irc.send(b"PRIVMSG #test :hi from irc \r\n")
  +
  +                print("Waiting for irc message...")
  +                while True:
  +                    buf = irc.recv(10000)
  +                    if b"hi from matrix" in buf:
  +                        print("Got IRC message")
  +                        break
  +
  +                print("Waiting for matrix message...")
  +
  +                async def callback(room, e):
  +                    if "hi from irc" in e.body:
  +                        print("Got Matrix message")
  +                        await matrix.close()
  +                        exit(0)  # Actual exit point
  +
  +                matrix.add_event_callback(callback, RoomMessageText)
  +                await matrix.sync_forever()
  +                exit(1)  # Unreachable
  +
  +            asyncio.run(run())
             ''
             )
           ];
  
positive.code:           homeserver.wait_for_open_port(8448)
  
        with subtest("ensure messages can be exchanged"):
            client.succeed("do_test")
      '';
  
    })
  
negative.code:                 "bind_address" = "";
                  "port" = 8448;
                  "resources" = [
                    { "compress" = true; "names" = [ "client" ]; }
                    { "compress" = false; "names" = [ "federation" ]; }
                  ];
                  "tls" = false;
  