From 963c39ee31b67106336fa28dd56c73d065349a3d Mon Sep 17 00:00:00 2001 From: dbth <1097224+believethehype@users.noreply.github.com> Date: Sun, 23 Feb 2025 22:26:31 +0100 Subject: [PATCH] add simple function to react to ping (kind 7007) React with kind 7000 and status "pong" --- nostr_dvm/dvm.py | 17 +++++++++++ nostr_dvm/utils/definitions.py | 1 + nostr_dvm/utils/output_utils.py | 2 ++ tests/mcp/dvm/mcp_test.py | 4 +-- tests/test_dvm_client.py | 50 +++++++++++++++++++++++++++------ 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/nostr_dvm/dvm.py b/nostr_dvm/dvm.py index 6771e1b..c2bef5c 100644 --- a/nostr_dvm/dvm.py +++ b/nostr_dvm/dvm.py @@ -76,10 +76,12 @@ class DVM: if dvm.KIND not in kinds: kinds.append(dvm.KIND) dvm_filter = (Filter().kinds(kinds).since(Timestamp.now())) + ping_filter= Filter().pubkey(pk).kind(EventDefinitions.KIND_NIP90_PING).since(Timestamp.now()) create_sql_table(self.dvm_config.DB) await admin_make_database_updates(adminconfig=self.admin_config, dvmconfig=self.dvm_config, client=self.client) await self.client.subscribe(dvm_filter, None) await self.client.subscribe(zap_filter, None) + await self.client.subscribe(ping_filter, None) if self.dvm_config.ENABLE_NUTZAP: nutzap_wallet = NutZapWallet() @@ -110,6 +112,8 @@ class DVM: await handle_zap(nostr_event) elif nostr_event.kind().as_u16() == EventDefinitions.KIND_NIP61_NUT_ZAP.as_u16(): await handle_nutzap(nostr_event) + elif nostr_event.kind().as_u16() == EventDefinitions.KIND_NIP90_PING.as_u16(): + await handle_ping(nostr_event) async def handle_msg(self, relay_url, msg): return @@ -320,6 +324,19 @@ class DVM: # else: # print("[" + self.dvm_config.NIP89.NAME + "] Task " + task + " not supported on this DVM, skipping..") + + async def handle_ping(event): + nip90_event, use_legacy_encryption = check_and_decrypt_tags(event, self.dvm_config) + # if event is encrypted, but we can't decrypt it (e.g. because its directed to someone else), return + if nip90_event is None: + return + + await send_job_status_reaction(nip90_event, "pong", client=self.client, + content="alive and kicking", + dvm_config=self.dvm_config) + print("Sent pong") + + async def handle_nutzap(nut_zap_event): if self.dvm_config.ENABLE_NUTZAP: nut_wallet = await nutzap_wallet.get_nut_wallet(self.client, self.keys) diff --git a/nostr_dvm/utils/definitions.py b/nostr_dvm/utils/definitions.py index 75a782c..80c899b 100644 --- a/nostr_dvm/utils/definitions.py +++ b/nostr_dvm/utils/definitions.py @@ -60,6 +60,7 @@ class EventDefinitions: KIND_NIP88_SUBSCRIBE_EVENT = Kind(7001) KIND_NIP88_STOP_SUBSCRIPTION_EVENT = Kind(7002) KIND_NIP88_PAYMENT_RECIPE = Kind(7003) + KIND_NIP90_PING = Kind(7007) KIND_NIP60_NUT_PROOF = Kind(7375) KIND_NIP60_NUT_HISTORY = Kind(7376) KIND_NIP61_NUT_ZAP = Kind(9321) diff --git a/nostr_dvm/utils/output_utils.py b/nostr_dvm/utils/output_utils.py index f4517f0..1eeb41d 100644 --- a/nostr_dvm/utils/output_utils.py +++ b/nostr_dvm/utils/output_utils.py @@ -296,6 +296,8 @@ def build_status_reaction(status, task, amount, content, dvm_config): elif status == "user-blocked-from-service": alt_description = "NIP90 DVM task " + task + " can't be performed. User has been blocked from Service. " reaction = alt_description + emoji.emojize(":thumbs_down:") + elif status == "pong": + reaction = "Pong!" else: reaction = emoji.emojize(":thumbs_down:") diff --git a/tests/mcp/dvm/mcp_test.py b/tests/mcp/dvm/mcp_test.py index 6533364..15d32ad 100644 --- a/tests/mcp/dvm/mcp_test.py +++ b/tests/mcp/dvm/mcp_test.py @@ -95,9 +95,9 @@ def playground(announce=False): if __name__ == '__main__': - env_path = Path('../../.env') + env_path = Path('.env') if not env_path.is_file(): - with open('../../.env', 'w') as f: + with open('.env', 'w') as f: print("Writing new .env file") f.write('') if env_path.is_file(): diff --git a/tests/test_dvm_client.py b/tests/test_dvm_client.py index cb35e3c..c1621ac 100644 --- a/tests/test_dvm_client.py +++ b/tests/test_dvm_client.py @@ -377,6 +377,31 @@ async def nostr_client_test_discovery_gallery(user, ptag): return event.as_json() +async def dvm_ping(ptag): + keys = Keys.parse(check_and_set_private_key("test_client5")) + + relay_list = ["wss://relay.damus.io", "wss://dvms.f7z.io", "wss://nostr.oxtr.dev", + ] + + relaysTag = Tag.parse(relay_list) + alttag = Tag.parse(["alt", "This is a NIP90 DVM Ping"]) + pTag = Tag.parse(["p", ptag]) + + tags = [relaysTag, alttag, pTag] + + event = EventBuilder(EventDefinitions.KIND_NIP90_PING, "ping").tags( + tags).sign_with_keys(keys) + + client = Client(NostrSigner.keys(keys)) + for relay in relay_list: + await client.add_relay(relay) + await client.connect() + config = DVMConfig + await send_event(event, client=client, dvm_config=config) + + return event.as_json() + + async def nostr_client_test_image_private(prompt, cashutoken): keys = Keys.parse(check_and_set_private_key("test_client")) receiver_keys = Keys.parse(check_and_set_private_key("replicate_sdxl")) @@ -421,6 +446,8 @@ async def nostr_client(): client = Client(NostrSigner.keys(keys)) dvmconfig = DVMConfig() + for relay in dvmconfig.SYNC_DB_RELAY_LIST: + await client.add_relay(relay) for relay in dvmconfig.RELAY_LIST: await client.add_relay(relay) await client.connect() @@ -431,13 +458,16 @@ async def nostr_client(): kinds = [EventDefinitions.KIND_NIP90_GENERIC] #SUPPORTED_KINDS = [Kind(6100), Kind(7000)] - for kind in range(6000, 7001): + for kind in range(6000, 7008): if kind not in kinds: kinds.append(Kind(kind)) - dvm_filter = (Filter().kinds(kinds).since(Timestamp.now()).pubkey(pk)) - await client.subscribe(dm_zap_filter, None) + dvm_filter = Filter().pubkey(pk).kinds(kinds).since(Timestamp.now()) + #await client.subscribe(dm_zap_filter, None) await client.subscribe(dvm_filter, None) + await dvm_ping("f0abaefb4ca4a30411d6e28fa1219330426a73f486dee090a5198103c45d6817") + + # await nostr_client_test_translation("This is the result of the DVM in spanish", "text", "es", 20, 20) # await nostr_client_test_translation("note1p8cx2dz5ss5gnk7c59zjydcncx6a754c0hsyakjvnw8xwlm5hymsnc23rs", "event", "es", 20,20) # await nostr_client_test_translation("44a0a8b395ade39d46b9d20038b3f0c8a11168e67c442e3ece95e4a1703e2beb", "event", "zh", 20, 20) @@ -463,7 +493,7 @@ async def nostr_client(): # cashutoken = "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MSwiQyI6IjAyNWU3ODZhOGFkMmExYTg0N2YxMzNiNGRhM2VhMGIyYWRhZGFkOTRiYzA4M2E2NWJjYjFlOTgwYTE1NGIyMDA2NCIsInNlY3JldCI6InQ1WnphMTZKMGY4UElQZ2FKTEg4V3pPck5rUjhESWhGa291LzVzZFd4S0U9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6NCwiQyI6IjAyOTQxNmZmMTY2MzU5ZWY5ZDc3MDc2MGNjZmY0YzliNTMzMzVmZTA2ZGI5YjBiZDg2Njg5Y2ZiZTIzMjVhYWUwYiIsInNlY3JldCI6IlRPNHB5WE43WlZqaFRQbnBkQ1BldWhncm44UHdUdE5WRUNYWk9MTzZtQXM9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MTYsIkMiOiIwMmRiZTA3ZjgwYmMzNzE0N2YyMDJkNTZiMGI3ZTIzZTdiNWNkYTBhNmI3Yjg3NDExZWYyOGRiZDg2NjAzNzBlMWIiLCJzZWNyZXQiOiJHYUNIdHhzeG9HM3J2WWNCc0N3V0YxbU1NVXczK0dDN1RKRnVwOHg1cURzPSJ9XSwibWludCI6Imh0dHBzOi8vbG5iaXRzLmJpdGNvaW5maXhlc3RoaXMub3JnL2Nhc2h1L2FwaS92MS9ScDlXZGdKZjlxck51a3M1eVQ2SG5rIn1dfQ==" # await nostr_client_test_image_private("a beautiful ostrich watching the sunset") - await nostr_client_test_mcp() + #await nostr_client_test_mcp() #nutzap_wallet = NutZapWallet() @@ -505,6 +535,10 @@ async def nostr_client(): amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats if tag.as_vec()[0] == "status": status = tag.as_vec()[1] + if status == "pong": + print(status) + + # THIS IS FOR TESTING @@ -526,10 +560,10 @@ async def nostr_client(): # #sleep to avoid event not being updated on self zap # await asyncio.sleep(5) - nut_wallet = await nutzap_wallet.get_nut_wallet(client, keys) - if nut_wallet is not None: - await nutzap_wallet.reedeem_nutzap(event, nut_wallet, client, keys) - # await get_nut_wallet(client, keys) + # nut_wallet = await nutzap_wallet.get_nut_wallet(client, keys) + # if nut_wallet is not None: + # await nutzap_wallet.reedeem_nutzap(event, nut_wallet, client, keys) + # # await get_nut_wallet(client, keys) async def handle_msg(self, relay_url, msg): return