Add NIP65, use events tag -> Nip65 -> Generic relays

This commit is contained in:
Believethehype 2024-06-03 20:24:29 +02:00
parent f3d894e4dc
commit 35e38a951e
5 changed files with 122 additions and 23 deletions

View File

@ -17,7 +17,8 @@ from nostr_dvm.utils.database_utils import create_sql_table, get_or_add_user, up
update_user_subscription
from nostr_dvm.utils.mediasource_utils import input_data_file_duration
from nostr_dvm.utils.nip88_utils import nip88_has_active_subscription
from nostr_dvm.utils.nostr_utils import get_event_by_id, get_referenced_event_by_id, send_event, check_and_decrypt_tags
from nostr_dvm.utils.nostr_utils import get_event_by_id, get_referenced_event_by_id, send_event, check_and_decrypt_tags, \
send_event_outbox
from nostr_dvm.utils.output_utils import build_status_reaction
from nostr_dvm.utils.zap_utils import check_bolt11_ln_bits_is_paid, create_bolt11_ln_bits, parse_zap_event_tags, \
parse_amount_from_bolt11_invoice, zaprequest, pay_bolt11_ln_bits, create_bolt11_lud16
@ -40,12 +41,11 @@ class DVM:
wait_for_send = False
skip_disconnected_relays = True
relaylimits = RelayLimits.disable()
opts = (Options().wait_for_send(wait_for_send). send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))
.skip_disconnected_relays(skip_disconnected_relays).relay_limits(relaylimits))
signer = NostrSigner.keys(self.keys)
self.client = Client.with_opts(signer, opts)
self.job_list = []
self.jobs_on_hold_list = []
pk = self.keys.public_key()
@ -121,7 +121,8 @@ class DVM:
print("[" + self.dvm_config.NIP89.NAME + "] Request by blacklisted user, skipped")
return
print(bcolors.MAGENTA + "[" + self.dvm_config.NIP89.NAME + "] Received new Request: " + task + " from " + user.name + bcolors.ENDC)
print(
bcolors.MAGENTA + "[" + self.dvm_config.NIP89.NAME + "] Received new Request: " + task + " from " + user.name + bcolors.ENDC)
duration = input_data_file_duration(nip90_event, dvm_config=self.dvm_config, client=self.client)
amount = get_amount_per_task(task, self.dvm_config, duration)
if amount is None:
@ -456,6 +457,16 @@ class DVM:
original_event.kind().as_u64()) + ". The task was: " + original_event.content()])
status_tag = Tag.parse(["status", "success"])
reply_tags = [request_tag, e_tag, p_tag, alt_tag, status_tag]
relay_tag = None
for tag in original_event.tags():
if tag.as_vec()[0] == "relays":
relay_tag = tag
break
if relay_tag is not None:
reply_tags.append(relay_tag)
encrypted = False
for tag in original_event.tags():
if tag.as_vec()[0] == "encrypted":
@ -477,7 +488,8 @@ class DVM:
reply_event = EventBuilder(Kind(original_event.kind().as_u64() + 1000), str(content), reply_tags).to_event(
self.keys)
send_event(reply_event, client=self.client, dvm_config=self.dvm_config)
# send_event(reply_event, client=self.client, dvm_config=self.dvm_config)
send_event_outbox(reply_event, client=self.client, dvm_config=self.dvm_config)
print(bcolors.GREEN + "[" + self.dvm_config.NIP89.NAME + "] " + str(
original_event.kind().as_u64() + 1000) + " Job Response event sent: " + reply_event.as_json() + bcolors.ENDC)
@ -493,7 +505,17 @@ class DVM:
p_tag = Tag.parse(["p", original_event.author().to_hex()])
alt_tag = Tag.parse(["alt", alt_description])
status_tag = Tag.parse(["status", status])
reply_tags = [e_tag, alt_tag, status_tag]
relay_tag = None
for tag in original_event.tags():
if tag.as_vec()[0] == "relays":
relay_tag = tag
break
if relay_tag is not None:
reply_tags.append(relay_tag)
encryption_tags = []
encrypted = False
@ -577,7 +599,8 @@ class DVM:
keys = Keys.parse(dvm_config.PRIVATE_KEY)
reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(keys)
send_event(reaction_event, client=self.client, dvm_config=self.dvm_config)
# send_event(reaction_event, client=self.client, dvm_config=self.dvm_config)
send_event_outbox(reaction_event, client=self.client, dvm_config=self.dvm_config)
print(bcolors.YELLOW + "[" + self.dvm_config.NIP89.NAME + "]" + " Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u64()) + " Reaction: " + status + " " + reaction_event.as_json() + bcolors.ENDC)
@ -625,7 +648,8 @@ class DVM:
post_processed = dvm.post_process(result, job_event)
send_nostr_reply_event(post_processed, job_event.as_json())
except Exception as e:
print(bcolors.RED + "[" + self.dvm_config.NIP89.NAME + "] Error: " + str(e) + bcolors.ENDC)
print(bcolors.RED + "[" + self.dvm_config.NIP89.NAME + "] Error: " + str(
e) + bcolors.ENDC)
send_job_status_reaction(job_event, "error", content=str(e),
dvm_config=self.dvm_config)
except Exception as e:

View File

@ -155,14 +155,16 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
ns.finallist[event.id().to_hex()] = invoice_amount
result_list = []
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
len(result_list)) + " fitting events.")
finallist_sorted = sorted(ns.finallist.items(), key=lambda x: x[1], reverse=True)[:int(options["max_results"])]
for entry in finallist_sorted:
# print(EventId.parse(entry[0]).to_bech32() + "/" + EventId.parse(entry[0]).to_hex() + ": " + str(entry[1]))
e_tag = Tag.parse(["e", entry[0]])
result_list.append(e_tag.as_vec())
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
len(result_list)) + " fitting events.")
cli.disconnect()
cli.shutdown()

View File

@ -176,7 +176,6 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
# print(EventId.parse(entry[0]).to_bech32() + "/" + EventId.parse(entry[0]).to_hex() + ": " + str(entry[1]))
e_tag = Tag.parse(["e", entry[0]])
result_list.append(e_tag.as_vec())
print(len(result_list))
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
len(result_list)) + " fitting events.")

View File

@ -6,7 +6,9 @@ from typing import List
import dotenv
from nostr_sdk import Filter, Client, Alphabet, EventId, Event, PublicKey, Tag, Keys, nip04_decrypt, Metadata, Options, \
Nip19Event, SingleLetterTag
Nip19Event, SingleLetterTag, RelayOptions, RelayLimits, SecretKey, NostrSigner
from nostr_dvm.utils.definitions import EventDefinitions
def get_event_by_id(event_id: str, client: Client, config=None) -> Event | None:
@ -104,10 +106,80 @@ def get_referenced_event_by_id(event_id, client, dvm_config, kinds) -> Event | N
return None
def get_inbox_relays(event_to_send: Event, client: Client, dvm_config):
ptags = []
for tag in event_to_send.tags():
if tag.as_vec()[0] == 'p':
ptag = PublicKey.parse(tag.as_vec()[1])
ptags.append(ptag)
filter = Filter().kinds([EventDefinitions.KIND_RELAY_ANNOUNCEMENT]).authors(ptags)
events = client.get_events_of([filter], timedelta(dvm_config.RELAY_TIMEOUT))
if len(events) == 0:
return []
else:
nip65event = events[0]
relays = []
for tag in nip65event.tags():
if tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2:
rtag = tag.as_vec()[1]
relays.append(rtag)
elif tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3:
if tag.as_vec()[2] == "read":
rtag = tag.as_vec()[1]
relays.append(rtag)
return relays
def send_event_outbox(event: Event, client, dvm_config) -> EventId:
# 1. OK, Let's overcomplicate things.
# 2. If our event has a relays tag, we just send the event to these relay in the classical way.
relays = []
for tag in event.tags():
if tag.as_vec()[0] == 'relays':
for index, param in enumerate(tag.as_vec()):
if index != 0:
relays.append(tag.as_vec()[index])
break
# 3. If we couldn't find relays, we look in the receivers inbox
if len(relays) == 0:
relays = get_inbox_relays(event, client, dvm_config)
# 4. If we don't find inbox relays (e.g. because the user didn't announce them, we just send to our default relays
if len(relays) == 0:
print("[" + dvm_config.NIP89.NAME + "] No Inbox found, replying to generic relays")
eventid = send_event(event, client, dvm_config)
return eventid
# 5. Otherwise, we create a new Outbox client with the inbox relays and send the event there
relaylimits = RelayLimits.disable()
opts = (
Options().wait_for_send(False).send_timeout(timedelta(seconds=dvm_config.RELAY_TIMEOUT)).relay_limits(
relaylimits))
sk = SecretKey.from_hex(dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
outboxclient = Client.with_opts(signer, opts)
print("[" + dvm_config.NIP89.NAME + "] Receiver Inbox relays: " + str(relays))
for relay in relays:
opts = RelayOptions().ping(False)
outboxclient.add_relay_with_opts(relay, opts)
outboxclient.connect()
event_id = outboxclient.send_event(event)
outboxclient.shutdown()
return event_id
def send_event(event: Event, client: Client, dvm_config, blastr=False) -> EventId:
try:
relays = []
for tag in event.tags():
if tag.as_vec()[0] == 'relays':
for index, param in enumerate(tag.as_vec()):
@ -118,16 +190,16 @@ def send_event(event: Event, client: Client, dvm_config, blastr=False) -> EventI
if relay not in dvm_config.RELAY_LIST:
client.add_relay(relay)
if blastr:
client.add_relay("wss://nostr.mutinywallet.com")
#if blastr:
# client.add_relay("wss://nostr.mutinywallet.com")
event_id = client.send_event(event)
for relay in relays:
if relay not in dvm_config.RELAY_LIST:
client.remove_relay(relay)
if blastr:
client.remove_relay("wss://nostr.mutinywallet.com")
#if blastr:
# client.remove_relay("wss://nostr.mutinywallet.com")
return event_id
except Exception as e:
print(e)

View File

@ -19,7 +19,9 @@ from nostr_dvm.utils.nostr_utils import check_and_set_private_key
from nostr_dvm.utils.zap_utils import check_and_set_ln_bits_keys
rebbroadcast_NIP89 = False # Announce NIP89 on startup
rebbroadcast_NIP65_Relay_List = True
rebbroadcast_NIP65_Relay_List = False
update_profile = False
global_update_rate = 120 # set this high on first sync so db can fully sync before another process trys to.
use_logger = True
@ -238,7 +240,7 @@ def playground():
admin_config_trending_nostr_band = AdminConfig()
admin_config_trending_nostr_band.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_trending_nostr_band.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_trending_nostr_band.UPDATE_PROFILE = False
admin_config_trending_nostr_band.UPDATE_PROFILE = update_profile
#admin_config_trending_nostr_band.DELETE_NIP89 = True
#admin_config_trending_nostr_band.PRIVKEY = ""
#admin_config_trending_nostr_band.EVENTID = "e7a7aaa7113f17af94ccbfe86c06e04c27ffce3d2f654d613ce249b68414bdae"
@ -259,7 +261,7 @@ def playground():
admin_config_animals = AdminConfig()
admin_config_animals.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_animals.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_animals.UPDATE_PROFILE = False
admin_config_animals.UPDATE_PROFILE = update_profile
#admin_config_animals.DELETE_NIP89 = True
#admin_config_animals.PRIVKEY = ""
#admin_config_animals.EVENTID = "79c613b5f0e71718628bd0c782a5b6b495dac491f36c326ccf416ada80fd8fdc"
@ -317,7 +319,7 @@ def playground():
admin_config_plants = AdminConfig()
admin_config_plants.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_plants.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_plants.UPDATE_PROFILE = False
admin_config_plants.UPDATE_PROFILE = update_profile
#admin_config_plants.DELETE_NIP89 = True
#admin_config_plants.PRIVKEY = ""
#admin_config_plants.EVENTID = "ff28be59708ee597c7010fd43a7e649e1ab51da491266ca82a84177e0007e4d6"
@ -363,7 +365,7 @@ def playground():
admin_config_top_zaps = AdminConfig()
admin_config_top_zaps.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_top_zaps.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_top_zaps.UPDATE_PROFILE = False
admin_config_top_zaps.UPDATE_PROFILE = update_profile
#admin_config_top_zaps.DELETE_NIP89 = True
#admin_config_top_zaps.PRIVKEY = ""
#admin_config_top_zaps.EVENTID = "05a6de88e15aa6c8b4c8ec54481f885f397a30761ff2799958e5c5ee9ad6917b"
@ -394,7 +396,7 @@ def playground():
admin_config_followers = AdminConfig()
admin_config_followers.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_followers.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_followers.UPDATE_PROFILE = False
admin_config_followers.UPDATE_PROFILE = update_profile
#admin_config_followers.DELETE_NIP89 = True
#admin_config_followers.PRIVKEY = ""
#admin_config_followers.EVENTID = "590cd7b2902224f740acbd6845023a5ab4a959386184f3360c2859019cfd48fa"
@ -426,7 +428,7 @@ def playground():
admin_config_global_popular = AdminConfig()
admin_config_global_popular.REBROADCAST_NIP89 = rebbroadcast_NIP89
admin_config_global_popular.REBROADCAST_NIP65_RELAY_LIST = rebbroadcast_NIP65_Relay_List
admin_config_global_popular.UPDATE_PROFILE = False
admin_config_global_popular.UPDATE_PROFILE = update_profile
#admin_config_global_popular.DELETE_NIP89 = True
#admin_config_global_popular.PRIVKEY = ""
#admin_config_global_popular.EVENTID = "2fea4ee2ccf0fa11db171113ffd7a676f800f34121478b7c9a4e73c2f1990028"