From 6009906577a5d458cd3748c99fd6ce845cea9730 Mon Sep 17 00:00:00 2001 From: Believethehype <1097224+believethehype@users.noreply.github.com> Date: Tue, 18 Jun 2024 08:39:50 +0200 Subject: [PATCH] fix external dvm access for bot after sdk update --- nostr_dvm/bot.py | 45 +++++++++++++------------ nostr_dvm/tasks/people_discovery_wot.py | 5 +-- nostr_dvm/utils/external_dvm_utils.py | 24 ++++++++----- setup.py | 2 +- tests/bot.py | 23 +++++++++++-- tests/discovery_people.py | 2 +- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/nostr_dvm/bot.py b/nostr_dvm/bot.py index 6257880..1dc072d 100644 --- a/nostr_dvm/bot.py +++ b/nostr_dvm/bot.py @@ -37,7 +37,7 @@ class Bot: dvm_config.DB = "db/" + self.NAME + ".db" self.dvm_config = dvm_config nip89config = NIP89Config() - nip89config.NAME = self.NAME + nip89config.PK = self.dvm_config.PRIVATE_KEY self.dvm_config.NIP89 = nip89config self.admin_config = admin_config self.keys = Keys.parse(dvm_config.PRIVATE_KEY) @@ -64,8 +64,8 @@ class Bot: zap_filter = Filter().pubkey(pk).kinds([EventDefinitions.KIND_ZAP]).since(Timestamp.now()) dm_filter = Filter().pubkey(pk).kinds([EventDefinitions.KIND_DM]).since(Timestamp.now()) - nip59_filter = Filter().pubkey(pk).kind(Kind.from_enum(KindEnum.GIFT_WRAP())).since( - Timestamp.from_secs(Timestamp.now().as_secs() - 60 * 60 * 24 * 7)) + nip59_filter = Filter().pubkey(pk).kinds([Kind.from_enum(KindEnum.GIFT_WRAP())]).since( + Timestamp.from_secs(Timestamp.now().as_secs() - 60 * 60 * 24 * 10)).limit(0) kinds = [EventDefinitions.KIND_NIP90_GENERIC, EventDefinitions.KIND_FEEDBACK] for dvm in self.dvm_config.SUPPORTED_DVMS: if dvm.KIND not in kinds: @@ -97,7 +97,7 @@ class Bot: await handle_dm(nostr_event, False) except Exception as e: print(f"Error during content NIP04 decryption: {e}") - elif nostr_event.kind() == Kind.from_enum(KindEnum.GIFT_WRAP()): + elif nostr_event.kind().as_enum() == KindEnum.GIFT_WRAP(): try: await handle_dm(nostr_event, True) except Exception as e: @@ -120,15 +120,16 @@ class Bot: sender = unwrapped_gift.sender().to_hex() rumor: UnsignedEvent = unwrapped_gift.rumor() - # Check timestamp of rumor + # client.send_sealed_msg(sender, f"Echo: {msg}", None) if rumor.created_at().as_secs() >= Timestamp.now().as_secs(): - if rumor.kind() == Kind.from_enum(KindEnum.PRIVATE_DIRECT_MESSAGE()): - decrypted_text = rumor.content() + if rumor.kind().as_enum() == KindEnum.PRIVATE_DIRECT_MESSAGE(): print(f"Received new msg [sealed]: {decrypted_text}") + decrypted_text = rumor.content() sealed = " [sealed] " - # client.send_sealed_msg(sender, f"Echo: {msg}", None) else: print(f"{rumor.as_json()}") + + except Exception as e: print(f"Error during content NIP59 decryption: {e}") @@ -218,9 +219,11 @@ class Bot: invoice, hash = create_bolt11_ln_bits(amount, self.dvm_config) expires = nostr_event.created_at().as_secs() + (60 * 60 * 24) - qr_code = "https://qrcode.tec-it.com/API/QRCode?data="+ invoice +"&backcolor=%23ffffff&size=small&quietzone=1&errorcorrection=H" + qr_code = "https://qrcode.tec-it.com/API/QRCode?data=" + invoice + "&backcolor=%23ffffff&size=small&quietzone=1&errorcorrection=H" - self.invoice_list.append(InvoiceToWatch(sender=sender, bolt11=invoice, payment_hash=hash, is_paid=False, expires=expires, amount=amount)) + self.invoice_list.append( + InvoiceToWatch(sender=sender, bolt11=invoice, payment_hash=hash, is_paid=False, + expires=expires, amount=amount)) if requests_rq: message = invoice + "\n" + qr_code @@ -229,14 +232,14 @@ class Bot: if giftwrap: await self.client.send_private_msg(PublicKey.parse(sender), message, None) else: - time.sleep(2.0) + await asyncio.sleep(2.0) evt = EventBuilder.encrypted_direct_msg(self.keys, PublicKey.parse(sender), message, None).to_event(self.keys) await send_event(evt, client=self.client, dvm_config=dvm_config) elif decrypted_text.lower().startswith("balance"): - time.sleep(2.0) + await asyncio.sleep(2.0) message = "Your current balance is " + str(user.balance) + (" Sats. Zap me to add to your " "balance. I will use your " "balance interact with the DVMs " @@ -263,7 +266,7 @@ class Bot: await update_user_balance(self.dvm_config.DB, sender, total_amount, client=self.client, config=self.dvm_config) else: - time.sleep(2.0) + await asyncio.sleep(2.0) message = "Error: " + cashu_message + ". Token has not been redeemed." if giftwrap: @@ -273,7 +276,7 @@ class Bot: None).to_event(self.keys) await send_event(evt, client=self.client, dvm_config=self.dvm_config) elif decrypted_text.lower().startswith("what's the second best"): - time.sleep(3.0) + await asyncio.sleep(2.0) message = "No, there is no second best.\n\nhttps://cdn.nostr.build/p/mYLv.mp4" if giftwrap: await self.client.send_private_msg(PublicKey.parse(sender), message, None) @@ -340,7 +343,7 @@ class Bot: if entry is not None and entry['dvm_key'] == nostr_event.author().to_hex(): user = await get_or_add_user(db=self.dvm_config.DB, npub=entry['npub'], client=self.client, config=self.dvm_config) - time.sleep(2.0) + await asyncio.sleep(2.0) if entry["giftwrap"]: await self.client.send_private_msg(PublicKey.parse(entry["npub"]), content, None) else: @@ -389,7 +392,7 @@ class Bot: else: print("Bot payment-required") - time.sleep(2.0) + await asyncio.sleep(2.0) evt = EventBuilder.encrypted_direct_msg(self.keys, PublicKey.parse(entry["npub"]), "Current balance: " + str( @@ -467,7 +470,7 @@ class Bot: content = post_process_list_to_users(content) print("[" + self.NAME + "] Received results, message to orignal sender " + user.name) - time.sleep(1.0) + await asyncio.sleep(2.0) if entry["giftwrap"]: await self.client.send_private_msg(PublicKey.parse(user.npub), content, None) else: @@ -541,7 +544,7 @@ class Bot: " Sats\n\n") index += 1 - time.sleep(3.0) + await asyncio.sleep(2.0) text = message + "\nSelect an Index and provide an input (e.g. \"2 A purple ostrich\")\nType \"index info\" to learn more about each DVM. (e.g. \"2 info\")\n\n Type \"balance\" to see your current balance" if giftwrap: @@ -567,7 +570,7 @@ class Bot: info = await print_dvm_info(self.client, index) if info is None: info = "No NIP89 Info found for " + self.dvm_config.SUPPORTED_DVMS[index].NAME - time.sleep(2.0) + await asyncio.sleep(2.0) if giftwrap: await self.client.send_private_msg(PublicKey.parse(sender), info, None) @@ -743,7 +746,8 @@ class Bot: print("is paid") invoice.is_paid = True - await update_user_balance(self.dvm_config.DB, invoice.sender, invoice.amount, client=self.client, + await update_user_balance(self.dvm_config.DB, invoice.sender, invoice.amount, + client=self.client, config=self.dvm_config) print("[" + self.dvm_config.NIP89.NAME + "] updating balance from invoice list") @@ -754,7 +758,6 @@ class Bot: elif Timestamp.now().as_secs() > invoice.expires: self.invoice_list.remove(invoice) - await asyncio.sleep(1.0) except KeyboardInterrupt: print('Stay weird!') diff --git a/nostr_dvm/tasks/people_discovery_wot.py b/nostr_dvm/tasks/people_discovery_wot.py index cc5be48..68075fb 100644 --- a/nostr_dvm/tasks/people_discovery_wot.py +++ b/nostr_dvm/tasks/people_discovery_wot.py @@ -119,7 +119,7 @@ class DiscoverPeopleWOT(DVMTaskInterface): ns = SimpleNamespace() options = self.set_options(request_form) - file = "db/friends223.csv" + file = "db/" + options["user"] + ".csv" try: print("Deleting existing file, creating new one") os.remove(file) @@ -285,10 +285,7 @@ class Friend(object): def write_to_csv(friends, file="friends222.csv"): with open(file, 'a') as f: writer = csv.writer(f) - friendcounter = 0 for friend in friends: - print(friendcounter) - friendcounter += 1 for fren in friend.friends: row = [friend.user_id, fren] writer.writerow(row) diff --git a/nostr_dvm/utils/external_dvm_utils.py b/nostr_dvm/utils/external_dvm_utils.py index 5368650..e021603 100644 --- a/nostr_dvm/utils/external_dvm_utils.py +++ b/nostr_dvm/utils/external_dvm_utils.py @@ -1,3 +1,4 @@ +import asyncio import json from datetime import timedelta @@ -9,14 +10,7 @@ from nostr_dvm.utils.nip89_utils import NIP89Config, nip89_fetch_events_pubkey from nostr_dvm.utils.output_utils import PostProcessFunctionType -async def build_external_dvm(pubkey, task, kind, fix_cost, per_unit_cost, config, - external_post_process=PostProcessFunctionType.NONE): - dvm_config = DVMConfig() - dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex() - dvm_config.FIX_COST = fix_cost - dvm_config.PER_UNIT_COST = per_unit_cost - dvm_config.EXTERNAL_POST_PROCESS_TYPE = external_post_process - +async def build_client(config): opts = (Options().wait_for_send(True).send_timeout(timedelta(seconds=config.RELAY_TIMEOUT)) .skip_disconnected_relays(True)) keys = Keys.parse(config.PRIVATE_KEY) @@ -26,8 +20,20 @@ async def build_external_dvm(pubkey, task, kind, fix_cost, per_unit_cost, config for relay in config.RELAY_LIST: await client.add_relay(relay) await client.connect() + return client - nip89content_str = await nip89_fetch_events_pubkey(client, pubkey, kind) + +def build_external_dvm(pubkey, task, kind, fix_cost, per_unit_cost, config, + external_post_process=PostProcessFunctionType.NONE): + dvm_config = DVMConfig() + dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex() + dvm_config.FIX_COST = fix_cost + dvm_config.PER_UNIT_COST = per_unit_cost + dvm_config.EXTERNAL_POST_PROCESS_TYPE = external_post_process + + client = asyncio.run(build_client(config)) + + nip89content_str = asyncio.run(nip89_fetch_events_pubkey(client, pubkey, kind)) name = "External DVM" image = "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg" about = "An External DVM with no info" diff --git a/setup.py b/setup.py index 4d2bd3d..c1ea5a1 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -VERSION = '0.6.15' +VERSION = '0.6.16' DESCRIPTION = 'A framework to build and run Nostr NIP90 Data Vending Machines' LONG_DESCRIPTION = ('A framework to build and run Nostr NIP90 Data Vending Machines. See the github repository for more information') diff --git a/tests/bot.py b/tests/bot.py index d2de03e..42ca4df 100644 --- a/tests/bot.py +++ b/tests/bot.py @@ -1,3 +1,4 @@ +import asyncio import json import os import threading @@ -10,9 +11,12 @@ from nostr_dvm.bot import Bot from nostr_dvm.tasks import textextraction_pdf from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.backend_utils import keep_alive +from nostr_dvm.utils.definitions import EventDefinitions from nostr_dvm.utils.dvmconfig import DVMConfig +from nostr_dvm.utils.external_dvm_utils import build_external_dvm from nostr_dvm.utils.nip89_utils import NIP89Config from nostr_dvm.utils.nostr_utils import check_and_set_private_key +from nostr_dvm.utils.output_utils import PostProcessFunctionType from nostr_dvm.utils.zap_utils import check_and_set_ln_bits_keys @@ -26,6 +30,7 @@ def playground(): bot_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back bot_config.LNBITS_URL = os.getenv("LNBITS_HOST") + admin_config = AdminConfig() pdfextractor = textextraction_pdf.build_example("PDF Extractor", "pdf_extractor", admin_config) @@ -33,13 +38,27 @@ def playground(): pdfextractor.run() bot_config.SUPPORTED_DVMS.append(pdfextractor) # We add translator to the bot - x = threading.Thread(target=Bot, args=([bot_config])) + ymhm_external = build_external_dvm(pubkey="58c52fdca7593dffea63ba6f758779d8251c6732f54e9dc0e56d7a1afe1bb1b6", + task="wot-discovery", + kind=EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, + fix_cost=0, per_unit_cost=0, config=bot_config, + external_post_process=PostProcessFunctionType.NONE) + + bot_config.SUPPORTED_DVMS.append(ymhm_external) + + admin_config = AdminConfig() + admin_config.REBROADCAST_NIP65_RELAY_LIST = True + x = threading.Thread(target=Bot, args=([bot_config, admin_config])) x.start() # Keep the main function alive for libraries that require it, like openai # keep_alive() + + + + if __name__ == '__main__': env_path = Path('.env') if not env_path.is_file(): @@ -51,4 +70,4 @@ if __name__ == '__main__': dotenv.load_dotenv(env_path, verbose=True, override=True) else: raise FileNotFoundError(f'.env file not found at {env_path} ') - playground() + playground() \ No newline at end of file diff --git a/tests/discovery_people.py b/tests/discovery_people.py index f99bf1f..57fc4ed 100644 --- a/tests/discovery_people.py +++ b/tests/discovery_people.py @@ -109,7 +109,7 @@ def playground(): # admin_config_global_popular.PRIVKEY = "" # admin_config_global_popular.EVENTID = "2fea4ee2ccf0fa11db171113ffd7a676f800f34121478b7c9a4e73c2f1990028" # admin_config_global_popular.POW = True - custom_processing_msg = ["Looking for people, that your WOT follows"] + custom_processing_msg = ["Looking for people, that npubs in your Web of Trust follow, but you don't"] update_db = True options_wot = {