update to sdk 0.36 (for testing..)

This commit is contained in:
Believethehype
2024-11-06 08:14:15 +01:00
parent 972785d28d
commit ab66d5ed46
82 changed files with 1420 additions and 654 deletions

View File

@@ -21,13 +21,12 @@ async def nostr_client_test_llm(prompt):
"wss://nostr-pub.wellorder.net"]) "wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTSt"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTSt"])
event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_TEXT, str("Generate an Audio File."), event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_TEXT, str("Generate an Audio File."),
[iTag, relaysTag, alttag]).to_event(keys) [iTag, relaysTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"] "wss://nostr-pub.wellorder.net"]
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)

View File

@@ -25,14 +25,13 @@ async def nostr_client_test_tts(prompt):
"wss://nostr-pub.wellorder.net"]) "wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTS"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTS"])
event = EventBuilder(EventDefinitions.KIND_NIP90_TEXT_TO_SPEECH, str("Generate an Audio File."), event = EventBuilder(EventDefinitions.KIND_NIP90_TEXT_TO_SPEECH, str("Generate an Audio File."),
[iTag, paramTag1, bidTag, relaysTag, alttag]).to_event(keys) [iTag, paramTag1, bidTag, relaysTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"] "wss://nostr-pub.wellorder.net"]
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -45,8 +44,7 @@ async def nostr_client():
sk = keys.secret_key() sk = keys.secret_key()
pk = keys.public_key() pk = keys.public_key()
print(f"Nostr Test Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ") print(f"Nostr Test Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:

View File

@@ -24,14 +24,12 @@ async def nostr_client_test(prompt):
"wss://nostr-pub.wellorder.net"]) "wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTS"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTS"])
event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_TEXT, str("Answer to prompt"), event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_TEXT, str("Answer to prompt"),
[iTag, relaysTag, alttag]).to_event(keys) [iTag, relaysTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"] "wss://nostr-pub.wellorder.net"]
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5))) client = Client(keys)
signer = NostrSigner.keys(keys)
client = Client.with_opts(signer,opts)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -44,8 +42,7 @@ async def nostr_client():
sk = keys.secret_key() sk = keys.secret_key()
pk = keys.public_key() pk = keys.public_key()
print(f"Nostr Test Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ") print(f"Nostr Test Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:

View File

@@ -43,12 +43,8 @@ class Bot:
self.keys = Keys.parse(dvm_config.PRIVATE_KEY) self.keys = Keys.parse(dvm_config.PRIVATE_KEY)
self.CHATBOT = False self.CHATBOT = False
wait_for_send = True opts = (Options().gossip(True))
skip_disconnected_relays = True self.client = Client.with_opts(self.keys, opts)
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))
.skip_disconnected_relays(skip_disconnected_relays).gossip(True))
signer = NostrSigner.keys(self.keys)
self.client = Client.with_opts(signer, opts)
self.invoice_list = [] self.invoice_list = []
pk = self.keys.public_key() pk = self.keys.public_key()
@@ -127,11 +123,11 @@ class Bot:
if giftwrap: if giftwrap:
try: try:
# Extract rumor # Extract rumor
unwrapped_gift = UnwrappedGift.from_gift_wrap(self.keys, nostr_event)
unwrapped_gift = await UnwrappedGift.from_gift_wrap(self.keys, nostr_event)
sender = unwrapped_gift.sender().to_hex() sender = unwrapped_gift.sender().to_hex()
rumor: UnsignedEvent = unwrapped_gift.rumor() rumor: UnsignedEvent = unwrapped_gift.rumor()
# client.send_sealed_msg(sender, f"Echo: {msg}", None)
if rumor.created_at().as_secs() >= Timestamp.now().as_secs(): if rumor.created_at().as_secs() >= Timestamp.now().as_secs():
if rumor.kind().as_enum() == KindEnum.PRIVATE_DIRECT_MESSAGE(): if rumor.kind().as_enum() == KindEnum.PRIVATE_DIRECT_MESSAGE():
print(f"Received new msg [sealed]: {decrypted_text}") print(f"Received new msg [sealed]: {decrypted_text}")
@@ -198,13 +194,13 @@ class Bot:
# add the encrypted params to the content # add the encrypted params to the content
nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND, nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND,
encrypted_params, [p_tag, encrypted_tag]). encrypted_params, [p_tag, encrypted_tag]).
to_event(self.keys)) sign_with_keys(self.keys))
else: else:
tags.append(p_tag) tags.append(p_tag)
nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND, nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND,
"", tags). "", tags).
to_event(self.keys)) sign_with_keys(self.keys))
# remember in the job_list that we have made an event, if anybody asks for payment, # remember in the job_list that we have made an event, if anybody asks for payment,
# we know we actually sent the request # we know we actually sent the request
@@ -317,7 +313,7 @@ class Bot:
nip90request = (EventBuilder(Kind(kind), nip90request = (EventBuilder(Kind(kind),
"", tags). "", tags).
to_event(self.keys)) sign_with_keys(self.keys))
entry = {"npub": user.npub, "event_id": nip90request.id().to_hex(), entry = {"npub": user.npub, "event_id": nip90request.id().to_hex(),
"dvm_key": self.DVM_KEY, "is_paid": False, "dvm_key": self.DVM_KEY, "is_paid": False,
@@ -338,7 +334,7 @@ class Bot:
etag = "" etag = ""
ptag = "" ptag = ""
content = nostr_event.content() content = nostr_event.content()
for tag in nostr_event.tags(): for tag in nostr_event.tags().to_vec():
if tag.as_vec()[0] == "status": if tag.as_vec()[0] == "status":
status = tag.as_vec()[1] status = tag.as_vec()[1]
if len(tag.as_vec()) > 2: if len(tag.as_vec()) > 2:
@@ -362,7 +358,7 @@ class Bot:
event_as_json['content'] = "" event_as_json['content'] = ""
nostr_event = Event.from_json(json.dumps(event_as_json)) nostr_event = Event.from_json(json.dumps(event_as_json))
for tag in nostr_event.tags(): for tag in nostr_event.tags().to_vec():
if tag.as_vec()[0] == "status": if tag.as_vec()[0] == "status":
status = tag.as_vec()[1] status = tag.as_vec()[1]
if len(tag.as_vec()) > 2: if len(tag.as_vec()) > 2:
@@ -390,7 +386,7 @@ class Bot:
"[" + self.NAME + "] Received reaction from " + nostr_event.author().to_hex() + " message to orignal sender " + user.name) "[" + self.NAME + "] Received reaction from " + nostr_event.author().to_hex() + " message to orignal sender " + user.name)
elif status == "payment-required" or status == "partial": elif status == "payment-required" or status == "partial":
for tag in nostr_event.tags(): for tag in nostr_event.tags().to_vec():
if tag.as_vec()[0] == "amount": if tag.as_vec()[0] == "amount":
amount_msats = int(tag.as_vec()[1]) amount_msats = int(tag.as_vec()[1])
amount = int(amount_msats / 1000) amount = int(amount_msats / 1000)
@@ -469,7 +465,7 @@ class Bot:
ptag = "" ptag = ""
etag = "" etag = ""
is_encrypted = False is_encrypted = False
for tag in nostr_event.tags(): for tag in nostr_event.tags().to_vec():
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":
etag = tag.as_vec()[1] etag = tag.as_vec()[1]
elif tag.as_vec()[0] == "p": elif tag.as_vec()[0] == "p":
@@ -522,7 +518,7 @@ class Bot:
etag = "" etag = ""
if zapped_event is not None: if zapped_event is not None:
for tag in zapped_event.tags(): for tag in zapped_event.tags().to_vec():
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":
etag = tag.as_vec()[1] etag = tag.as_vec()[1]

View File

@@ -1,11 +1,10 @@
import asyncio import asyncio
import json import json
import os import os
from datetime import timedelta
from sys import platform from sys import platform
from nostr_sdk import PublicKey, Keys, Client, Tag, Event, EventBuilder, Filter, HandleNotification, Timestamp, \ from nostr_sdk import PublicKey, Keys, Client, Tag, Event, EventBuilder, Filter, HandleNotification, Timestamp, \
LogLevel, Options, nip04_encrypt, NostrSigner, Kind, RelayLimits LogLevel, Options, nip04_encrypt, Kind, RelayLimits
from nostr_dvm.utils.admin_utils import admin_make_database_updates, AdminConfig from nostr_dvm.utils.admin_utils import admin_make_database_updates, AdminConfig
from nostr_dvm.utils.backend_utils import get_amount_per_task, check_task_is_supported, get_task from nostr_dvm.utils.backend_utils import get_amount_per_task, check_task_is_supported, get_task
@@ -42,15 +41,11 @@ class DVM:
self.dvm_config = dvm_config self.dvm_config = dvm_config
self.admin_config = admin_config self.admin_config = admin_config
self.keys = Keys.parse(dvm_config.PRIVATE_KEY) self.keys = Keys.parse(dvm_config.PRIVATE_KEY)
wait_for_send = False
skip_disconnected_relays = True
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (
Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)) Options().relay_limits(relaylimits))
.skip_disconnected_relays(skip_disconnected_relays).relay_limits(relaylimits))
signer = NostrSigner.keys(self.keys) self.client = Client.with_opts(self.keys, opts)
self.client = Client.with_opts(signer, opts)
self.job_list = [] self.job_list = []
self.jobs_on_hold_list = [] self.jobs_on_hold_list = []
pk = self.keys.public_key() pk = self.keys.public_key()
@@ -119,7 +114,7 @@ class DVM:
cashu = "" cashu = ""
p_tag_str = "" p_tag_str = ""
for tag in nip90_event.tags(): for tag in nip90_event.tags().to_vec():
if tag.as_vec()[0] == "cashu": if tag.as_vec()[0] == "cashu":
cashu = tag.as_vec()[1] cashu = tag.as_vec()[1]
elif tag.as_vec()[0] == "p": elif tag.as_vec()[0] == "p":
@@ -281,7 +276,7 @@ class DVM:
# dvm_config=self.dvm_config) # dvm_config=self.dvm_config)
else: else:
bid = 0 bid = 0
for tag in nip90_event.tags(): for tag in nip90_event.tags().to_vec():
if tag.as_vec()[0] == 'bid': if tag.as_vec()[0] == 'bid':
bid = int(tag.as_vec()[1]) bid = int(tag.as_vec()[1])
@@ -321,7 +316,7 @@ class DVM:
user = await get_or_add_user(db=self.dvm_config.DB, npub=sender, client=self.client, user = await get_or_add_user(db=self.dvm_config.DB, npub=sender, client=self.client,
config=self.dvm_config) config=self.dvm_config)
zapped_event = None zapped_event = None
for tag in nut_zap_event.tags(): for tag in nut_zap_event.tags().to_vec():
if tag.as_vec()[0] == 'e': if tag.as_vec()[0] == 'e':
zapped_event = await get_event_by_id(tag.as_vec()[1], client=self.client, zapped_event = await get_event_by_id(tag.as_vec()[1], client=self.client,
config=self.dvm_config) config=self.dvm_config)
@@ -332,7 +327,7 @@ class DVM:
job_event = None job_event = None
p_tag_str = "" p_tag_str = ""
status = "" status = ""
for tag in zapped_event.tags(): for tag in zapped_event.tags().to_vec():
if tag.as_vec()[0] == 'amount': if tag.as_vec()[0] == 'amount':
amount = int(float(tag.as_vec()[1]) / 1000) amount = int(float(tag.as_vec()[1]) / 1000)
elif tag.as_vec()[0] == 'e': elif tag.as_vec()[0] == 'e':
@@ -414,7 +409,7 @@ class DVM:
job_event = None job_event = None
p_tag_str = "" p_tag_str = ""
status = "" status = ""
for tag in zapped_event.tags(): for tag in zapped_event.tags().to_vec():
if tag.as_vec()[0] == 'amount': if tag.as_vec()[0] == 'amount':
amount = int(float(tag.as_vec()[1]) / 1000) amount = int(float(tag.as_vec()[1]) / 1000)
elif tag.as_vec()[0] == 'e': elif tag.as_vec()[0] == 'e':
@@ -499,7 +494,7 @@ class DVM:
if not task_supported: if not task_supported:
return False return False
for tag in nevent.tags(): for tag in nevent.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
if len(tag.as_vec()) < 3: if len(tag.as_vec()) < 3:
print("Job Event missing/malformed i tag, skipping..") print("Job Event missing/malformed i tag, skipping..")
@@ -587,7 +582,7 @@ class DVM:
reply_tags = [request_tag, e_tag, p_tag, alt_tag, status_tag] reply_tags = [request_tag, e_tag, p_tag, alt_tag, status_tag]
relay_tag = None relay_tag = None
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "relays": if tag.as_vec()[0] == "relays":
relay_tag = tag relay_tag = tag
if tag.as_vec()[0] == "client": if tag.as_vec()[0] == "client":
@@ -597,13 +592,13 @@ class DVM:
reply_tags.append(relay_tag) reply_tags.append(relay_tag)
encrypted = False encrypted = False
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "encrypted": if tag.as_vec()[0] == "encrypted":
encrypted = True encrypted = True
encrypted_tag = Tag.parse(["encrypted"]) encrypted_tag = Tag.parse(["encrypted"])
reply_tags.append(encrypted_tag) reply_tags.append(encrypted_tag)
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "i": if tag.as_vec()[0] == "i":
i_tag = tag i_tag = tag
if not encrypted: if not encrypted:
@@ -614,7 +609,7 @@ class DVM:
content = nip04_encrypt(self.keys.secret_key(), PublicKey.from_hex(original_event.author().to_hex()), content = nip04_encrypt(self.keys.secret_key(), PublicKey.from_hex(original_event.author().to_hex()),
content) content)
reply_event = EventBuilder(Kind(original_event.kind().as_u16() + 1000), str(content), reply_tags).to_event( reply_event = EventBuilder(Kind(original_event.kind().as_u16() + 1000), str(content), reply_tags).sign_with_keys(
self.keys) 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)
@@ -641,7 +636,7 @@ class DVM:
reply_tags = [e_tag, alt_tag, status_tag] reply_tags = [e_tag, alt_tag, status_tag]
relay_tag = None relay_tag = None
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "relays": if tag.as_vec()[0] == "relays":
relay_tag = tag relay_tag = tag
break break
@@ -651,7 +646,7 @@ class DVM:
encryption_tags = [] encryption_tags = []
encrypted = False encrypted = False
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "encrypted": if tag.as_vec()[0] == "encrypted":
encrypted = True encrypted = True
encrypted_tag = Tag.parse(["encrypted"]) encrypted_tag = Tag.parse(["encrypted"])
@@ -730,7 +725,7 @@ class DVM:
content = reaction content = reaction
keys = Keys.parse(dvm_config.PRIVATE_KEY) keys = Keys.parse(dvm_config.PRIVATE_KEY)
reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(keys) reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).sign_with_keys(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)
await send_event_outbox(reaction_event, client=self.client, dvm_config=self.dvm_config) await send_event_outbox(reaction_event, client=self.client, dvm_config=self.dvm_config)

View File

@@ -38,13 +38,7 @@ class Subscription:
self.dvm_config.NIP89 = nip89config self.dvm_config.NIP89 = nip89config
self.admin_config = admin_config self.admin_config = admin_config
self.keys = Keys.parse(dvm_config.PRIVATE_KEY) self.keys = Keys.parse(dvm_config.PRIVATE_KEY)
self.client = Client(self.keys)
wait_for_send = False
skip_disconnected_relays = True
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))
.skip_disconnected_relays(skip_disconnected_relays))
signer = NostrSigner.keys(self.keys)
self.client = Client.with_opts(signer, opts)
pk = self.keys.public_key() pk = self.keys.public_key()
@@ -100,7 +94,7 @@ class Subscription:
if sender == self.keys.public_key().to_hex(): if sender == self.keys.public_key().to_hex():
return return
for tag in nostr_event.tags(): for tag in nostr_event.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
recipient = tag.as_vec()[1] recipient = tag.as_vec()[1]
elif tag.as_vec()[0] == "e": elif tag.as_vec()[0] == "e":
@@ -156,7 +150,7 @@ class Subscription:
reply_tags = encryption_tags reply_tags = encryption_tags
keys = Keys.parse(dvm_config.PRIVATE_KEY) keys = Keys.parse(dvm_config.PRIVATE_KEY)
reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(keys) reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).sign_with_keys(keys)
await send_event(reaction_event, client=self.client, dvm_config=self.dvm_config) await send_event(reaction_event, client=self.client, dvm_config=self.dvm_config)
print("[" + self.dvm_config.NIP89.NAME + "]" + ": Sent Kind " + str( print("[" + self.dvm_config.NIP89.NAME + "]" + ": Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + "success" + " " + reaction_event.as_json()) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + "success" + " " + reaction_event.as_json())
@@ -214,11 +208,10 @@ class Subscription:
tags = [pTag, PTag, eTag, validTag, tierTag, alttag] tags = [pTag, PTag, eTag, validTag, tierTag, alttag]
event = EventBuilder(EventDefinitions.KIND_NIP88_PAYMENT_RECIPE, event = EventBuilder(EventDefinitions.KIND_NIP88_PAYMENT_RECIPE,
message, tags).to_event(self.keys) message, tags).sign_with_keys(self.keys)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
signer = NostrSigner.keys(self.keys) client = Client(self.keys)
client = Client(signer)
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -248,10 +241,10 @@ class Subscription:
subscriptionfilter = Filter().kind(EventDefinitions.KIND_NIP88_SUBSCRIBE_EVENT).author( subscriptionfilter = Filter().kind(EventDefinitions.KIND_NIP88_SUBSCRIBE_EVENT).author(
PublicKey.parse(subscriber)).limit(1) PublicKey.parse(subscriber)).limit(1)
evts = await self.client.get_events_of([subscriptionfilter], relay_timeout) evts = await self.client.fetch_events([subscriptionfilter], relay_timeout)
if len(evts) > 0: if len(evts.to_vec()) > 0:
event7001id = evts[0].id().to_hex() event7001id = evts.to_vec()[0].id().to_hex()
print(evts[0].as_json()) print(evts.to_vec()[0].as_json())
tier_dtag = "" tier_dtag = ""
recipient = "" recipient = ""
cadence = "" cadence = ""
@@ -260,7 +253,7 @@ class Subscription:
tier = "DVM" tier = "DVM"
overall_amount = 0 overall_amount = 0
subscription_event_id = "" subscription_event_id = ""
for tag in evts[0].tags(): for tag in evts.to_vec()[0].tags().to_vec():
if tag.as_vec()[0] == "amount": if tag.as_vec()[0] == "amount":
overall_amount = int(tag.as_vec()[1]) overall_amount = int(tag.as_vec()[1])
@@ -275,7 +268,7 @@ class Subscription:
jsonevent = json.loads(tag.as_vec()[1]) jsonevent = json.loads(tag.as_vec()[1])
subscription_event = Event.from_json(jsonevent) subscription_event = Event.from_json(jsonevent)
for tag in subscription_event.tags(): for tag in subscription_event.tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
tier_dtag = tag.as_vec()[1] tier_dtag = tag.as_vec()[1]
elif tag.as_vec()[0] == "zap": elif tag.as_vec()[0] == "zap":
@@ -285,9 +278,9 @@ class Subscription:
if tier_dtag == "" or len(zaps) == 0: if tier_dtag == "" or len(zaps) == 0:
tierfilter = Filter().id(EventId.parse(subscription_event_id)) tierfilter = Filter().id(EventId.parse(subscription_event_id))
evts = await self.client.get_events_of([tierfilter], relay_timeout) evts = await self.client.fetch_events([tierfilter], relay_timeout)
if len(evts) > 0: if len(evts.to_vec()) > 0:
for tag in evts[0].tags(): for tag in evts[0].tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
tier_dtag = tag.as_vec()[0] tier_dtag = tag.as_vec()[0]

View File

@@ -54,7 +54,7 @@ class AdvancedSearch(DVMTaskInterface):
max_results = 100 max_results = 100
relay = "wss://relay.nostr.band" relay = "wss://relay.nostr.band"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":
@@ -88,11 +88,9 @@ class AdvancedSearch(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) cli = Client(keys)
cli = Client.with_opts(signer, opts)
await cli.add_relay(options["relay"]) await cli.add_relay(options["relay"])
@@ -132,12 +130,12 @@ class AdvancedSearch(DVMTaskInterface):
notes_filter = Filter().kind(Kind(1)).authors(userkeys).search(options["search"]).since( notes_filter = Filter().kind(Kind(1)).authors(userkeys).search(options["search"]).since(
search_since).until(search_until).limit(options["max_results"]) search_since).until(search_until).limit(options["max_results"])
events = await cli.get_events_of([notes_filter], relay_timeout) events = await cli.fetch_events([notes_filter], relay_timeout)
result_list = [] result_list = []
if len(events) > 0: if len(events.to_vec()) > 0:
for event in events: for event in events.to_vec():
e_tag = Tag.parse(["e", event.id().to_hex()]) e_tag = Tag.parse(["e", event.id().to_hex()])
result_list.append(e_tag.as_vec()) result_list.append(e_tag.as_vec())
@@ -146,7 +144,7 @@ class AdvancedSearch(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -53,7 +53,7 @@ class AdvancedSearchWine(DVMTaskInterface):
search = "" search = ""
max_results = 100 max_results = 100
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":
@@ -129,7 +129,7 @@ class AdvancedSearchWine(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -45,7 +45,7 @@ class AudioGenerationSonoAI(DVMTaskInterface):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")} request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = "A popular heavy metal song about a purple Ostrich, Nostr, sung by a deep-voiced male singer, slowly and melodiously. The lyrics depict hope for a better future." prompt = "A popular heavy metal song about a purple Ostrich, Nostr, sung by a deep-voiced male singer, slowly and melodiously. The lyrics depict hope for a better future."
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -3,7 +3,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind, \
RelayLimits RelayLimits
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -79,7 +79,7 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
search = "" search = ""
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -107,14 +107,12 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
# print(self.db_name) # print(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(keys).build()
await cli.connect() await cli.connect()
# Negentropy reconciliation # Negentropy reconciliation
@@ -150,7 +148,7 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -173,13 +171,11 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = (Options().wait_for_send(False).send_timeout( opts = (Options().relay_limits(relaylimits))
timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT))).relay_limits(relaylimits)
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -196,8 +192,8 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -3,7 +3,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind, \
RelayLimits RelayLimits
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -79,7 +79,7 @@ class DicoverContentLatestWiki(DVMTaskInterface):
search = "" search = ""
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -107,14 +107,12 @@ class DicoverContentLatestWiki(DVMTaskInterface):
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
# print(self.db_name) # print(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(keys).build()
await cli.connect() await cli.connect()
# Negentropy reconciliation # Negentropy reconciliation
@@ -150,7 +148,7 @@ class DicoverContentLatestWiki(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -173,13 +171,11 @@ class DicoverContentLatestWiki(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = (Options().wait_for_send(False).send_timeout( opts = (Options().relay_limits(relaylimits))
timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT))).relay_limits(relaylimits)
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -195,8 +191,8 @@ class DicoverContentLatestWiki(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -4,7 +4,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils import definitions from nostr_dvm.utils import definitions
@@ -80,7 +80,7 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
search = "" search = ""
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -145,7 +145,7 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -169,12 +169,10 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -192,8 +190,8 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -2,7 +2,7 @@ import json
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils import definitions from nostr_dvm.utils import definitions
@@ -79,7 +79,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
# default values # default values
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -107,19 +107,8 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
options = self.set_options(request_form) options = self.set_options(request_form)
# opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
# sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
# keys = Keys.parse(sk.to_hex())
# signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
# cli = ClientBuilder().database(database).signer(signer).opts(opts).build()
# await cli.connect()
# Negentropy reconciliation
# Query events from database
timestamp_hour_ago = Timestamp.now().as_secs() - self.db_since timestamp_hour_ago = Timestamp.now().as_secs() - self.db_since
since = Timestamp.from_secs(timestamp_hour_ago) since = Timestamp.from_secs(timestamp_hour_ago)
@@ -143,7 +132,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
if event_author == zap.author().to_hex(): if event_author == zap.author().to_hex():
continue # Skip self zaps.. continue # Skip self zaps..
invoice_amount = 0 invoice_amount = 0
for tag in zap.tags(): for tag in zap.tags().to_vec():
if tag.as_vec()[0] == 'bolt11': if tag.as_vec()[0] == 'bolt11':
# print(tag.as_vec()[1]) # print(tag.as_vec()[1])
@@ -166,7 +155,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
# elif tag.as_vec()[0] == 'description': # elif tag.as_vec()[0] == 'description':
# try: # try:
# event = Event.from_json(tag.as_vec()[1]) # event = Event.from_json(tag.as_vec()[1])
# for tag in event.tags(): # for tag in event.tags().to_vec():
# if tag.as_vec()[0] == "amount": # if tag.as_vec()[0] == "amount":
# invoice_amount = tag.as_vec()[1] # invoice_amount = tag.as_vec()[1]
# overall_amount += invoice_amount # overall_amount += invoice_amount
@@ -198,7 +187,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -224,12 +213,10 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -247,8 +234,8 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -2,7 +2,7 @@ import json
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Event, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Event, Kind, \
RelayLimits RelayLimits
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -67,7 +67,7 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
user = event.author().to_hex() user = event.author().to_hex()
max_results = 100 max_results = 100
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -92,14 +92,13 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
options = self.set_options(request_form) options = self.set_options(request_form)
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (
Options().wait_for_send(True).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)).relay_limits( Options().relay_limits(
relaylimits)) relaylimits))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(keys).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -110,7 +109,7 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
user = PublicKey.parse(options["user"]) user = PublicKey.parse(options["user"])
followers_filter = Filter().author(user).kinds([Kind(3)]) followers_filter = Filter().author(user).kinds([Kind(3)])
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
# print(followers) # print(followers)
# Negentropy reconciliation # Negentropy reconciliation
@@ -120,17 +119,17 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
result_list = [] result_list = []
if len(followers) > 0: if len(followers.to_vec()) > 0:
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
# print(best_entry.as_json()) # print(best_entry.as_json())
followings = [] followings = []
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = PublicKey.parse(tag.as_vec()[1]) following = PublicKey.parse(tag.as_vec()[1])
followings.append(following) followings.append(following)
@@ -167,7 +166,7 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -190,12 +189,10 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -213,8 +210,8 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -4,7 +4,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, EventId, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, EventId, Kind, \
RelayLimits RelayLimits
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -84,7 +84,7 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
search = "" search = ""
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -133,7 +133,7 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
for ge_event in ge_events: for ge_event in ge_events:
id = None id = None
for tag in ge_event.tags(): for tag in ge_event.tags().to_vec():
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":
id = EventId.from_hex(tag.as_vec()[1]) id = EventId.from_hex(tag.as_vec()[1])
ids.append(id) ids.append(id)
@@ -146,13 +146,11 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
continue continue
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = (Options().wait_for_send(True).send_timeout( opts = (Options().relay_limits(relaylimits))
timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)).relay_limits(relaylimits))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
cli = ClientBuilder().database(databasegallery).signer(signer).opts(opts).build() cli = ClientBuilder().database(databasegallery).signer(keys).opts(opts).build()
for relay in relays: for relay in relays:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -166,15 +164,15 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
definitions.EventDefinitions.KIND_DELETION, definitions.EventDefinitions.KIND_DELETION,
definitions.EventDefinitions.KIND_NOTE]).events(ids).since(since) definitions.EventDefinitions.KIND_NOTE]).events(ids).since(since)
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filtreactions, dbopts) await cli.sync(filtreactions, dbopts)
filter2 = Filter().ids(ids) filter2 = Filter().ids(ids)
events = await cli.get_events_of([filter2], relay_timeout) events = await cli.fetch_events([filter2], relay_timeout)
print(len(events)) print(len(events.to_vec()))
for event in events: for event in events.to_vec():
if event.created_at().as_secs() > timestamp_since: if event.created_at().as_secs() > timestamp_since:
filt1 = Filter().kinds([definitions.EventDefinitions.KIND_DELETION]).event(event.id()).limit(1) filt1 = Filter().kinds([definitions.EventDefinitions.KIND_DELETION]).event(event.id()).limit(1)
deletions = await databasegallery.query([filt1]) deletions = await databasegallery.query([filt1])
@@ -190,7 +188,7 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
if len(reactions) >= self.min_reactions: if len(reactions) >= self.min_reactions:
found = False found = False
for ge_event in ge_events: for ge_event in ge_events:
for tag in ge_event.tags(): for tag in ge_event.tags().to_vec():
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":
if event.id().to_hex() == tag.as_vec()[1]: if event.id().to_hex() == tag.as_vec()[1]:
ns.finallist[ge_event.id().to_hex()] = len(reactions) ns.finallist[ge_event.id().to_hex()] = len(reactions)
@@ -216,7 +214,7 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -240,12 +238,10 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -262,8 +258,8 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -80,7 +80,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
search = "" search = ""
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -109,11 +109,8 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (
Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
try: try:
@@ -121,7 +118,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
Timestamp.now().as_secs() - self.db_since))) Timestamp.now().as_secs() - self.db_since)))
except Exception as e: except Exception as e:
print(e) print(e)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
timestamp_since = Timestamp.now().as_secs() - self.db_since timestamp_since = Timestamp.now().as_secs() - self.db_since
since = Timestamp.from_secs(timestamp_since) since = Timestamp.from_secs(timestamp_since)
@@ -161,7 +158,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -185,12 +182,10 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -216,14 +211,11 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
# dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
# await cli.reconcile(filter1, dbopts)
# await cli.reconcile(filter2, dbopts)
# await cli.reconcile(filter3, dbopts)
# RECONCOILE NOT POSSIBLE ON THESE RELAYS SO WE FETCH AB BUNCH (will be stored in db) # RECONCOILE NOT POSSIBLE ON THESE RELAYS SO WE FETCH AB BUNCH (will be stored in db)
try: try:
events = await cli.get_events_of([filter1, filter2, filter3], relay_timeout_long) events = await cli.fetch_events([filter1, filter2, filter3], relay_timeout_long)
except Exception as e: except Exception as e:
print(e) print(e)
# Do not delete profiles # Do not delete profiles

View File

@@ -4,7 +4,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind, \
RelayLimits RelayLimits
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -96,7 +96,7 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
# default values # default values
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -124,7 +124,7 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -141,15 +141,13 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
options = self.set_options(request_form) options = self.set_options(request_form)
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (
Options().wait_for_send(True).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)).relay_limits( Options().relay_limits(relaylimits))
relaylimits))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
if self.database is None: if self.database is None:
self.database = NostrDatabase.lmdb(self.db_name) self.database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().database(self.database).signer(signer).opts(opts).build() cli = ClientBuilder().database(self.database).signer(keys).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -159,18 +157,18 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
await cli.connect() await cli.connect()
user = PublicKey.parse(options["user"]) user = PublicKey.parse(options["user"])
followers_filter = Filter().author(user).kinds([Kind(3)]) followers_filter = Filter().author(user).kinds([Kind(3)])
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
# print(best_entry.as_json()) # print(best_entry.as_json())
followings = [] followings = []
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = tag.as_vec()[1] following = tag.as_vec()[1]
followings.append(following) followings.append(following)
@@ -227,12 +225,10 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -250,8 +246,8 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -4,7 +4,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils import definitions from nostr_dvm.utils import definitions
@@ -95,7 +95,7 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
max_results = 200 max_results = 200
user = event.author().to_hex() user = event.author().to_hex()
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -133,7 +133,7 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -202,12 +202,10 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -225,8 +223,8 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -48,7 +48,7 @@ class Discoverlatestperfollower(DVMTaskInterface):
since_days = 30 since_days = 30
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'param': if tag.as_vec()[0] == 'param':
param = tag.as_vec()[1] param = tag.as_vec()[1]
if param == "user": # check for param type if param == "user": # check for param type
@@ -71,15 +71,12 @@ class Discoverlatestperfollower(DVMTaskInterface):
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (Options().relay_limits(relaylimits))
Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))).relay_limits(
relaylimits)
cli = Client.with_opts(signer, opts) cli = Client.with_opts(keys, opts)
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
# ropts = RelayOptions().ping(False) # ropts = RelayOptions().ping(False)
@@ -91,14 +88,14 @@ class Discoverlatestperfollower(DVMTaskInterface):
step = 20 step = 20
followers_filter = Filter().author(PublicKey.parse(options["user"])).kind(Kind(3)) followers_filter = Filter().author(PublicKey.parse(options["user"])).kind(Kind(3))
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
result_list = [] result_list = []
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
print(len(best_entry.tags())) print(len(best_entry.tags().to_vec()))
print(best_entry.created_at().as_secs()) print(best_entry.created_at().as_secs())
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
@@ -107,7 +104,7 @@ class Discoverlatestperfollower(DVMTaskInterface):
followings = [] followings = []
ns.dic = {} ns.dic = {}
tagcount = 0 tagcount = 0
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
tagcount += 1 tagcount += 1
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = tag.as_vec()[1] following = tag.as_vec()[1]
@@ -126,10 +123,7 @@ class Discoverlatestperfollower(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
keys = Keys.parse(self.dvm_config.PRIVATE_KEY) keys = Keys.parse(self.dvm_config.PRIVATE_KEY)
opts = Options().wait_for_send(True).send_timeout( cli = Client(keys)
timedelta(seconds=10)).skip_disconnected_relays(True)
signer = NostrSigner.keys(keys)
cli = Client.with_opts(signer, opts)
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
await cli.connect() await cli.connect()
@@ -144,8 +138,8 @@ class Discoverlatestperfollower(DVMTaskInterface):
except Exception as e: except Exception as e:
print(e) print(e)
event_from_authors = await cli.get_events_of(filters, relay_timeout_long) event_from_authors = await cli.fetch_events(filters, relay_timeout_long)
for author in event_from_authors: for author in event_from_authors.to_vec():
if instance.dic[author.author().to_hex()] is None: if instance.dic[author.author().to_hex()] is None:
instance.dic[author.author().to_hex()] = author instance.dic[author.author().to_hex()] = author
print(str(i) + "/" + str(len(users))) print(str(i) + "/" + str(len(users)))
@@ -191,7 +185,7 @@ class Discoverlatestperfollower(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -5,7 +5,7 @@ from datetime import timedelta
from itertools import islice from itertools import islice
from nostr_sdk import Timestamp, PublicKey, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, PublicKey, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind, \ ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind, \
RelayLimits, RelayFilteringMode RelayLimits, RelayFilteringMode
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
@@ -87,7 +87,7 @@ class DicoverContentDBUpdateScheduler(DVMTaskInterface):
# default values # default values
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -107,7 +107,7 @@ class DicoverContentDBUpdateScheduler(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -129,17 +129,15 @@ class DicoverContentDBUpdateScheduler(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
try: try:
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = (Options().wait_for_send(False).send_timeout( opts = (Options().relay_limits(relaylimits))
timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT))).relay_limits(relaylimits)
if self.dvm_config.WOT_FILTERING: if self.dvm_config.WOT_FILTERING:
opts = opts.filtering_mode(RelayFilteringMode.WHITELIST) opts = opts.filtering_mode(RelayFilteringMode.WHITELIST)
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
if self.database is None: if self.database is None:
self.database = NostrDatabase.lmdb(self.db_name) self.database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(self.database).opts(opts).build() cli = ClientBuilder().signer(keys).database(self.database).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -183,8 +181,8 @@ class DicoverContentDBUpdateScheduler(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str( print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()

View File

@@ -49,7 +49,7 @@ class MediaConverter(DVMTaskInterface):
end_time = 0 end_time = 0
# TODO parse start/end parameters # TODO parse start/end parameters
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -3,7 +3,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.admin_utils import AdminConfig
@@ -53,7 +53,7 @@ class DiscoveryBotFarms(DVMTaskInterface):
search = "airdrop;just your average nostr enjoyer" # ;@nostrich.house; search = "airdrop;just your average nostr enjoyer" # ;@nostrich.house;
max_results = 500 max_results = 500
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":
@@ -74,13 +74,11 @@ class DiscoveryBotFarms(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb("db/nostr_profiles.db") database = NostrDatabase.lmdb("db/nostr_profiles.db")
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(keys).build()
await cli.add_relay("wss://relay.damus.io") await cli.add_relay("wss://relay.damus.io")
# cli.add_relay("wss://atl.purplerelay.com") # cli.add_relay("wss://atl.purplerelay.com")
@@ -116,7 +114,7 @@ class DiscoveryBotFarms(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -136,12 +134,10 @@ class DiscoveryBotFarms(DVMTaskInterface):
return 1 return 1
async def sync_db(self): async def sync_db(self):
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb("db/nostr_profiles.db") database = NostrDatabase.lmdb("db/nostr_profiles.db")
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
await cli.add_relay("wss://relay.damus.io") await cli.add_relay("wss://relay.damus.io")
await cli.add_relay("wss://nostr21.com") await cli.add_relay("wss://nostr21.com")
@@ -151,8 +147,8 @@ class DiscoveryBotFarms(DVMTaskInterface):
# filter = Filter().author(keys.public_key()) # filter = Filter().author(keys.public_key())
print("Syncing Profile Database.. this might take a while..") print("Syncing Profile Database.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
print("Done Syncing Profile Database.") print("Done Syncing Profile Database.")

View File

@@ -46,7 +46,7 @@ class DiscoverReports(DVMTaskInterface):
since_days = 90 since_days = 90
# users.append(event.author().to_hex()) # users.append(event.author().to_hex())
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
users.append(tag.as_vec()[1]) users.append(tag.as_vec()[1])
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -70,12 +70,10 @@ class DiscoverReports(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (
Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)).relay_limits( Options().relay_limits(relaylimits))
relaylimits))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) cli = Client.with_opts(keys, opts)
cli = Client.with_opts(signer, opts)
# cli.add_relay("wss://relay.nostr.band") # cli.add_relay("wss://relay.nostr.band")
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -94,19 +92,19 @@ class DiscoverReports(DVMTaskInterface):
# if we don't add users, e.g. by a wot, we check all our followers. # if we don't add users, e.g. by a wot, we check all our followers.
if len(pubkeys) == 0: if len(pubkeys) == 0:
followers_filter = Filter().author(PublicKey.parse(options["sender"])).kind(Kind(3)) followers_filter = Filter().author(PublicKey.parse(options["sender"])).kind(Kind(3))
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
result_list = [] result_list = []
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
print(len(best_entry.tags())) print(len(best_entry.tags().to_vec()))
print(best_entry.created_at().as_secs()) print(best_entry.created_at().as_secs())
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = PublicKey.parse(tag.as_vec()[1]) following = PublicKey.parse(tag.as_vec()[1])
pubkeys.append(following) pubkeys.append(following)
@@ -115,20 +113,20 @@ class DiscoverReports(DVMTaskInterface):
options["since_days"]) # TODO make this an option, 180 days for now options["since_days"]) # TODO make this an option, 180 days for now
since = Timestamp.from_secs(ago) since = Timestamp.from_secs(ago)
kind1984_filter = Filter().authors(pubkeys).kind(Kind(1984)).since(since) kind1984_filter = Filter().authors(pubkeys).kind(Kind(1984)).since(since)
reports = await cli.get_events_of([kind1984_filter], relay_timeout) reports = await cli.fetch_events([kind1984_filter], relay_timeout)
bad_actors = [] bad_actors = []
ns.dic = {} ns.dic = {}
reasons = ["spam", "illegal", "impersonation"] reasons = ["spam", "illegal", "impersonation"]
# init # init
for report in reports: for report in reports.to_vec():
for tag in report.tags(): for tag in report.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
ns.dic[tag.as_vec()[1]] = 0 ns.dic[tag.as_vec()[1]] = 0
for report in reports: for report in reports.to_vec():
# print(report.as_json()) # print(report.as_json())
for tag in report.tags(): for tag in report.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
if len(tag.as_vec()) > 2 and tag.as_vec()[2] in reasons or len(tag.as_vec()) <= 2: if len(tag.as_vec()) > 2 and tag.as_vec()[2] in reasons or len(tag.as_vec()) <= 2:
ns.dic[tag.as_vec()[1]] += 1 ns.dic[tag.as_vec()[1]] += 1
@@ -153,7 +151,7 @@ class DiscoverReports(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -48,7 +48,7 @@ class DiscoverInactiveFollows(DVMTaskInterface):
user = event.author().to_hex() user = event.author().to_hex()
since_days = 90 since_days = 90
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'param': if tag.as_vec()[0] == 'param':
param = tag.as_vec()[1] param = tag.as_vec()[1]
if param == "user": # check for param type if param == "user": # check for param type
@@ -70,20 +70,15 @@ class DiscoverInactiveFollows(DVMTaskInterface):
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
# relaylimits = RelayLimits().event_max_num_tags(max_num_tags=10000) # relaylimits = RelayLimits().event_max_num_tags(max_num_tags=10000)
# relaylimits.event_max_size(None) # relaylimits.event_max_size(None)
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (Options().relay_limits(relaylimits))
Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT))).relay_limits(
relaylimits)
cli = Client.with_opts(signer, opts) cli = Client.with_opts(keys, opts)
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
ropts = RelayOptions().ping(False)
await cli.add_relay("wss://nostr.band") await cli.add_relay("wss://nostr.band")
await cli.connect() await cli.connect()
@@ -92,27 +87,27 @@ class DiscoverInactiveFollows(DVMTaskInterface):
step = 20 step = 20
followers_filter = Filter().author(PublicKey.parse(options["user"])).kind(Kind(3)) followers_filter = Filter().author(PublicKey.parse(options["user"])).kind(Kind(3))
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
result_list = [] result_list = []
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
print(len(best_entry.tags())) print(len(best_entry.tags().to_vec()))
print(best_entry.created_at().as_secs()) print(best_entry.created_at().as_secs())
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
print(best_entry.as_json()) print(best_entry.as_json())
print(len(best_entry.tags())) print(len(best_entry.tags().to_vec()))
print(best_entry.created_at().as_secs()) print(best_entry.created_at().as_secs())
print(Timestamp.now().as_secs()) print(Timestamp.now().as_secs())
followings = [] followings = []
ns.dic = {} ns.dic = {}
tagcount = 0 tagcount = 0
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
tagcount += 1 tagcount += 1
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = tag.as_vec()[1] following = tag.as_vec()[1]
@@ -128,10 +123,7 @@ class DiscoverInactiveFollows(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
keys = Keys.parse(self.dvm_config.PRIVATE_KEY) keys = Keys.parse(self.dvm_config.PRIVATE_KEY)
opts = Options().wait_for_send(True).send_timeout( cli = Client(keys)
timedelta(seconds=5)).skip_disconnected_relays(True)
signer = NostrSigner.keys(keys)
cli = Client.with_opts(signer, opts)
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
await cli.connect() await cli.connect()
@@ -140,8 +132,8 @@ class DiscoverInactiveFollows(DVMTaskInterface):
for i in range(i, i + st): for i in range(i, i + st):
filter1 = Filter().author(PublicKey.from_hex(users[i])).since(notactivesince).limit(1) filter1 = Filter().author(PublicKey.from_hex(users[i])).since(notactivesince).limit(1)
filters.append(filter1) filters.append(filter1)
event_from_authors = await cli.get_events_of(filters, relay_timeout_long) event_from_authors = await cli.fetch_events(filters, relay_timeout_long)
for author in event_from_authors: for author in event_from_authors.to_vec():
instance.dic[author.author().to_hex()] = "True" instance.dic[author.author().to_hex()] = "True"
print(str(i) + "/" + str(len(users))) print(str(i) + "/" + str(len(users)))
await cli.shutdown() await cli.shutdown()
@@ -179,7 +171,7 @@ class DiscoverInactiveFollows(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -46,7 +46,7 @@ class DiscoverNonFollowers(DVMTaskInterface):
# default values # default values
user = event.author().to_hex() user = event.author().to_hex()
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'param': if tag.as_vec()[0] == 'param':
param = tag.as_vec()[1] param = tag.as_vec()[1]
if param == "user": # check for param type if param == "user": # check for param type
@@ -64,17 +64,15 @@ class DiscoverNonFollowers(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (
Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)).relay_limits( Options().relay_limits(
relaylimits)) relaylimits))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) cli = Client.with_opts(keys, opts)
cli = Client.with_opts(signer, opts)
# cli.add_relay("wss://relay.nostr.band") # cli.add_relay("wss://relay.nostr.band")
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
# add nostr band, too. # add nostr band, too.
ropts = RelayOptions().ping(False)
await cli.add_relay("wss://nostr.band") await cli.add_relay("wss://nostr.band")
await cli.connect() await cli.connect()
@@ -83,13 +81,13 @@ class DiscoverNonFollowers(DVMTaskInterface):
step = 20 step = 20
followers_filter = Filter().author(PublicKey.from_hex(options["user"])).kind(Kind(3)) followers_filter = Filter().author(PublicKey.from_hex(options["user"])).kind(Kind(3))
followers = await cli.get_events_of([followers_filter], relay_timeout) followers = await cli.fetch_events([followers_filter], relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
result_list = [] result_list = []
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
@@ -97,7 +95,7 @@ class DiscoverNonFollowers(DVMTaskInterface):
print(best_entry.as_json()) print(best_entry.as_json())
followings = [] followings = []
ns.dic = {} ns.dic = {}
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
following = tag.as_vec()[1] following = tag.as_vec()[1]
followings.append(following) followings.append(following)
@@ -106,12 +104,8 @@ class DiscoverNonFollowers(DVMTaskInterface):
async def scanList(users, instance, i, st): async def scanList(users, instance, i, st):
from nostr_sdk import Filter from nostr_sdk import Filter
keys = Keys.parse(self.dvm_config.PRIVATE_KEY) keys = Keys.parse(self.dvm_config.PRIVATE_KEY)
opts = Options().wait_for_send(True).send_timeout( cli = Client(keys)
timedelta(seconds=5)).skip_disconnected_relays(True)
signer = NostrSigner.keys(keys)
cli = Client.with_opts(signer, opts)
for relay in self.dvm_config.RELAY_LIST: for relay in self.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
await cli.connect() await cli.connect()
@@ -120,19 +114,19 @@ class DiscoverNonFollowers(DVMTaskInterface):
filters = [] filters = []
filter1 = Filter().author(PublicKey.from_hex(users[i])).kind(Kind(3)) filter1 = Filter().author(PublicKey.from_hex(users[i])).kind(Kind(3))
filters.append(filter1) filters.append(filter1)
followers = await cli.get_events_of(filters, relay_timeout) followers = await cli.fetch_events(filters, relay_timeout)
if len(followers) > 0: if len(followers.to_vec()) > 0:
result_list = [] result_list = []
newest = 0 newest = 0
best_entry = followers[0] best_entry = followers.to_vec()[0]
for entry in followers: for entry in followers.to_vec():
if entry.created_at().as_secs() > newest: if entry.created_at().as_secs() > newest:
newest = entry.created_at().as_secs() newest = entry.created_at().as_secs()
best_entry = entry best_entry = entry
foundfollower = False foundfollower = False
for tag in best_entry.tags(): for tag in best_entry.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
if len(tag.as_vec()) > 1: if len(tag.as_vec()) > 1:
if tag.as_vec()[1] == options["user"]: if tag.as_vec()[1] == options["user"]:
@@ -180,7 +174,7 @@ class DiscoverNonFollowers(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -52,7 +52,7 @@ class TrendingNotesGleasonator(DVMTaskInterface):
request_form = {"jobID": event.id().to_hex()} request_form = {"jobID": event.id().to_hex()}
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -70,11 +70,9 @@ class TrendingNotesGleasonator(DVMTaskInterface):
async def process(self, request_form): async def process(self, request_form):
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) cli = Client(keys)
cli = Client.with_opts(signer, opts)
await cli.add_relay(options["relay"]) await cli.add_relay(options["relay"])
await cli.connect() await cli.connect()
@@ -84,13 +82,13 @@ class TrendingNotesGleasonator(DVMTaskInterface):
notes_filter = Filter().authors(authors).kind(Kind(1985)).custom_tag(SingleLetterTag.lowercase(Alphabet.L), notes_filter = Filter().authors(authors).kind(Kind(1985)).custom_tag(SingleLetterTag.lowercase(Alphabet.L),
ltags) ltags)
events = await cli.get_events_of([notes_filter], relay_timeout_long) events = await cli.fetch_events([notes_filter], relay_timeout_long)
result_list = [] result_list = []
if len(events) > 0: if len(events.to_vec()) > 0:
event = events[0] event = events.to_vec()[0]
print(event) print(event)
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":
e_tag = Tag.parse(["e", tag.as_vec()[1], tag.as_vec()[2]]) e_tag = Tag.parse(["e", tag.as_vec()[1], tag.as_vec()[2]])
result_list.append(e_tag.as_vec()) result_list.append(e_tag.as_vec())
@@ -105,7 +103,7 @@ class TrendingNotesGleasonator(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -52,7 +52,7 @@ class TrendingNotesNostrBand(DVMTaskInterface):
request_form = {"jobID": event.id().to_hex()} request_form = {"jobID": event.id().to_hex()}
max_results = 200 max_results = 200
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -95,7 +95,7 @@ class TrendingNotesNostrBand(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type

View File

@@ -38,7 +38,7 @@ class GenericDVM(DVMTaskInterface):
print(self.dvm_config.PRIVATE_KEY) print(self.dvm_config.PRIVATE_KEY)
prompt = "" prompt = ""
user = event.author().to_hex() user = event.author().to_hex()
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -59,7 +59,7 @@ class ImageGenerationDALLE(DVMTaskInterface):
model = "dall-e-3" model = "dall-e-3"
quality = "standard" quality = "standard"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -0,0 +1,171 @@
import json
import os
from io import BytesIO
import requests
from PIL import Image
from nostr_sdk import Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip88_utils import NIP88Config
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag
from nostr_dvm.utils.output_utils import upload_media_to_hoster
from nostr_dvm.utils.zap_utils import get_price_per_sat
"""
This File contains a Module to generate an Image on replicate and receive results back.
Accepted Inputs: Prompt (text)
Outputs: An url to an Image
Params:
"""
class ImageGenerationReplicate(DVMTaskInterface):
KIND: Kind = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
TASK: str = "text-to-image"
FIX_COST: float = 120
dependencies = [("nostr-dvm", "nostr-dvm"),
("replicate", "replicate")]
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None,
options=None, task=None):
super().__init__(name, dvm_config, nip89config, nip88config, admin_config, options, task)
if options is not None:
self.model = options["model"]
else:
self.model = None
async def init_dvm(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None, options=None):
dvm_config.SCRIPT = os.path.abspath(__file__)
async def is_input_supported(self, tags, client=None, dvm_config=None):
for tag in tags:
if tag.as_vec()[0] == 'i':
input_value = tag.as_vec()[1]
input_type = tag.as_vec()[2]
if input_type != "text":
return False
elif tag.as_vec()[0] == 'output':
output = tag.as_vec()[1]
if (output == "" or
not (output == "image/png" or "image/jpg"
or output == "image/png;format=url" or output == "image/jpg;format=url")):
print("Output format not supported, skipping..")
return False
return True
async def create_request_from_nostr_event(self, event, client=None, dvm_config=None):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = ""
width = "1"
height = "1"
if self.model is None:
self.model = "stability-ai/stable-diffusion-3",
for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2]
if input_type == "text":
prompt = tag.as_vec()[1]
elif tag.as_vec()[0] == 'param':
print("Param: " + tag.as_vec()[1] + ": " + tag.as_vec()[2])
if tag.as_vec()[1] == "size":
if len(tag.as_vec()) > 3:
width = (tag.as_vec()[2])
height = (tag.as_vec()[3])
elif len(tag.as_vec()) == 3:
split = tag.as_vec()[2].split(":")
if len(split) > 1:
width = split[0]
height = split[1]
elif tag.as_vec()[1] == "model":
model = tag.as_vec()[2]
elif tag.as_vec()[1] == "quality":
quality = tag.as_vec()[2]
options = {
"prompt": prompt,
"model": self.model,
"aspect_ratio": width + ":" + height,
"number": 1
}
request_form['options'] = json.dumps(options)
return request_form
async def process(self, request_form):
try:
options = self.set_options(request_form)
import replicate
#width = int(options["size"].split("x")[0])
#height = int(options["size"].split("x")[1])
output = replicate.run(
options["model"],
input={"prompt": options["prompt"],
"cfg": 3.5,
"steps": 28,
"prompt_upsampling": True,
"aspect_ratio": options["aspect_ratio"],
"output_format": "jpg",
"output_quality": 90,
"negative_prompt": "",
"prompt_strength": 0.85,
"safety_tolerance": 5
}
)
print(output[0])
response = requests.get(output[0])
image = Image.open(BytesIO(response.content)).convert("RGB")
image.save("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:
print("Error in Module")
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = build_default_config(identifier)
admin_config.LUD16 = dvm_config.LN_ADDRESS
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use Replicate to run StableDiffusion 3",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"ratio": {
"required": False,
"values": ["1:1" , "3:2", "4:5"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationReplicate(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
process_venv(ImageGenerationReplicate)

View File

@@ -0,0 +1,166 @@
import json
import os
from io import BytesIO
import requests
from PIL import Image
from nostr_sdk import Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip88_utils import NIP88Config
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag
from nostr_dvm.utils.output_utils import upload_media_to_hoster
from nostr_dvm.utils.zap_utils import get_price_per_sat
"""
This File contains a Module to generate an Image on replicate and receive results back.
Accepted Inputs: Prompt (text)
Outputs: An url to an Image
Params:
"""
class ImageGenerationReplicateFluxPro(DVMTaskInterface):
KIND: Kind = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
TASK: str = "text-to-image"
FIX_COST: float = 120
dependencies = [("nostr-dvm", "nostr-dvm"),
("replicate", "replicate")]
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None,
options=None, task=None):
super().__init__(name, dvm_config, nip89config, nip88config, admin_config, options, task)
if options is not None:
self.model = options["model"]
else:
self.model = None
async def init_dvm(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None, options=None):
dvm_config.SCRIPT = os.path.abspath(__file__)
async def is_input_supported(self, tags, client=None, dvm_config=None):
for tag in tags:
if tag.as_vec()[0] == 'i':
input_value = tag.as_vec()[1]
input_type = tag.as_vec()[2]
if input_type != "text":
return False
elif tag.as_vec()[0] == 'output':
output = tag.as_vec()[1]
if (output == "" or
not (output == "image/png" or "image/jpg"
or output == "image/png;format=url" or output == "image/jpg;format=url")):
print("Output format not supported, skipping..")
return False
return True
async def create_request_from_nostr_event(self, event, client=None, dvm_config=None):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = ""
width = "1024"
height = "1024"
for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2]
if input_type == "text":
prompt = tag.as_vec()[1]
elif tag.as_vec()[0] == 'param':
print("Param: " + tag.as_vec()[1] + ": " + tag.as_vec()[2])
if tag.as_vec()[1] == "size":
if len(tag.as_vec()) > 3:
width = (tag.as_vec()[2])
height = (tag.as_vec()[3])
elif len(tag.as_vec()) == 3:
split = tag.as_vec()[2].split(":")
if len(split) > 1:
width = split[0]
height = split[1]
elif tag.as_vec()[1] == "model":
model = tag.as_vec()[2]
elif tag.as_vec()[1] == "quality":
quality = tag.as_vec()[2]
options = {
"prompt": prompt,
"size": width + "x" + height,
"number": 1
}
request_form['options'] = json.dumps(options)
return request_form
async def process(self, request_form):
try:
options = self.set_options(request_form)
import replicate
#width = int(options["size"].split("x")[0])
#height = int(options["size"].split("x")[1])
output = replicate.run(
"black-forest-labs/flux-1.1-pro",
input={"prompt": options["prompt"],
"aspect_ratio": "5:4",
"output_format": "jpg",
"output_quality": 80,
"safety_tolerance": 2,
"prompt_upsampling": True
}
)
print(output)
response = requests.get(output)
image = Image.open(BytesIO(response.content)).convert("RGB")
image.save("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:
print("Error in Module")
raise Exception(e)
def write_text(data: str, path: str):
with open(path, 'w') as file:
file.write(data)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = build_default_config(identifier)
admin_config.LUD16 = dvm_config.LN_ADDRESS
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use Replicate to run FluxPro",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"ratio": {
"required": False,
"values": ["1:1" , "3:2", "4:5"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationReplicateFluxPro(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
process_venv(ImageGenerationReplicateFluxPro)

View File

@@ -0,0 +1,165 @@
import json
import os
from io import BytesIO
import requests
from PIL import Image
from nostr_sdk import Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip88_utils import NIP88Config
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag
from nostr_dvm.utils.output_utils import upload_media_to_hoster
from nostr_dvm.utils.zap_utils import get_price_per_sat
"""
This File contains a Module to generate an Image on replicate and receive results back.
Accepted Inputs: Prompt (text)
Outputs: An url to an Image
Params:
"""
class ImageGenerationReplicateRecraft(DVMTaskInterface):
KIND: Kind = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
TASK: str = "text-to-image"
FIX_COST: float = 120
dependencies = [("nostr-dvm", "nostr-dvm"),
("replicate", "replicate")]
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None,
options=None, task=None):
super().__init__(name, dvm_config, nip89config, nip88config, admin_config, options, task)
if options is not None:
self.model = options["model"]
else:
self.model = None
async def init_dvm(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None, options=None):
dvm_config.SCRIPT = os.path.abspath(__file__)
async def is_input_supported(self, tags, client=None, dvm_config=None):
for tag in tags:
if tag.as_vec()[0] == 'i':
input_value = tag.as_vec()[1]
input_type = tag.as_vec()[2]
if input_type != "text":
return False
elif tag.as_vec()[0] == 'output':
output = tag.as_vec()[1]
if (output == "" or
not (output == "image/png" or "image/jpg"
or output == "image/png;format=url" or output == "image/jpg;format=url")):
print("Output format not supported, skipping..")
return False
return True
async def create_request_from_nostr_event(self, event, client=None, dvm_config=None):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = ""
width = "1024"
height = "1024"
if self.model is None:
self.model = "stability-ai/stable-diffusion-3",
for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2]
if input_type == "text":
prompt = tag.as_vec()[1]
elif tag.as_vec()[0] == 'param':
print("Param: " + tag.as_vec()[1] + ": " + tag.as_vec()[2])
if tag.as_vec()[1] == "size":
if len(tag.as_vec()) > 3:
width = (tag.as_vec()[2])
height = (tag.as_vec()[3])
elif len(tag.as_vec()) == 3:
split = tag.as_vec()[2].split(":")
if len(split) > 1:
width = split[0]
height = split[1]
elif tag.as_vec()[1] == "model":
model = tag.as_vec()[2]
elif tag.as_vec()[1] == "quality":
quality = tag.as_vec()[2]
options = {
"prompt": prompt,
"size": width + "x" + height,
"number": 1
}
request_form['options'] = json.dumps(options)
return request_form
async def process(self, request_form):
try:
options = self.set_options(request_form)
import replicate
#width = int(options["size"].split("x")[0])
#height = int(options["size"].split("x")[1])
output = replicate.run(
"recraft-ai/recraft-v3",
input={"prompt": options["prompt"],
"size": options["size"],
"style": "any",
}
)
print(output)
response = requests.get(output)
image = Image.open(BytesIO(response.content)).convert("RGB")
image.save("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:
print("Error in Module")
raise Exception(e)
def write_text(data: str, path: str):
with open(path, 'w') as file:
file.write(data)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = build_default_config(identifier)
admin_config.LUD16 = dvm_config.LN_ADDRESS
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use Replicate to run Recraft",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"ratio": {
"required": False,
"values": ["1:1" , "3:2", "4:5"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationReplicateRecraft(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
process_venv(ImageGenerationReplicateRecraft)

View File

@@ -59,7 +59,7 @@ class ImageGenerationReplicateSDXL(DVMTaskInterface):
width = "1024" width = "1024"
height = "1024" height = "1024"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -63,7 +63,7 @@ class ImageGenerationMLX(DVMTaskInterface):
width = "1024" width = "1024"
height = "1024" height = "1024"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -81,7 +81,7 @@ class ImageGenerationSD35(DVMTaskInterface):
lora_weight = "" lora_weight = ""
strength = "" strength = ""
guidance_scale = "" guidance_scale = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -71,7 +71,7 @@ class ImageGenerationSDXL(DVMTaskInterface):
lora_weight = "" lora_weight = ""
strength = "" strength = ""
guidance_scale = "" guidance_scale = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -87,7 +87,7 @@ class ImageGenerationSDXLIMG2IMG(DVMTaskInterface):
guidance_scale = float(self.options['guidance_scale']) guidance_scale = float(self.options['guidance_scale'])
else: else:
guidance_scale = 11.0 guidance_scale = 11.0
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -51,7 +51,7 @@ class ImageInterrogator(DVMTaskInterface):
method = "prompt" method = "prompt"
mode = "best" mode = "best"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -50,7 +50,7 @@ class ImageUpscale(DVMTaskInterface):
url = "" url = ""
out_scale = 4 out_scale = 4
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -2,29 +2,10 @@ import csv
import json import json
import os import os
import time import time
from datetime import timedelta
import networkx as nx import networkx as nx
from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip88_utils import NIP88Config, check_and_set_d_tag_nip88, check_and_set_tiereventid_nip88
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag, create_amount_tag
from nostr_dvm.utils.output_utils import post_process_list_to_users
from nostr_dvm.utils.wot_utils import build_wot_network, save_network, load_network, convert_index_to_hex
import csv
import json
import os
import time
from datetime import timedelta
import networkx as nx
from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.admin_utils import AdminConfig
@@ -102,7 +83,7 @@ class DiscoverPeopleMyWOT(DVMTaskInterface):
hops = 2 hops = 2
dunbar = 1000 dunbar = 1000
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -198,7 +179,7 @@ class DiscoverPeopleMyWOT(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -221,12 +202,10 @@ class DiscoverPeopleMyWOT(DVMTaskInterface):
async def sync_db(self): async def sync_db(self):
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -242,8 +221,8 @@ class DiscoverPeopleMyWOT(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()
@@ -272,14 +251,14 @@ async def analyse_users(user_ids=None, dunbar=100000000):
if len(followers) > 0: if len(followers) > 0:
for follower in followers: for follower in followers:
frens = [] frens = []
if len(follower.tags()) < dunbar: if len(follower.tags().to_vec()) < dunbar:
for tag in follower.tags(): for tag in follower.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
frens.append(tag.as_vec()[1]) frens.append(tag.as_vec()[1])
allfriends.append(Friend(follower.author().to_hex(), frens)) allfriends.append(Friend(follower.author().to_hex(), frens))
else: else:
print("Skipping friend: " + follower.author().to_hex() + "Following: " + str( print("Skipping friend: " + follower.author().to_hex() + "Following: " + str(
len(follower.tags())) + " npubs") len(follower.tags().to_vec())) + " npubs")
return allfriends return allfriends
else: else:

View File

@@ -7,7 +7,7 @@ from datetime import timedelta
import networkx as nx import networkx as nx
import pandas as pd import pandas as pd
from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, init_logger, LogLevel, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.admin_utils import AdminConfig
@@ -84,7 +84,7 @@ class DiscoverPeopleWOT(DVMTaskInterface):
hops = 2 hops = 2
dunbar = 1000 dunbar = 1000
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param': elif tag.as_vec()[0] == 'param':
@@ -185,7 +185,7 @@ class DiscoverPeopleWOT(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -207,13 +207,10 @@ class DiscoverPeopleWOT(DVMTaskInterface):
return 1 return 1
async def sync_db(self): async def sync_db(self):
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
@@ -229,8 +226,8 @@ class DiscoverPeopleWOT(DVMTaskInterface):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str( print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..") self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
await cli.database().delete(Filter().until(Timestamp.from_secs( await cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full. Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
await cli.shutdown() await cli.shutdown()
@@ -259,14 +256,14 @@ async def analyse_users(user_ids=None, dunbar=100000000):
if len(followers) > 0: if len(followers) > 0:
for follower in followers: for follower in followers:
frens = [] frens = []
if len(follower.tags()) < dunbar: if len(follower.tags().to_vec()) < dunbar:
for tag in follower.tags(): for tag in follower.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
frens.append(tag.as_vec()[1]) frens.append(tag.as_vec()[1])
allfriends.append(Friend(follower.author().to_hex(), frens)) allfriends.append(Friend(follower.author().to_hex(), frens))
else: else:
print("Skipping friend: " + follower.author().to_hex() + "Following: " + str( print("Skipping friend: " + follower.author().to_hex() + "Following: " + str(
len(follower.tags())) + " npubs") len(follower.tags().to_vec())) + " npubs")
return allfriends return allfriends
else: else:

View File

@@ -3,7 +3,7 @@ import os
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \ from nostr_sdk import Timestamp, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, Kind ClientBuilder, Filter, SyncOptions, SyncDirection, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.admin_utils import AdminConfig
@@ -57,7 +57,7 @@ class SearchUser(DVMTaskInterface):
search = "" search = ""
max_results = 100 max_results = 100
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":
@@ -78,13 +78,10 @@ class SearchUser(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
options = self.set_options(request_form) options = self.set_options(request_form)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(keys).build()
await cli.add_relay(self.relay) await cli.add_relay(self.relay)
# cli.add_relay("wss://atl.purplerelay.com") # cli.add_relay("wss://atl.purplerelay.com")
@@ -120,7 +117,7 @@ class SearchUser(DVMTaskInterface):
async def post_process(self, result, event): async def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested""" """Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'output': if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1] format = tag.as_vec()[1]
if format == "text/plain": # check for output type if format == "text/plain": # check for output type
@@ -140,12 +137,10 @@ class SearchUser(DVMTaskInterface):
return 1 return 1
async def sync_db(self): async def sync_db(self):
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
await cli.add_relay(self.relay) await cli.add_relay(self.relay)
await cli.connect() await cli.connect()
@@ -154,8 +149,8 @@ class SearchUser(DVMTaskInterface):
# filter = Filter().author(keys.public_key()) # filter = Filter().author(keys.public_key())
print("Syncing Profile Database.. this might take a while..") print("Syncing Profile Database.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
print("Done Syncing Profile Database.") print("Done Syncing Profile Database.")
await cli.shutdown() await cli.shutdown()

View File

@@ -48,7 +48,7 @@ class SummarizationDuckDuck(DVMTaskInterface):
collect_events = [] collect_events = []
nostr_mode = True nostr_mode = True
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -46,7 +46,7 @@ class TextSummarizationHuggingChat(DVMTaskInterface):
prompt = "" prompt = ""
collect_events = [] collect_events = []
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -48,7 +48,7 @@ class SummarizationUnleashedChat(DVMTaskInterface):
collect_events = [] collect_events = []
nostr_mode = True nostr_mode = True
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -59,7 +59,7 @@ class SpeechToTextGoogle(DVMTaskInterface):
media_format = "audio/wav" media_format = "audio/wav"
language = "en-US" language = "en-US"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -49,7 +49,7 @@ class TextExtractionPDF(DVMTaskInterface):
input_content = "" input_content = ""
url = "" url = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
input_content = tag.as_vec()[1] input_content = tag.as_vec()[1]

View File

@@ -68,7 +68,7 @@ class SpeechToTextWhisperX(DVMTaskInterface):
end_time = 0 end_time = 0
media_format = "audio/mp3" media_format = "audio/mp3"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -43,7 +43,7 @@ class TextGenerationHuggingChat(DVMTaskInterface):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")} request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = "" prompt = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -51,7 +51,7 @@ class TextGenerationLLMLite(DVMTaskInterface):
else: else:
server = "http://localhost:11434" # default ollama server. This will only be used for ollama models. server = "http://localhost:11434" # default ollama server. This will only be used for ollama models.
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -44,7 +44,7 @@ class TextGenerationUnleashedChat(DVMTaskInterface):
prompt = "" prompt = ""
nostr_mode = True nostr_mode = True
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "text": if input_type == "text":

View File

@@ -70,7 +70,7 @@ class TextToSpeech(DVMTaskInterface):
language = "en" language = "en"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "event": if input_type == "event":

View File

@@ -47,7 +47,7 @@ class TranslationGoogle(DVMTaskInterface):
text = "" text = ""
translation_lang = "en" translation_lang = "en"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "event": if input_type == "event":

View File

@@ -48,7 +48,7 @@ class TranslationLibre(DVMTaskInterface):
text = "" text = ""
translation_lang = "en" translation_lang = "en"
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "event": if input_type == "event":

View File

@@ -58,7 +58,7 @@ class VideoGenerationReplicateSVD(DVMTaskInterface):
motion_bucket_id = 127 # Increase overall motion in the generated video motion_bucket_id = 127 # Increase overall motion in the generated video
cond_aug = 0.02 # Amount of noise to add to input image cond_aug = 0.02 # Amount of noise to add to input image
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -47,7 +47,7 @@ class VideoGenerationSVD(DVMTaskInterface):
frames = 7 # 25 frames = 7 # 25
model = "stabilityai/stable-video-diffusion-img2vid-xt" # ,stabilityai/stable-video-diffusion-img2vid model = "stabilityai/stable-video-diffusion-img2vid-xt" # ,stabilityai/stable-video-diffusion-img2vid
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
if input_type == "url": if input_type == "url":

View File

@@ -13,13 +13,13 @@ from nostr_dvm.utils.nostr_utils import get_event_by_id, get_referenced_event_by
async def get_task(event, client, dvm_config): async def get_task(event, client, dvm_config):
try: try:
if event.kind() == EventDefinitions.KIND_NIP90_GENERIC: # use this for events that have no id yet, inclufr j tag if event.kind() == EventDefinitions.KIND_NIP90_GENERIC: # use this for events that have no id yet, inclufr j tag
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'j': if tag.as_vec()[0] == 'j':
return tag.as_vec()[1] return tag.as_vec()[1]
else: else:
return "unknown job: " + event.as_json() return "unknown job: " + event.as_json()
elif event.kind() == EventDefinitions.KIND_DM: # dm elif event.kind() == EventDefinitions.KIND_DM: # dm
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'j': if tag.as_vec()[0] == 'j':
return tag.as_vec()[1] return tag.as_vec()[1]
else: else:
@@ -27,7 +27,7 @@ async def get_task(event, client, dvm_config):
# This looks a bit more complicated, but we do several tasks for text-extraction in the future # This looks a bit more complicated, but we do several tasks for text-extraction in the future
elif event.kind() == EventDefinitions.KIND_NIP90_EXTRACT_TEXT: elif event.kind() == EventDefinitions.KIND_NIP90_EXTRACT_TEXT:
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "i": if tag.as_vec()[0] == "i":
if tag.as_vec()[2] == "url": if tag.as_vec()[2] == "url":
file_type = check_url_is_readable(tag.as_vec()[1]) file_type = check_url_is_readable(tag.as_vec()[1])
@@ -44,7 +44,7 @@ async def get_task(event, client, dvm_config):
evt = await get_event_by_id(tag.as_vec()[1], client=client, config=dvm_config) evt = await get_event_by_id(tag.as_vec()[1], client=client, config=dvm_config)
if evt is not None: if evt is not None:
if evt.kind() == 1063: if evt.kind() == 1063:
for tg in evt.tags(): for tg in evt.tags().to_vec():
if tg.as_vec()[0] == 'url': if tg.as_vec()[0] == 'url':
file_type = check_url_is_readable(tg.as_vec()[1]) file_type = check_url_is_readable(tg.as_vec()[1])
if file_type == "pdf": if file_type == "pdf":
@@ -60,7 +60,7 @@ async def get_task(event, client, dvm_config):
elif event.kind() == EventDefinitions.KIND_NIP90_GENERATE_IMAGE: elif event.kind() == EventDefinitions.KIND_NIP90_GENERATE_IMAGE:
has_image_tag = False has_image_tag = False
has_text_tag = False has_text_tag = False
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "i": if tag.as_vec()[0] == "i":
if tag.as_vec()[2] == "url": if tag.as_vec()[2] == "url":
file_type = check_url_is_readable(tag.as_vec()[1]) file_type = check_url_is_readable(tag.as_vec()[1])
@@ -130,7 +130,7 @@ async def check_task_is_supported(event: Event, client, config=None):
try: try:
dvm_config = config dvm_config = config
# Check for generic issues, event maformed, referenced event not found etc.. # Check for generic issues, event maformed, referenced event not found etc..
if not is_input_supported_generic(event.tags(), client, dvm_config): if not is_input_supported_generic(event.tags().to_vec(), client, dvm_config):
return False, "" return False, ""
# See if current dvm supports the task # See if current dvm supports the task
@@ -140,7 +140,7 @@ async def check_task_is_supported(event: Event, client, config=None):
# See if current dvm can handle input for given task # See if current dvm can handle input for given task
for dvm in dvm_config.SUPPORTED_DVMS: for dvm in dvm_config.SUPPORTED_DVMS:
if dvm.TASK == task: if dvm.TASK == task:
if not await dvm.is_input_supported(event.tags(), client, config): if not await dvm.is_input_supported(event.tags().to_vec(), client, config):
return False, task return False, task
return True, task return True, task

View File

@@ -252,12 +252,12 @@ async def fetch_user_metadata(npub, client):
pk = PublicKey.parse(npub) pk = PublicKey.parse(npub)
print(f"\nGetting profile metadata for {pk.to_bech32()}...") print(f"\nGetting profile metadata for {pk.to_bech32()}...")
profile_filter = Filter().kind(Kind(0)).author(pk).limit(1) profile_filter = Filter().kind(Kind(0)).author(pk).limit(1)
events = await client.get_events_of([profile_filter], relay_timeout) events = await client.fetch_events([profile_filter], relay_timeout)
if len(events) > 0: if len(events.to_vec()) > 0:
latest_entry = events[0] latest_entry = events.to_vec()[0]
latest_time = 0 latest_time = 0
try: try:
for entry in events: for entry in events.to_vec():
if entry.created_at().as_secs() > latest_time: if entry.created_at().as_secs() > latest_time:
latest_time = entry.created_at().as_secs() latest_time = entry.created_at().as_secs()
latest_entry = entry latest_entry = entry

View File

@@ -1,7 +1,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
from nostr_sdk import Event, Kind, EventSource from nostr_sdk import Event, Kind
class EventDefinitions: class EventDefinitions:
@@ -106,5 +106,5 @@ class InvoiceToWatch:
expires: int expires: int
relay_timeout = EventSource.relays(timedelta(seconds=5)) relay_timeout = timedelta(seconds=5)
relay_timeout_long = EventSource.relays(timedelta(seconds=10)) relay_timeout_long = timedelta(seconds=10)

View File

@@ -11,11 +11,8 @@ from nostr_dvm.utils.output_utils import PostProcessFunctionType
async def build_client(config): 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) keys = Keys.parse(config.PRIVATE_KEY)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client.with_opts(signer, opts)
for relay in config.RELAY_LIST: for relay in config.RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)

View File

@@ -7,8 +7,8 @@ from nostr_dvm.utils.print_utils import bcolors
async def gallery_announce_list(tags, dvm_config, client): async def gallery_announce_list(tags, dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK) keys = Keys.parse(dvm_config.NIP89.PK)
content = "" content = ""
event = EventBuilder(Kind(10011), content, tags).to_event(keys) event = EventBuilder(Kind(10011), content, tags).sign_with_keys(keys)
eventid = await send_event(event, client=client, dvm_config=dvm_config, blastr=True) eventid = await send_event(event, client=client, dvm_config=dvm_config)
print( print(
bcolors.BLUE + "[" + dvm_config.NIP89.NAME + "] Announced Gallery for " + dvm_config.NIP89.NAME + " (EventID: " + str( bcolors.BLUE + "[" + dvm_config.NIP89.NAME + "] Announced Gallery for " + dvm_config.NIP89.NAME + " (EventID: " + str(

View File

@@ -18,7 +18,7 @@ async def input_data_file_duration(event, dvm_config, client, start=0, end=0):
input_value = "" input_value = ""
input_type = "" input_type = ""
count = 0 count = 0
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'i': if tag.as_vec()[0] == 'i':
input_value = tag.as_vec()[1] input_value = tag.as_vec()[1]
input_type = tag.as_vec()[2] input_type = tag.as_vec()[2]
@@ -132,7 +132,7 @@ def check_nip94_event_for_media(evt, input_value, input_type):
input_type = "text" input_type = "text"
input_value = evt.content() input_value = evt.content()
if evt.kind() == 1063: if evt.kind() == 1063:
for tag in evt.tags(): for tag in evt.tags().to_vec():
if tag.as_vec()[0] == 'url': if tag.as_vec()[0] == 'url':
input_type = "url" input_type = "url"
input_value = tag.as_vec()[1] input_value = tag.as_vec()[1]

View File

@@ -15,7 +15,7 @@ async def announce_dm_relays(dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK) keys = Keys.parse(dvm_config.NIP89.PK)
content = "" content = ""
event = EventBuilder(Kind(10050), content, tags).to_event(keys) event = EventBuilder(Kind(10050), content, tags).sign_with_keys(keys)
eventid = await send_event(event, client=client, dvm_config=dvm_config) eventid = await send_event(event, client=client, dvm_config=dvm_config)
if (eventid is not None): if (eventid is not None):
print( print(
@@ -39,7 +39,7 @@ async def nip65_announce_relays(dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK) keys = Keys.parse(dvm_config.NIP89.PK)
content = "" content = ""
event = EventBuilder(EventDefinitions.KIND_RELAY_ANNOUNCEMENT, content, tags).to_event(keys) event = EventBuilder(EventDefinitions.KIND_RELAY_ANNOUNCEMENT, content, tags).sign_with_keys(keys)
eventid = await send_event(event, client=client, dvm_config=dvm_config) eventid = await send_event(event, client=client, dvm_config=dvm_config)
if (eventid is not None): if (eventid is not None):
print( print(

View File

@@ -36,14 +36,14 @@ def nip88_create_d_tag(name, pubkey, image):
async def fetch_nip88_parameters_for_deletion(keys, eventid, client, dvmconfig): async def fetch_nip88_parameters_for_deletion(keys, eventid, client, dvmconfig):
idfilter = Filter().id(EventId.from_hex(eventid)).limit(1) idfilter = Filter().id(EventId.from_hex(eventid)).limit(1)
nip88events = await client.get_events_of([idfilter], relay_timeout) nip88events = await client.fetch_events([idfilter], relay_timeout)
d_tag = "" d_tag = ""
if len(nip88events) == 0: if len(nip88events.to_vec()) == 0:
print("Event not found. Potentially gone.") print("Event not found. Potentially gone.")
for event in nip88events: for event in nip88events.to_vec():
print(event.as_json()) print(event.as_json())
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
d_tag = tag.as_vec()[1] d_tag = tag.as_vec()[1]
if d_tag == "": if d_tag == "":
@@ -59,14 +59,14 @@ async def fetch_nip88_parameters_for_deletion(keys, eventid, client, dvmconfig):
async def fetch_nip88_event(keys, eventid, client, dvmconfig): async def fetch_nip88_event(keys, eventid, client, dvmconfig):
idfilter = Filter().id(EventId.parse(eventid)).limit(1) idfilter = Filter().id(EventId.parse(eventid)).limit(1)
nip88events = await client.get_events_of([idfilter], relay_timeout) nip88events = await client.fetch_events([idfilter], relay_timeout)
d_tag = "" d_tag = ""
if len(nip88events) == 0: if len(nip88events.to_vec()) == 0:
print("Event not found. Potentially gone.") print("Event not found. Potentially gone.")
for event in nip88events: for event in nip88events.to_vec():
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
d_tag = tag.as_vec()[1] d_tag = tag.as_vec()[1]
if d_tag == "": if d_tag == "":
@@ -83,7 +83,7 @@ async def nip88_delete_announcement(eid: str, keys: Keys, dtag: str, client: Cli
e_tag = Tag.parse(["e", eid]) e_tag = Tag.parse(["e", eid])
a_tag = Tag.parse( a_tag = Tag.parse(
["a", str(EventDefinitions.KIND_NIP88_TIER_EVENT) + ":" + keys.public_key().to_hex() + ":" + dtag]) ["a", str(EventDefinitions.KIND_NIP88_TIER_EVENT) + ":" + keys.public_key().to_hex() + ":" + dtag])
event = EventBuilder(Kind(5), "", [e_tag, a_tag]).to_event(keys) event = EventBuilder(Kind(5), "", [e_tag, a_tag]).sign_with_keys(keys)
await send_event(event, client, config) await send_event(event, client, config)
@@ -99,11 +99,11 @@ async def nip88_has_active_subscription(user: PublicKey, tiereventdtag, client:
subscriptionfilter = Filter().kind(definitions.EventDefinitions.KIND_NIP88_PAYMENT_RECIPE).pubkey( subscriptionfilter = Filter().kind(definitions.EventDefinitions.KIND_NIP88_PAYMENT_RECIPE).pubkey(
PublicKey.parse(receiver_public_key_hex)).custom_tag(SingleLetterTag.uppercase(Alphabet.P), PublicKey.parse(receiver_public_key_hex)).custom_tag(SingleLetterTag.uppercase(Alphabet.P),
[user.to_hex()]).limit(1) [user.to_hex()]).limit(1)
evts = await client.get_events_of([subscriptionfilter], relay_timeout) evts = await client.fetch_events([subscriptionfilter], relay_timeout)
if len(evts) > 0: if len(evts.to_vec()) > 0:
print(evts[0].as_json()) print(evts.to_vec()[0].as_json())
matchesdtag = False matchesdtag = False
for tag in evts[0].tags(): for tag in evts.to_vec()[0].tags().to_vec():
if tag.as_vec()[0] == "valid": if tag.as_vec()[0] == "valid":
subscription_status["validUntil"] = int(tag.as_vec()[2]) subscription_status["validUntil"] = int(tag.as_vec()[2])
elif tag.as_vec()[0] == "e": elif tag.as_vec()[0] == "e":
@@ -120,9 +120,9 @@ async def nip88_has_active_subscription(user: PublicKey, tiereventdtag, client:
cancel_filter = Filter().kind(EventDefinitions.KIND_NIP88_STOP_SUBSCRIPTION_EVENT).author( cancel_filter = Filter().kind(EventDefinitions.KIND_NIP88_STOP_SUBSCRIPTION_EVENT).author(
user).pubkey(PublicKey.parse(receiver_public_key_hex)).event( user).pubkey(PublicKey.parse(receiver_public_key_hex)).event(
EventId.parse(subscription_status["subscriptionId"])).limit(1) EventId.parse(subscription_status["subscriptionId"])).limit(1)
cancel_events = await client.get_events_of([cancel_filter], relay_timeout) cancel_events = await client.fetch_events([cancel_filter], relay_timeout)
if len(cancel_events) > 0: if len(cancel_events.to_vec()) > 0:
if cancel_events[0].created_at().as_secs() > evts[0].created_at().as_secs(): if cancel_events.to_vec()[0].created_at().as_secs() > evts[0].created_at().as_secs():
subscription_status["expires"] = True subscription_status["expires"] = True
return subscription_status return subscription_status
@@ -176,7 +176,7 @@ async def nip88_announce_tier(dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK) keys = Keys.parse(dvm_config.NIP89.PK)
content = dvm_config.NIP88.CONTENT content = dvm_config.NIP88.CONTENT
event = EventBuilder(EventDefinitions.KIND_NIP88_TIER_EVENT, content, tags).to_event(keys) event = EventBuilder(EventDefinitions.KIND_NIP88_TIER_EVENT, content, tags).sign_with_keys(keys)
annotier_id = await send_event(event, client=client, dvm_config=dvm_config) annotier_id = await send_event(event, client=client, dvm_config=dvm_config)
if dvm_config.NIP89 is not None: if dvm_config.NIP89 is not None:

View File

@@ -29,7 +29,7 @@ async def nip89_announce_tasks(dvm_config, client):
d_tag = Tag.parse(["d", dvm_config.NIP89.DTAG]) d_tag = Tag.parse(["d", dvm_config.NIP89.DTAG])
keys = Keys.parse(dvm_config.NIP89.PK) keys = Keys.parse(dvm_config.NIP89.PK)
content = dvm_config.NIP89.CONTENT content = dvm_config.NIP89.CONTENT
event = EventBuilder(EventDefinitions.KIND_ANNOUNCEMENT, content, [k_tag, d_tag]).to_event(keys) event = EventBuilder(EventDefinitions.KIND_ANNOUNCEMENT, content, [k_tag, d_tag]).sign_with_keys(keys)
eventid = await send_event(event, client=client, dvm_config=dvm_config) eventid = await send_event(event, client=client, dvm_config=dvm_config)
print( print(
@@ -38,14 +38,14 @@ async def nip89_announce_tasks(dvm_config, client):
async def fetch_nip89_parameters_for_deletion(keys, eventid, client, dvmconfig, pow=False): async def fetch_nip89_parameters_for_deletion(keys, eventid, client, dvmconfig, pow=False):
idfilter = Filter().id(EventId.from_hex(eventid)).limit(1) idfilter = Filter().id(EventId.from_hex(eventid)).limit(1)
nip89events = await client.get_events_of([idfilter], relay_timeout) nip89events = await client.fetch_events([idfilter], relay_timeout)
d_tag = "" d_tag = ""
if len(nip89events) == 0: if len(nip89events.to_vec()) == 0:
print("Event not found. Potentially gone.") print("Event not found. Potentially gone.")
for event in nip89events: for event in nip89events.to_vec():
print(event.as_json()) print(event.as_json())
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
d_tag = tag.as_vec()[1] d_tag = tag.as_vec()[1]
if d_tag == "": if d_tag == "":
@@ -65,7 +65,7 @@ async def nip89_delete_announcement(eid: str, keys: Keys, dtag: str, client: Cli
e_tag = Tag.parse(["e", eid]) e_tag = Tag.parse(["e", eid])
a_tag = Tag.parse( a_tag = Tag.parse(
["a", str(EventDefinitions.KIND_ANNOUNCEMENT.as_u16()) + ":" + keys.public_key().to_hex() + ":" + dtag]) ["a", str(EventDefinitions.KIND_ANNOUNCEMENT.as_u16()) + ":" + keys.public_key().to_hex() + ":" + dtag])
event = EventBuilder(Kind(5), "", [e_tag, a_tag]).to_event(keys) event = EventBuilder(Kind(5), "", [e_tag, a_tag]).sign_with_keys(keys)
print(f"POW event: {event.as_json()}") print(f"POW event: {event.as_json()}")
await send_event(event, client, config) await send_event(event, client, config)
@@ -74,7 +74,7 @@ async def nip89_delete_announcement_pow(eid: str, keys: Keys, dtag: str, client:
e_tag = Tag.parse(["e", eid]) e_tag = Tag.parse(["e", eid])
a_tag = Tag.parse( a_tag = Tag.parse(
["a", str(EventDefinitions.KIND_ANNOUNCEMENT.as_u16()) + ":" + keys.public_key().to_hex() + ":" + dtag]) ["a", str(EventDefinitions.KIND_ANNOUNCEMENT.as_u16()) + ":" + keys.public_key().to_hex() + ":" + dtag])
event = EventBuilder(Kind(5), "", [e_tag, a_tag]).pow(28).to_event(keys) event = EventBuilder(Kind(5), "", [e_tag, a_tag]).pow(28).sign_with_keys(keys)
print(f"POW event: {event.as_json()}") print(f"POW event: {event.as_json()}")
await send_event(event, client, config) await send_event(event, client, config)
@@ -85,8 +85,8 @@ async def nip89_fetch_all_dvms(client):
ktags.append(str(i)) ktags.append(str(i))
filter = Filter().kind(EventDefinitions.KIND_ANNOUNCEMENT).custom_tag(SingleLetterTag.lowercase(Alphabet.K), ktags) filter = Filter().kind(EventDefinitions.KIND_ANNOUNCEMENT).custom_tag(SingleLetterTag.lowercase(Alphabet.K), ktags)
events = await client.get_events_of([filter], relay_timeout) events = await client.fetch_events([filter], relay_timeout)
for event in events: for event in events.to_vec():
print(event.as_json()) print(event.as_json())
@@ -94,10 +94,10 @@ async def nip89_fetch_events_pubkey(client, pubkey, kind):
ktags = [str(kind.as_u16())] ktags = [str(kind.as_u16())]
nip89filter = (Filter().kind(EventDefinitions.KIND_ANNOUNCEMENT).author(PublicKey.parse(pubkey)). nip89filter = (Filter().kind(EventDefinitions.KIND_ANNOUNCEMENT).author(PublicKey.parse(pubkey)).
custom_tag(SingleLetterTag.lowercase(Alphabet.K), ktags)) custom_tag(SingleLetterTag.lowercase(Alphabet.K), ktags))
events = await client.get_events_of([nip89filter], relay_timeout) events = await client.fetch_events([nip89filter], relay_timeout)
dvms = {} dvms = {}
for event in events: for event in events.to_vec():
if dvms.get(event.author().to_hex()): if dvms.get(event.author().to_hex()):
if dvms.get(event.author().to_hex()).created_at().as_secs() < event.created_at().as_secs(): if dvms.get(event.author().to_hex()).created_at().as_secs() < event.created_at().as_secs():
dvms[event.author().to_hex()] = event dvms[event.author().to_hex()] = event

View File

@@ -17,7 +17,8 @@ async def generate_nip98_header(pkeys_hex, url="", kind="POST", filepath=""):
if kind == "POST": if kind == "POST":
payloadtag = Tag.parse(["payload", sha256sum(filepath)]) payloadtag = Tag.parse(["payload", sha256sum(filepath)])
tags.append(payloadtag) tags.append(payloadtag)
event = EventBuilder(Kind(27235), "", tags).to_event(keys) eb = EventBuilder(Kind(27235), "", tags)
event = eb.sign_with_keys(keys)
encoded_nip98_event = base64.b64encode(event.as_json().encode('utf-8')).decode('utf-8') encoded_nip98_event = base64.b64encode(event.as_json().encode('utf-8')).decode('utf-8')

View File

@@ -17,16 +17,16 @@ async def get_event_by_id(event_id_str: str, client: Client, config=None) -> Eve
if len(split) == 3: if len(split) == 3:
pk = PublicKey.from_hex(split[1]) pk = PublicKey.from_hex(split[1])
id_filter = Filter().author(pk).custom_tag(SingleLetterTag.lowercase(Alphabet.D), [split[2]]) id_filter = Filter().author(pk).custom_tag(SingleLetterTag.lowercase(Alphabet.D), [split[2]])
events = await client.get_events_of([id_filter], relay_timeout) events = await client.fetch_events([id_filter], relay_timeout)
else: else:
event_id = EventId.parse(event_id_str) event_id = EventId.parse(event_id_str)
id_filter = Filter().id(event_id).limit(1) id_filter = Filter().id(event_id).limit(1)
events = await client.get_events_of([id_filter], relay_timeout) events = await client.fetch_events([id_filter], relay_timeout)
if len(events) > 0: if len(events.to_vec()) > 0:
return events[0] return events.to_vec()[0]
else: else:
print("Event not found") print("Event not found")
return None return None
@@ -34,8 +34,8 @@ async def get_event_by_id(event_id_str: str, client: Client, config=None) -> Eve
async def get_events_async(client, filter, timeout): async def get_events_async(client, filter, timeout):
source_l = EventSource.relays(timedelta(seconds=timeout)) source_l = EventSource.relays(timedelta(seconds=timeout))
events = await client.get_events_of([filter], source_l) events = await client.fetch_events([filter], source_l)
return events return events.to_vec()
async def get_events_by_ids(event_ids, client: Client, config=None) -> List | None: async def get_events_by_ids(event_ids, client: Client, config=None) -> List | None:
@@ -46,7 +46,7 @@ async def get_events_by_ids(event_ids, client: Client, config=None) -> List | No
if len(split) == 3: if len(split) == 3:
pk = PublicKey.from_hex(split[1]) pk = PublicKey.from_hex(split[1])
id_filter = Filter().author(pk).custom_tag(SingleLetterTag.lowercase(Alphabet.D), [split[2]]) id_filter = Filter().author(pk).custom_tag(SingleLetterTag.lowercase(Alphabet.D), [split[2]])
events = await client.get_events_of([id_filter], relay_timeout) events = await client.fetch_events([id_filter], relay_timeout)
else: else:
if str(event_id).startswith('note'): if str(event_id).startswith('note'):
event_id = EventId.from_bech32(event_id) event_id = EventId.from_bech32(event_id)
@@ -62,10 +62,10 @@ async def get_events_by_ids(event_ids, client: Client, config=None) -> List | No
search_ids.append(event_id) search_ids.append(event_id)
id_filter = Filter().ids(search_ids) id_filter = Filter().ids(search_ids)
events = await client.get_events_of([id_filter], relay_timeout) events = await client.fetch_events([id_filter], relay_timeout)
if len(events) > 0: if len(events.to_vec()) > 0:
return events return events.to_vec()
else: else:
return None return None
@@ -73,9 +73,9 @@ async def get_events_by_ids(event_ids, client: Client, config=None) -> List | No
async def get_events_by_id(event_ids: list, client: Client, config=None) -> list[Event] | None: async def get_events_by_id(event_ids: list, client: Client, config=None) -> list[Event] | None:
id_filter = Filter().ids(event_ids) id_filter = Filter().ids(event_ids)
# events = asyncio.run(get_events_async(client, id_filter, config.RELAY_TIMEOUT)) # events = asyncio.run(get_events_async(client, id_filter, config.RELAY_TIMEOUT))
events = await client.get_events_of([id_filter], relay_timeout) events = await client.fetch_events([id_filter], relay_timeout)
if len(events) > 0: if len(events.to_vec()) > 0:
return events return events.to_vec()
else: else:
return None return None
@@ -98,29 +98,29 @@ async def get_referenced_event_by_id(event_id, client, dvm_config, kinds) -> Eve
job_id_filter = Filter().kinds(kinds).event(event_id).limit(1) job_id_filter = Filter().kinds(kinds).event(event_id).limit(1)
else: else:
job_id_filter = Filter().event(event_id).limit(1) job_id_filter = Filter().event(event_id).limit(1)
events = await client.get_events_of([job_id_filter], relay_timeout) events = await client.fetch_events([job_id_filter], relay_timeout)
if len(events) > 0: if len(events.to_vec()) > 0:
return events[0] return events.to_vec()[0]
else: else:
return None return None
async def get_inbox_relays(event_to_send: Event, client: Client, dvm_config): async def get_inbox_relays(event_to_send: Event, client: Client, dvm_config):
ptags = [] ptags = []
for tag in event_to_send.tags(): for tag in event_to_send.tags().to_vec():
if tag.as_vec()[0] == 'p': if tag.as_vec()[0] == 'p':
ptag = PublicKey.parse(tag.as_vec()[1]) ptag = PublicKey.parse(tag.as_vec()[1])
ptags.append(ptag) ptags.append(ptag)
filter = Filter().kinds([EventDefinitions.KIND_RELAY_ANNOUNCEMENT]).authors(ptags) filter = Filter().kinds([EventDefinitions.KIND_RELAY_ANNOUNCEMENT]).authors(ptags)
events = await client.get_events_of([filter], relay_timeout) events = await client.fetch_events([filter], relay_timeout)
if len(events) == 0: if len(events.to_vec()) == 0:
return [] return []
else: else:
nip65event = events[0] nip65event = events.to_vec()[0]
relays = [] relays = []
for tag in nip65event.tags(): for tag in nip65event.tags().to_vec():
if ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2) if ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2)
or ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3) and tag.as_vec()[2] == "read")): or ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3) and tag.as_vec()[2] == "read")):
rtag = tag.as_vec()[1] rtag = tag.as_vec()[1]
@@ -132,19 +132,19 @@ async def get_inbox_relays(event_to_send: Event, client: Client, dvm_config):
async def get_dm_relays(event_to_send: Event, client: Client, dvm_config): async def get_dm_relays(event_to_send: Event, client: Client, dvm_config):
ptags = [] ptags = []
for tag in event_to_send.tags(): for tag in event_to_send.tags().to_vec():
if tag.as_vec()[0] == 'p': if tag.as_vec()[0] == 'p':
ptag = PublicKey.parse(tag.as_vec()[1]) ptag = PublicKey.parse(tag.as_vec()[1])
ptags.append(ptag) ptags.append(ptag)
filter = Filter().kinds([Kind(10050)]).authors(ptags) filter = Filter().kinds([Kind(10050)]).authors(ptags)
events = await client.get_events_of([filter], relay_timeout) events = await client.fetch_events([filter], relay_timeout)
if len(events) == 0: if len(events.to_vec()) == 0:
return [] return []
else: else:
nip65event = events[0] nip65event = events.to_vec()[0]
relays = [] relays = []
for tag in nip65event.tags(): for tag in nip65event.tags().to_vec():
if ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2) if ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2)
or ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3) and tag.as_vec()[2] == "read")): or ((tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3) and tag.as_vec()[2] == "read")):
rtag = tag.as_vec()[1] rtag = tag.as_vec()[1]
@@ -156,7 +156,7 @@ async def get_dm_relays(event_to_send: Event, client: Client, dvm_config):
async def get_main_relays(event_to_send: Event, client: Client, dvm_config): async def get_main_relays(event_to_send: Event, client: Client, dvm_config):
ptags = [] ptags = []
for tag in event_to_send.tags(): for tag in event_to_send.tags().to_vec():
if tag.as_vec()[0] == 'p': if tag.as_vec()[0] == 'p':
ptag = PublicKey.parse(tag.as_vec()[1]) ptag = PublicKey.parse(tag.as_vec()[1])
ptags.append(ptag) ptags.append(ptag)
@@ -167,11 +167,11 @@ async def get_main_relays(event_to_send: Event, client: Client, dvm_config):
await client.connect() await client.connect()
filter = Filter().kinds([EventDefinitions.KIND_FOLLOW_LIST]).authors(ptags) filter = Filter().kinds([EventDefinitions.KIND_FOLLOW_LIST]).authors(ptags)
events = await client.get_events_of([filter], relay_timeout) events = await client.fetch_events([filter], relay_timeout)
if len(events) == 0: if len(events.to_vec()) == 0:
return [] return []
else: else:
followlist = events[0] followlist = events.to_vec()[0]
try: try:
content = json.loads(followlist.content()) content = json.loads(followlist.content())
relays = [] relays = []
@@ -186,7 +186,7 @@ async def send_event_outbox(event: Event, client, dvm_config) -> EventId:
# 1. OK, Let's overcomplicate things. # 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. # 2. If our event has a relays tag, we just send the event to these relay in the classical way.
relays = [] relays = []
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'relays': if tag.as_vec()[0] == 'relays':
for index, param in enumerate(tag.as_vec()): for index, param in enumerate(tag.as_vec()):
if index != 0: if index != 0:
@@ -215,13 +215,11 @@ async def send_event_outbox(event: Event, client, dvm_config) -> EventId:
connection = Connection().embedded_tor().target(ConnectionTarget.ONION) connection = Connection().embedded_tor().target(ConnectionTarget.ONION)
# connection = Connection().addr("127.0.0.1:9050").target(ConnectionTarget.ONION) # connection = Connection().addr("127.0.0.1:9050").target(ConnectionTarget.ONION)
opts = (( opts = ((
Options().wait_for_send(False).send_timeout(timedelta(seconds=5)).relay_limits( Options().relay_limits(relaylimits)).connection(connection).connection_timeout(timedelta(seconds=30)))
relaylimits)).connection(connection).connection_timeout(timedelta(seconds=30)))
sk = SecretKey.from_hex(dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) outboxclient = Client.with_opts(keys, opts)
outboxclient = Client.with_opts(signer, opts)
print("[" + dvm_config.NIP89.NAME + "] Receiver Inbox relays: " + str(relays)) print("[" + dvm_config.NIP89.NAME + "] Receiver Inbox relays: " + str(relays))
for relay in relays[:5]: for relay in relays[:5]:
@@ -265,7 +263,7 @@ async def send_event_outbox(event: Event, client, dvm_config) -> EventId:
async def send_event(event: Event, client: Client, dvm_config): async def send_event(event: Event, client: Client, dvm_config):
try: try:
relays = [] relays = []
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'relays': if tag.as_vec()[0] == 'relays':
for index, param in enumerate(tag.as_vec()): for index, param in enumerate(tag.as_vec()):
if index != 0: if index != 0:
@@ -301,7 +299,7 @@ def check_and_decrypt_tags(event, dvm_config):
is_encrypted = False is_encrypted = False
p = "" p = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'encrypted': if tag.as_vec()[0] == 'encrypted':
is_encrypted = True is_encrypted = True
elif tag.as_vec()[0] == 'p': elif tag.as_vec()[0] == 'p':
@@ -333,7 +331,7 @@ def check_and_decrypt_own_tags(event, dvm_config):
try: try:
is_encrypted = False is_encrypted = False
p = "" p = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == 'encrypted': if tag.as_vec()[0] == 'encrypted':
is_encrypted = True is_encrypted = True
elif tag.as_vec()[0] == 'p': elif tag.as_vec()[0] == 'p':
@@ -363,11 +361,7 @@ def check_and_decrypt_own_tags(event, dvm_config):
async def update_profile_lnaddress(private_key, dvm_config, lud16="", ): async def update_profile_lnaddress(private_key, dvm_config, lud16="", ):
keys = Keys.parse(private_key) keys = Keys.parse(private_key)
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5)) client = Client(keys)
.skip_disconnected_relays(True))
signer = NostrSigner.keys(keys)
client = Client.with_opts(signer, opts)
for relay in dvm_config.RELAY_LIST: for relay in dvm_config.RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -409,10 +403,10 @@ async def update_profile(dvm_config, client, lud16=""):
async def send_nip04_dm(client: Client, msg, receiver: PublicKey, dvm_config): async def send_nip04_dm(client: Client, msg, receiver: PublicKey, dvm_config):
signer = NostrSigner.keys(Keys.parse(dvm_config.PRIVATE_KEY)) keys = Keys.parse(dvm_config.PRIVATE_KEY)
content = await signer.nip04_encrypt(receiver, msg) content = await keys.nip04_encrypt(receiver, msg)
ptag = Tag.parse(["p", receiver.to_hex()]) ptag = Tag.parse(["p", receiver.to_hex()])
event = EventBuilder(Kind(4), content, [ptag]).to_event(Keys.parse(dvm_config.PRIVATE_KEY)) event = EventBuilder(Kind(4), content, [ptag]).sign_with_keys(Keys.parse(dvm_config.PRIVATE_KEY))
await client.send_event(event) await client.send_event(event)
# relays = await get_dm_relays(event, client, dvm_config) # relays = await get_dm_relays(event, client, dvm_config)

View File

@@ -52,13 +52,7 @@ class NutZapWallet:
async def client_connect(self, relay_list): async def client_connect(self, relay_list):
keys = Keys.parse(check_and_set_private_key("TEST_ACCOUNT_PK")) keys = Keys.parse(check_and_set_private_key("TEST_ACCOUNT_PK"))
wait_for_send = False client = Client(keys)
skip_disconnected_relays = True
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=5))
.skip_disconnected_relays(skip_disconnected_relays))
signer = NostrSigner.keys(keys)
client = Client.with_opts(signer, opts)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -109,7 +103,7 @@ class NutZapWallet:
relay_tag = Tag.parse(["relay", relay]) relay_tag = Tag.parse(["relay", relay])
tags.append(relay_tag) tags.append(relay_tag)
event = EventBuilder(EventDefinitions.KIND_NUT_WALLET, content, tags).to_event(keys) event = EventBuilder(EventDefinitions.KIND_NUT_WALLET, content, tags).sign_with_keys(keys)
send_response = await client.send_event(event) send_response = await client.send_event(event)
print( print(
@@ -121,8 +115,8 @@ class NutZapWallet:
nut_wallet = None nut_wallet = None
wallet_filter = Filter().kind(EventDefinitions.KIND_NUT_WALLET).author(keys.public_key()) wallet_filter = Filter().kind(EventDefinitions.KIND_NUT_WALLET).author(keys.public_key())
# relay_timeout = EventSource.relays(timedelta(seconds=10)) wallets_struct = await client.fetch_events([wallet_filter], relay_timeout_long)
wallets = await client.get_events_of([wallet_filter], relay_timeout_long) wallets = wallets_struct.to_vec()
if len(wallets) > 0: if len(wallets) > 0:
@@ -133,7 +127,7 @@ class NutZapWallet:
for wallet_event in wallets: for wallet_event in wallets:
isdeleted = False isdeleted = False
for tag in wallet_event.tags(): for tag in wallet_event.tags().to_vec():
if tag.as_vec()[0] == "deleted": if tag.as_vec()[0] == "deleted":
isdeleted = True isdeleted = True
break break
@@ -175,7 +169,7 @@ class NutZapWallet:
if tag[1] not in nut_wallet.mints: if tag[1] not in nut_wallet.mints:
nut_wallet.mints.append(tag[1]) nut_wallet.mints.append(tag[1])
for tag in best_wallet.tags(): for tag in best_wallet.tags().to_vec():
if tag.as_vec()[0] == "d": if tag.as_vec()[0] == "d":
nut_wallet.d = tag.as_vec()[1] nut_wallet.d = tag.as_vec()[1]
@@ -197,7 +191,8 @@ class NutZapWallet:
# Now all proof events # Now all proof events
proof_filter = Filter().kind(Kind(7375)).author(keys.public_key()) proof_filter = Filter().kind(Kind(7375)).author(keys.public_key())
# relay_timeout = EventSource.relays(timedelta(seconds=5)) # relay_timeout = EventSource.relays(timedelta(seconds=5))
proof_events = await client.get_events_of([proof_filter], relay_timeout) proof_events_struct = await client.fetch_events([proof_filter], relay_timeout)
proof_events = proof_events_struct.to_vec()
latest_proof_sec = 0 latest_proof_sec = 0
latest_proof_event_id = EventId latest_proof_event_id = EventId
@@ -227,7 +222,7 @@ class NutZapWallet:
except Exception as e: except Exception as e:
pass pass
for tag in proof_event.tags(): for tag in proof_event.tags().to_vec():
if tag.as_vec()[0] == "mint": if tag.as_vec()[0] == "mint":
mint_url = tag.as_vec()[1] mint_url = tag.as_vec()[1]
print("mint: " + mint_url) print("mint: " + mint_url)
@@ -334,7 +329,7 @@ class NutZapWallet:
p_tag = Tag.parse(["p", sender_hex]) p_tag = Tag.parse(["p", sender_hex])
tags.append(p_tag) tags.append(p_tag)
event = EventBuilder(Kind(7376), content, tags).to_event(keys) event = EventBuilder(Kind(7376), content, tags).sign_with_keys(keys)
eventid = await client.send_event(event) eventid = await client.send_event(event)
async def create_unspent_proof_event(self, nut_wallet: NutWallet, mint_proofs, mint_url, amount, direction, marker, async def create_unspent_proof_event(self, nut_wallet: NutWallet, mint_proofs, mint_url, amount, direction, marker,
@@ -358,7 +353,7 @@ class NutZapWallet:
if mint.previous_event_id is not None: if mint.previous_event_id is not None:
print( print(
bcolors.MAGENTA + "[" + nut_wallet.name + "] Deleted previous proofs event.. : (" + mint.previous_event_id.to_hex() + ")" + bcolors.ENDC) bcolors.MAGENTA + "[" + nut_wallet.name + "] Deleted previous proofs event.. : (" + mint.previous_event_id.to_hex() + ")" + bcolors.ENDC)
evt = EventBuilder.delete([mint.previous_event_id], reason="deleted").to_event( evt = EventBuilder.delete([mint.previous_event_id], reason="deleted").sign_with_keys(
keys) # .to_pow_event(keys, 28) keys) # .to_pow_event(keys, 28)
response = await client.send_event(evt) response = await client.send_event(evt)
@@ -380,7 +375,7 @@ class NutZapWallet:
else: else:
content = nip44_encrypt(keys.secret_key(), keys.public_key(), message, Nip44Version.V2) content = nip44_encrypt(keys.secret_key(), keys.public_key(), message, Nip44Version.V2)
event = EventBuilder(Kind(7375), content, tags).to_event(keys) event = EventBuilder(Kind(7375), content, tags).sign_with_keys(keys)
eventid = await client.send_event(event) eventid = await client.send_event(event)
await self.create_transaction_history_event(nut_wallet, amount, nut_wallet.unit, old_event_id, eventid.id, await self.create_transaction_history_event(nut_wallet, amount, nut_wallet.unit, old_event_id, eventid.id,
direction, marker, sender_hex, event_hex, client, keys) direction, marker, sender_hex, event_hex, client, keys)
@@ -443,7 +438,7 @@ class NutZapWallet:
pubkey = Keys.parse(nut_wallet.privkey).public_key().to_hex() pubkey = Keys.parse(nut_wallet.privkey).public_key().to_hex()
tags.append(Tag.parse(["pubkey", pubkey])) tags.append(Tag.parse(["pubkey", pubkey]))
event = EventBuilder(Kind(10019), "", tags).to_event(keys) event = EventBuilder(Kind(10019), "", tags).sign_with_keys(keys)
eventid = await client.send_event(event) eventid = await client.send_event(event)
print( print(
bcolors.CYAN + "[" + nut_wallet.name + "] Announced mint preferences info event (" + eventid.id.to_hex() + ")" + bcolors.ENDC) bcolors.CYAN + "[" + nut_wallet.name + "] Announced mint preferences info event (" + eventid.id.to_hex() + ")" + bcolors.ENDC)
@@ -451,7 +446,8 @@ class NutZapWallet:
async def fetch_mint_info_event(self, pubkey, client): async def fetch_mint_info_event(self, pubkey, client):
mint_info_filter = Filter().kind(Kind(10019)).author(PublicKey.parse(pubkey)) mint_info_filter = Filter().kind(Kind(10019)).author(PublicKey.parse(pubkey))
# relay_timeout = EventSource.relays(timedelta(seconds=5)) # relay_timeout = EventSource.relays(timedelta(seconds=5))
preferences = await client.get_events_of([mint_info_filter], relay_timeout) events_struct = await client.fetch_events([mint_info_filter], relay_timeout)
preferences = events_struct.to_vec()
mints = [] mints = []
relays = [] relays = []
pubkey = "" pubkey = ""
@@ -459,7 +455,7 @@ class NutZapWallet:
if len(preferences) > 0: if len(preferences) > 0:
preference = preferences[0] preference = preferences[0]
for tag in preference.tags(): for tag in preference.tags().to_vec():
if tag.as_vec()[0] == "pubkey": if tag.as_vec()[0] == "pubkey":
pubkey = tag.as_vec()[1] pubkey = tag.as_vec()[1]
elif tag.as_vec()[0] == "relay": elif tag.as_vec()[0] == "relay":
@@ -632,7 +628,7 @@ class NutZapWallet:
} }
tags.append(Tag.parse(["proof", json.dumps(nut_proof)])) tags.append(Tag.parse(["proof", json.dumps(nut_proof)]))
event = EventBuilder(Kind(9321), comment, tags).to_event(keys) event = EventBuilder(Kind(9321), comment, tags).sign_with_keys(keys)
response = await client.send_event(event) response = await client.send_event(event)
await self.update_spend_mint_proof_event(nut_wallet, proofs, mint_url, "zapped", keys.public_key().to_hex(), await self.update_spend_mint_proof_event(nut_wallet, proofs, mint_url, "zapped", keys.public_key().to_hex(),
@@ -667,7 +663,7 @@ class NutZapWallet:
unit = "sat" unit = "sat"
sender = "" sender = ""
event = "" event = ""
for tag in transaction.tags(): for tag in transaction.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
sender = tag.as_vec()[1] sender = tag.as_vec()[1]
elif tag.as_vec()[0] == "e": elif tag.as_vec()[0] == "e":
@@ -707,7 +703,7 @@ class NutZapWallet:
zapped_event = "" zapped_event = ""
sender = event.author().to_hex() sender = event.author().to_hex()
message = event.content() message = event.content()
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "proof": if tag.as_vec()[0] == "proof":
proof_json = json.loads(tag.as_vec()[1]) proof_json = json.loads(tag.as_vec()[1])
proof = Proof().from_dict(proof_json) proof = Proof().from_dict(proof_json)

View File

@@ -33,7 +33,7 @@ def post_process_result(anno, original_event):
has_output_tag = False has_output_tag = False
output_format = "text/plain" output_format = "text/plain"
for tag in original_event.tags(): for tag in original_event.tags().to_vec():
if tag.as_vec()[0] == "output": if tag.as_vec()[0] == "output":
output_format = tag.as_vec()[1] output_format = tag.as_vec()[1]
has_output_tag = True has_output_tag = True
@@ -170,6 +170,7 @@ async def upload_media_to_hoster(filepath: str, key_hex=None, fallback=True):
limitinmb = await request_nostr_build_limit(key_hex) limitinmb = await request_nostr_build_limit(key_hex)
if sizeinmb > limitinmb: if sizeinmb > limitinmb:
if fallback: if fallback:
print("Filesize over Nostr.build limit, using paid account") print("Filesize over Nostr.build limit, using paid account")
@@ -217,7 +218,9 @@ async def upload_nostr_build(pkey, files, filepath):
async def request_nostr_build_limit(pkey): async def request_nostr_build_limit(pkey):
url = 'https://nostr.build/api/v2/upload/limit' url = 'https://nostr.build/api/v2/upload/limit'
auth = await generate_nip98_header(pkey, url, "GET") auth = await generate_nip98_header(pkey, url, "GET")
headers = {'authorization': auth} headers = {'authorization': auth}
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)
json_object = json.loads(response.text) json_object = json.loads(response.text)
@@ -309,7 +312,7 @@ async def send_job_status_reaction(original_event_id_hex, original_event_author_
content = reaction content = reaction
keys = Keys.parse(dvm_config.PRIVATE_KEY) keys = Keys.parse(dvm_config.PRIVATE_KEY)
reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(keys) reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).sign_with_keys(keys)
await send_event_outbox(reaction_event, client=client, dvm_config=dvm_config) await send_event_outbox(reaction_event, client=client, dvm_config=dvm_config)
if dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:

View File

@@ -21,10 +21,9 @@ async def create_reaction(keys, title, dtag):
keys = Keys.parse(keys) keys = Keys.parse(keys)
content = "" content = ""
event = EventBuilder(Kind(30030), content, [d_tag, title_tag] + emoji_tags).to_event(keys) event = EventBuilder(Kind(30030), content, [d_tag, title_tag] + emoji_tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
# We add the relays we defined above and told our DVM we would want to receive events to. # We add the relays we defined above and told our DVM we would want to receive events to.
for relay in DVMConfig().RELAY_LIST: for relay in DVMConfig().RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)
@@ -43,10 +42,9 @@ async def delete_reaction(keys, eid: str, dtag: str):
e_tag = Tag.parse(["e", eid]) e_tag = Tag.parse(["e", eid])
a_tag = Tag.parse( a_tag = Tag.parse(
["a", "30030:" + keys.public_key().to_hex() + ":" + dtag]) ["a", "30030:" + keys.public_key().to_hex() + ":" + dtag])
event = EventBuilder(Kind(5), "", [e_tag, a_tag]).to_event(keys) event = EventBuilder(Kind(5), "", [e_tag, a_tag]).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
# We add the relays we defined above and told our DVM we would want to receive events to. # We add the relays we defined above and told our DVM we would want to receive events to.
for relay in DVMConfig().RELAY_LIST: for relay in DVMConfig().RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)

View File

@@ -37,34 +37,32 @@ async def get_following(pks, max_time_request=10, newer_than_time=None):
# newer_than_time provided? If so, it only fetch events that are newer # newer_than_time provided? If so, it only fetch events that are newer
if newer_than_time is None: if newer_than_time is None:
filter = nostr_sdk.Filter().authors(list_pk).kind(Kind(3)) filter = Filter().authors(list_pk).kind(Kind(3))
else: else:
newer_than_time = round(newer_than_time) newer_than_time = round(newer_than_time)
ts = nostr_sdk.Timestamp().from_secs(newer_than_time) ts = nostr_sdk.Timestamp().from_secs(newer_than_time)
filter = nostr_sdk.Filter().authors(list_pk).kind(3).since(ts) filter = Filter().authors(list_pk).kind(Kind(3)).since(ts)
# fetching events # fetching events
opts = (Options().wait_for_send(False).send_timeout(datetime.timedelta(seconds=5)))
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
signer = NostrSigner.keys(keys) cli = ClientBuilder().signer(keys).build()
cli = ClientBuilder().signer(signer).opts(opts).build()
for relay in DVMConfig.RECONCILE_DB_RELAY_LIST: for relay in DVMConfig.RECONCILE_DB_RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
await cli.connect() await cli.connect()
events = await cli.get_events_of([filter], relay_timeout) events = await cli.fetch_events([filter], relay_timeout)
# initializing the graph structure # initializing the graph structure
following = nx.DiGraph() following = nx.DiGraph()
following.add_nodes_from(pks) following.add_nodes_from(pks)
if events == []: if not events.to_vec():
return following return following
for event in events: for event in events.to_vec():
author = event.author().to_hex() author = event.author().to_hex()
@@ -73,7 +71,7 @@ async def get_following(pks, max_time_request=10, newer_than_time=None):
if event.verify() and author in following.nodes() and 'timestamp' not in following.nodes[author]: if event.verify() and author in following.nodes() and 'timestamp' not in following.nodes[author]:
# updating the nodes and edges # updating the nodes and edges
nodes = event.public_keys() nodes = event.tags().public_keys() # TODO
# converting to hex and removing self-following # converting to hex and removing self-following
nodes = [pk.to_hex() for pk in nodes if pk.to_hex() != author] nodes = [pk.to_hex() for pk in nodes if pk.to_hex() != author]
@@ -194,7 +192,7 @@ def split_set(my_set, max_batch):
def save_network(index_map, network_graph, name=None): def save_network(index_map, network_graph, name=None):
if name == None: if name is None:
# adding unix time to file name to avoid replacing an existing file # adding unix time to file name to avoid replacing an existing file
name = str(round(time.time())) name = str(round(time.time()))
# filename = os.path.join('/cache/', 'index_map_' + name + '.json') # filename = os.path.join('/cache/', 'index_map_' + name + '.json')
@@ -583,10 +581,8 @@ async def get_metadata(npub):
pk = PublicKey.parse(npub) pk = PublicKey.parse(npub)
except: except:
return "", "", "" return "", "", ""
opts = (Options().wait_for_send(False).send_timeout(datetime.timedelta(seconds=5)))
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
signer = NostrSigner.keys(keys) client = ClientBuilder().signer(keys).build()
client = ClientBuilder().signer(signer).opts(opts).build()
await client.add_relay("wss://relay.damus.io") await client.add_relay("wss://relay.damus.io")
await client.add_relay("wss://relay.primal.net") await client.add_relay("wss://relay.primal.net")
await client.add_relay("wss://purplepag.es") await client.add_relay("wss://purplepag.es")
@@ -594,7 +590,8 @@ async def get_metadata(npub):
profile_filter = Filter().kind(Kind(0)).author(pk).limit(1) profile_filter = Filter().kind(Kind(0)).author(pk).limit(1)
events = await client.get_events_of([profile_filter], relay_timeout) events_struct = await client.fetch_events([profile_filter], relay_timeout)
events = events_struct.to_vec()
if len(events) > 0: if len(events) > 0:
try: try:
profile = json.loads(events[0].content()) profile = json.loads(events[0].content())

View File

@@ -33,7 +33,7 @@ async def parse_zap_event_tags(zap_event, keys, name, client, config):
anon = False anon = False
message = "" message = ""
sender = zap_event.author() sender = zap_event.author()
for tag in zap_event.tags(): for tag in zap_event.tags().to_vec():
if tag.as_vec()[0] == 'bolt11': if tag.as_vec()[0] == 'bolt11':
invoice_amount = parse_amount_from_bolt11_invoice(tag.as_vec()[1]) invoice_amount = parse_amount_from_bolt11_invoice(tag.as_vec()[1])
elif tag.as_vec()[0] == 'e': elif tag.as_vec()[0] == 'e':
@@ -46,7 +46,7 @@ async def parse_zap_event_tags(zap_event, keys, name, client, config):
zap_request_event = Event.from_json(tag.as_vec()[1]) zap_request_event = Event.from_json(tag.as_vec()[1])
sender = check_for_zapplepay(zap_request_event.author().to_hex(), sender = check_for_zapplepay(zap_request_event.author().to_hex(),
zap_request_event.content()) zap_request_event.content())
for z_tag in zap_request_event.tags(): for z_tag in zap_request_event.tags().to_vec():
if z_tag.as_vec()[0] == 'anon': if z_tag.as_vec()[0] == 'anon':
if len(z_tag.as_vec()) > 1: if len(z_tag.as_vec()) > 1:
# print("[" + name + "] Private Zap received.") # print("[" + name + "] Private Zap received.")
@@ -305,7 +305,7 @@ def zaprequest(lud16: str, amount: int, content, zapped_event, zapped_user, keys
if zapped_event is not None: if zapped_event is not None:
tags.append(e_tag) tags.append(e_tag)
zap_request = EventBuilder(Kind(9733), content, zap_request = EventBuilder(Kind(9733), content,
tags).to_event(keys).as_json() tags).sign_with_keys(keys).as_json()
keys = Keys.parse(encryption_key) keys = Keys.parse(encryption_key)
if zapped_event is not None: if zapped_event is not None:
encrypted_content = enrypt_private_zap_message(zap_request, keys.secret_key(), zapped_event.author()) encrypted_content = enrypt_private_zap_message(zap_request, keys.secret_key(), zapped_event.author())
@@ -317,7 +317,7 @@ def zaprequest(lud16: str, amount: int, content, zapped_event, zapped_user, keys
content = "" content = ""
zap_request = EventBuilder(Kind(9734), content, zap_request = EventBuilder(Kind(9734), content,
tags).to_event(keys).as_json() tags).sign_with_keys(keys).as_json()
response = requests.get(callback + "?amount=" + str(int(amount) * 1000) + "&nostr=" + urllib.parse.quote_plus( response = requests.get(callback + "?amount=" + str(int(amount) * 1000) + "&nostr=" + urllib.parse.quote_plus(
zap_request) + "&lnurl=" + encoded_lnurl) zap_request) + "&lnurl=" + encoded_lnurl)

View File

@@ -1,5 +1,5 @@
from threading import Thread from threading import Thread
from nostr_sdk import Keys, Filter, ClientBuilder, NostrDatabase, NegentropyOptions, init_logger, LogLevel from nostr_sdk import Keys, Filter, ClientBuilder, NostrDatabase, SyncOptions, init_logger, LogLevel
init_logger(LogLevel.INFO) init_logger(LogLevel.INFO)
keys = Keys.parse("nsec1ufnus6pju578ste3v90xd5m2decpuzpql2295m3sknqcjzyys9ls0qlc85") keys = Keys.parse("nsec1ufnus6pju578ste3v90xd5m2decpuzpql2295m3sknqcjzyys9ls0qlc85")
print(keys.public_key().to_bech32()) print(keys.public_key().to_bech32())
@@ -22,8 +22,8 @@ async def reconcile_db():
# Negentropy reconciliation # Negentropy reconciliation
f = Filter().author(keys.public_key()) f = Filter().author(keys.public_key())
opts = NegentropyOptions() opts = SyncOptions()
await client.reconcile(f, opts) await client.sync(f, opts)
await do_some_work() await do_some_work()

View File

@@ -16,10 +16,8 @@ async def main():
"relay": "wss://gleasonator.dev/relay" "relay": "wss://gleasonator.dev/relay"
} }
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5)))
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
signer = NostrSigner.keys(keys) cli = Client(keys)
cli = Client.with_opts(signer, opts)
await cli.add_relay(options["relay"]) await cli.add_relay(options["relay"])
await cli.connect() await cli.connect()
@@ -29,14 +27,16 @@ async def main():
authors = [PublicKey.parse("db0e60d10b9555a39050c258d460c5c461f6d18f467aa9f62de1a728b8a891a4")] authors = [PublicKey.parse("db0e60d10b9555a39050c258d460c5c461f6d18f467aa9f62de1a728b8a891a4")]
notes_filter = Filter().authors(authors).custom_tag(SingleLetterTag.lowercase(Alphabet.L), ltags) notes_filter = Filter().authors(authors).custom_tag(SingleLetterTag.lowercase(Alphabet.L), ltags)
events = await cli.get_events_of([notes_filter], relay_timeout_long) events_struct = await cli.fetch_events([notes_filter], relay_timeout_long)
events = events_struct.to_vec()
result_list = [] result_list = []
if len(events) > 0: if len(events) > 0:
event = events[0] event = events[0]
print(event) print(event)
result_list = [] result_list = []
for tag in event.tags(): for tag in event.tags().to_vec():
print(tag.as_vec()) print(tag.as_vec())
if tag.as_vec()[0] == "e": if tag.as_vec()[0] == "e":

View File

@@ -102,15 +102,11 @@ def playground(announce=False):
options = dvm.set_options(request_form) options = dvm.set_options(request_form)
sk = SecretKey.from_hex(dvm.dvm_config.PRIVATE_KEY) sk = SecretKey.from_hex(dvm.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
relaylimits = RelayLimits.disable() relaylimits = RelayLimits.disable()
opts = ( opts = (Options().relay_limits(relaylimits))
Options().wait_for_send(False).send_timeout(timedelta(seconds=dvm.dvm_config.RELAY_TIMEOUT))).relay_limits(
relaylimits)
cli = Client.with_opts(signer, opts) cli = Client.with_opts(keys, opts)
for relay in dvm.dvm_config.RELAY_LIST: for relay in dvm.dvm_config.RELAY_LIST:
await cli.add_relay(relay) await cli.add_relay(relay)
# ropts = RelayOptions().ping(False) # ropts = RelayOptions().ping(False)
@@ -122,10 +118,9 @@ def playground(announce=False):
print(options["request_event_author"]) print(options["request_event_author"])
filterauth = Filter().kind(definitions.EventDefinitions.KIND_NOTE).author(author).limit(100) filterauth = Filter().kind(definitions.EventDefinitions.KIND_NOTE).author(author).limit(100)
evts = await cli.get_events_of([filterauth], relay_timeout) event_struct = await cli.fetch_events([filterauth], relay_timeout)
text = "" text = ""
for event in evts: for event in event_struct.to_vec():
text = text + event.content() + ";" text = text + event.content() + ";"

445
tests/otherstuff.py Normal file
View File

@@ -0,0 +1,445 @@
import asyncio
import json
import os
import threading
from pathlib import Path
import dotenv
from nostr_sdk import Keys, LogLevel, init_logger
from nostr_dvm.bot import Bot
from nostr_dvm.tasks.convert_media import MediaConverter
from nostr_dvm.tasks.discovery_bot_farms import DiscoveryBotFarms
from nostr_dvm.tasks.discovery_censor_wot import DiscoverReports
from nostr_dvm.tasks.discovery_inactive_follows import DiscoverInactiveFollows
from nostr_dvm.tasks.imagegeneration_openai_dalle import ImageGenerationDALLE
from nostr_dvm.tasks.imagegeneration_replicate import ImageGenerationReplicate
from nostr_dvm.tasks.imagegeneration_replicate_fluxpro import ImageGenerationReplicateFluxPro
from nostr_dvm.tasks.imagegeneration_replicate_recraft import ImageGenerationReplicateRecraft
from nostr_dvm.tasks.imagegeneration_sd35_api import ImageGenerationSD35
from nostr_dvm.tasks.videogeneration_replicate_svd import VideoGenerationReplicateSVD
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config, DVMConfig
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag
from nostr_dvm.utils.nostr_utils import check_and_set_private_key
from nostr_dvm.utils.zap_utils import get_price_per_sat, check_and_set_ln_bits_keys
# Some other DVMs to run.
use_logger = True
log_level = LogLevel.ERROR
if use_logger:
init_logger(log_level)
def build_sd35(name, identifier, announce):
dvm_config = build_default_config(identifier)
dvm_config.NEW_USER_BALANCE = 0
dvm_config.USE_OWN_VENV = False
dvm_config.ENABLE_NUTZAP = False
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://i.nostr.build/NOXcCIPmOZrDTK35.jpg",
"about": "I draw images using Stable diffusion ultra",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"negative_prompt": {
"required": False,
"values": []
},
"ratio": {
"required": False,
"values": ["1:1", "5:4", "3:2", "16:9","21:9", "9:21", "9:16", "2:3", "4:5"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
aconfig = AdminConfig()
aconfig.REBROADCAST_NIP89 = announce # We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
aconfig.REBROADCAST_NIP65_RELAY_LIST = announce
aconfig.LUD16 = dvm_config.LN_ADDRESS
aconfig.PRIVKEY = dvm_config.PRIVATE_KEY
aconfig.MELT_ON_STARTUP = False # set this to true to melt cashu tokens to our ln address on startup
options= {"API_KEY": os.getenv("STABILITY_KEY")}
return ImageGenerationSD35(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=aconfig, options=options)
def build_dalle(name, identifier, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
dvm_config.NEW_USER_BALANCE = 0
dvm_config.USE_OWN_VENV = False
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://image.nostr.build/22f2267ca9d4ee9d5e8a0c7818a9fa325bbbcdac5573a60a2d163e699bb69923.jpg",
"about": "I create Images bridging OpenAI's DALL·E 3",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"size": {
"required": False,
"values": ["1024:1024", "1024x1792", "1792x1024"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationDALLE(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
def build_svd(name, identifier, announce):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
profit_in_sats = 10
cost_in_cent = 4.0
dvm_config.FIX_COST = int(((cost_in_cent / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use Stable Video Diffusion to create short videos",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return VideoGenerationReplicateSVD(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_media_converter(name, identifier, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
nip89info = {
"name": name,
"image": "https://cdn.nostr.build/i/a177be1159da5aad8396a1188f686728d55647d3a7371549584daf2b5e50eec9.jpg",
"about": "I convert videos from urls to given output format.",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"media_format": {
"required": False,
"values": ["video/mp4", "audio/mp3"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return MediaConverter(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_inactive_follows_finder(name, identifier, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
dvm_config.USE_OWN_VENV = False
dvm_config.FIX_COST = 0
# Add NIP89
nip89info = {
"name": name,
"image": "https://image.nostr.build/50621bbf8082c478bc06a06684e1c443b5d37f1362ad56d679cab7328e0481db.jpg",
"about": "I discover npubs you follow, but that have been inactive on Nostr for the last 90 days",
"action": "unfollow",
"cashuAccepted": True,
"nip90Params": {
"user": {
"required": False,
"values": [],
"description": "Do the task for another user"
},
"since_days": {
"required": False,
"values": [],
"description": "The number of days a user has not been active to be considered inactive"
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DiscoverInactiveFollows(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_1984(name, identifier, announce):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
# Add NIP89
nip89info = {
"name": name,
"image": "https://image.nostr.build/19872a2edd866258fa9eab137631efda89310d52b2c6ea8f99ef057325aa1c7b.jpg",
"about": "I show users that have been reported by either your followers or your Web of Trust. Note: Anyone can report, so you might double check and decide for yourself who to mute. Considers spam, illegal and impersonation reports. Notice: This works with NIP51 mute lists. Not all clients support the new mute list format.",
"encryptionSupported": True,
"cashuAccepted": True,
"action": "mute", # follow, unfollow, mute, unmute
"nip90Params": {
"since_days": {
"required": False,
"values": [],
"description": "The number of days a report is ago in order to be considered "
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DiscoverReports(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_botfarms(name, identifier, announce):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
dvm_config.SHOWLOG = True
dvm_config.SCHEDULE_UPDATES_SECONDS = 600 # Every 10 seconds
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
# Add NIP89
nip89info = {
"name": name,
"image": "https://image.nostr.build/981b560820bc283c58de7989b7abc6664996b487a531d852e4ef7322586a2122.jpg",
"about": "I hunt down bot farms.",
"encryptionSupported": True,
"cashuAccepted": True,
"action": "mute", # follow, unfollow, mute, unmute
"nip90Params": {
"max_results": {
"required": False,
"values": [],
"description": "The number of maximum results to return (default currently 20)"
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
options = {"relay": "wss://relay.damus.io"}
return DiscoveryBotFarms(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_replicate(name, identifier, model, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://i.nostr.build/qnoBIN4jSkfF8IHk.png",
"about": "I use Replicate to run StableDiffusion XL",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"size": {
"required": False,
"values": ["1024:1024", "1024x1792", "1792x1024"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
opts = {"model": model}
return ImageGenerationReplicate(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=opts)
def build_replicate_recraft(name, identifier, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://i.nostr.build/jSbrXvYglXCzSeAc.jpg",
"about": "I use Replicate to run Recraft v3",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"size": {
"required": False,
"values": ["1024:1024"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationReplicateRecraft(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_replicate_fluxpro(name, identifier, announce):
dvm_config = build_default_config(identifier)
admin_config = AdminConfig()
admin_config.LUD16 = dvm_config.LN_ADDRESS
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip89info = {
"name": name,
"image": "https://i.nostr.build/AQTujqzVmLxLmG16.jpg",
"about": "I use Replicate to FluxPro 1.1.",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {
"size": {
"required": False,
"values": ["5:4"]
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationReplicateFluxPro(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def playground(announce=False):
#bot_config = DVMConfig()
bot_config = build_default_config("bot")
#bot_config.PRIVATE_KEY = check_and_set_private_key("bot")
#npub = Keys.parse(bot_config.PRIVATE_KEY).public_key().to_bech32()
#invoice_key, admin_key, wallet_id, lnaddress = check_and_set_ln_bits_keys("bot",npub)
#bot_config.LNBITS_INVOICE_KEY = invoice_key
#bot_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs backbot_config.LNBITS_URL = os.getenv("LNBITS_HOST")
if os.getenv("OPENAI_API_KEY") is not None and os.getenv("OPENAI_API_KEY") != "":
dalle = build_dalle("Dall-E 3", "dalle3", announce)
bot_config.SUPPORTED_DVMS.append(dalle)
dalle.run()
if os.getenv("STABILITY_KEY") is not None and os.getenv("STABILITY_KEY") != "":
sd35 = build_sd35("Stable Diffusion Ultra", "sd35", announce)
sd35.run()
if os.getenv("REPLICATE_API_TOKEN") is not None and os.getenv("REPLICATE_API_TOKEN") != "":
model = "stability-ai/stable-diffusion-3.5-large"
sd3replicate = build_replicate("Stable Diffusion 3.5 Large", "replicate_svd", model, announce)
bot_config.SUPPORTED_DVMS.append(sd3replicate)
sd3replicate.run()
model = "black-forest-labs/flux-1.1-pro"
fluxreplicate = build_replicate_fluxpro("Flux 1.1. Pro", "fluxpro", announce)
bot_config.SUPPORTED_DVMS.append(fluxreplicate)
fluxreplicate.run()
recraftreplicate = build_replicate_recraft("Recraft v3", "recraftsvg", announce)
bot_config.SUPPORTED_DVMS.append(recraftreplicate)
recraftreplicate.run()
media_bringer = build_media_converter("Nostr AI DVM Media Converter", "media_converter", announce)
#bot_config.SUPPORTED_DVMS.append(media_bringer)
media_bringer.run()
discover_inactive = build_inactive_follows_finder("Those who left", "discovery_inactive_follows", announce)
bot_config.SUPPORTED_DVMS.append(discover_inactive)
discover_inactive.run()
discovery_censor = build_1984("Censorship 1984", "discovery_censor", announce)
#bot_config.SUPPORTED_DVMS.append(discovery_censor)
discovery_censor.run()
#discovery_bots = build_botfarms("Bot Hunter", "discovery_botfarms", announce)
#bot_config.SUPPORTED_DVMS.append(discovery_bots)
#discovery_bots.run()
admin_config = AdminConfig()
#admin_config.REBROADCAST_NIP65_RELAY_LIST = True
x = threading.Thread(target=Bot, args=([bot_config, admin_config]))
x.start()
if __name__ == '__main__':
env_path = Path('.env')
if not env_path.is_file():
with open('.env', 'w') as f:
print("Writing new .env file")
f.write('')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
announce = False
playground(announce)

View File

@@ -20,8 +20,7 @@ async def test():
pk = keys.public_key() pk = keys.public_key()
print(f"Bot public key: {pk.to_bech32()}") print(f"Bot public key: {pk.to_bech32()}")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
await client.add_relay("wss://relay.damus.io") await client.add_relay("wss://relay.damus.io")
await client.add_relay("wss://nostr.mom") await client.add_relay("wss://nostr.mom")

View File

@@ -19,7 +19,7 @@ async def nostr_client_test_translation(input, kind, lang, sats, satsmax):
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
if kind == "text": if kind == "text":
iTag = Tag.parse(["i", input, "text"]) iTag = Tag.parse(["i", input, "text"])
elif kind == "event": else:
iTag = Tag.parse(["i", input, "event"]) iTag = Tag.parse(["i", input, "event"])
paramTag1 = Tag.parse(["param", "language", lang]) paramTag1 = Tag.parse(["param", "language", lang])
@@ -28,13 +28,12 @@ async def nostr_client_test_translation(input, kind, lang, sats, satsmax):
"wss://nostr-pub.wellorder.net"]) "wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to translate a given Input"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to translate a given Input"])
event = EventBuilder(EventDefinitions.KIND_NIP90_TRANSLATE_TEXT, str("Translate the given input."), event = EventBuilder(EventDefinitions.KIND_NIP90_TRANSLATE_TEXT, str("Translate the given input."),
[iTag, paramTag1, bidTag, relaysTag, alttag]).to_event(keys) [iTag, paramTag1, bidTag, relaysTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"] "wss://nostr-pub.wellorder.net"]
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
@@ -50,13 +49,12 @@ async def nostr_client_test_search_profile(input):
iTag = Tag.parse(["i", input, "text"]) iTag = Tag.parse(["i", input, "text"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to translate a given Input"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to translate a given Input"])
event = EventBuilder(EventDefinitions.KIND_NIP90_USER_SEARCH, str("Search for user"), event = EventBuilder(EventDefinitions.KIND_NIP90_USER_SEARCH, str("Search for user"),
[iTag, alttag]).to_event(keys) [iTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"] "wss://nostr-pub.wellorder.net"]
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
@@ -77,10 +75,9 @@ async def nostr_client_test_image(prompt):
relaysTag = Tag.parse(['relays', "wss://relay.primal.net", "wss://nostr.oxtr.dev"]) relaysTag = Tag.parse(['relays', "wss://relay.primal.net", "wss://nostr.oxtr.dev"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate an Image from a given Input"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate an Image from a given Input"])
event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_IMAGE, str("Generate an Image."), event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_IMAGE, str("Generate an Image."),
[iTag, outTag, paramTag1, bidTag, relaysTag, alttag]).to_event(keys) [iTag, outTag, paramTag1, bidTag, relaysTag, alttag]).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in DVMConfig().RELAY_LIST: for relay in DVMConfig().RELAY_LIST:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -106,10 +103,9 @@ async def nostr_client_test_censor_filter(users):
tags.append(iTag) tags.append(iTag)
event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me bad actors"), event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me bad actors"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -132,10 +128,9 @@ async def nostr_client_test_inactive_filter(user):
tags = [relaysTag, alttag, paramTag, paramTag2] tags = [relaysTag, alttag, paramTag, paramTag2]
event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me inactive users"), event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me inactive users"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.add_relay("wss://nostr.band") await client.add_relay("wss://nostr.band")
@@ -156,13 +151,12 @@ async def nostr_client_test_tts(prompt):
"wss://nostr-pub.wellorder.net"]) "wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTSt"]) alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate TTSt"])
event = EventBuilder(EventDefinitions.KIND_NIP90_TEXT_TO_SPEECH, str("Generate an Audio File."), event = EventBuilder(EventDefinitions.KIND_NIP90_TEXT_TO_SPEECH, str("Generate an Audio File."),
[iTag, paramTag1, bidTag, relaysTag, alttag]).to_event(keys) [iTag, paramTag1, bidTag, relaysTag, alttag]).sign_with_keys(keys)
relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org" "wss://dvms.f7z.io", relay_list = ["wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org" "wss://dvms.f7z.io",
] ]
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -185,13 +179,12 @@ async def nostr_client_test_discovery(user, ptag):
tags = [relaysTag, alttag, paramTag, pTag] tags = [relaysTag, alttag, paramTag, pTag]
event = EventBuilder(EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY, str("Give me content"), event = EventBuilder(EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY, str("Give me content"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
ropts = RelayOptions().ping(False)
await client.add_relay("wss://nostr.band") await client.add_relay("wss://nostr.band")
await client.connect() await client.connect()
config = DVMConfig config = DVMConfig
@@ -223,13 +216,11 @@ async def nostr_client_custom_discovery(user, ptag):
tags = [relaysTag, alttag, paramTag, pTag]# paramTagSearch, paramTagMust, paramTagAvoid] tags = [relaysTag, alttag, paramTag, pTag]# paramTagSearch, paramTagMust, paramTagAvoid]
event = EventBuilder(EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY, str("Give me content"), event = EventBuilder(EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY, str("Give me content"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
ropts = RelayOptions().ping(False)
await client.connect() await client.connect()
config = DVMConfig config = DVMConfig
@@ -251,13 +242,11 @@ async def nostr_client_generic_test(ptag):
tags = [relaysTag, alttag, pTag] tags = [relaysTag, alttag, pTag]
event = EventBuilder(Kind(5050), str("Give me content"), event = EventBuilder(Kind(5050), str("Give me content"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
ropts = RelayOptions().ping(False)
await client.connect() await client.connect()
config = DVMConfig config = DVMConfig
await send_event(event, client=client, dvm_config=config) await send_event(event, client=client, dvm_config=config)
@@ -279,13 +268,11 @@ async def nostr_client_duckduck_test(ptag, query):
tags = [relaysTag, alttag, pTag, iTag] tags = [relaysTag, alttag, pTag, iTag]
event = EventBuilder(Kind(5050), str("Give me content"), event = EventBuilder(Kind(5050), str("Give me content"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
ropts = RelayOptions().ping(False)
await client.connect() await client.connect()
config = DVMConfig config = DVMConfig
await send_event(event, client=client, dvm_config=config) await send_event(event, client=client, dvm_config=config)
@@ -305,10 +292,9 @@ async def nostr_client_flux_schnell(ptag, query):
tags = [relaysTag, alttag, pTag, iTag] tags = [relaysTag, alttag, pTag, iTag]
event = EventBuilder(Kind(5100), str("Give me image"), event = EventBuilder(Kind(5100), str("Give me image"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
ropts = RelayOptions().ping(False) ropts = RelayOptions().ping(False)
@@ -334,10 +320,9 @@ async def nostr_client_test_discovery_user(user, ptag):
tags = [relaysTag, alttag, paramTag, pTag] tags = [relaysTag, alttag, paramTag, pTag]
event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me people"), event = EventBuilder(EventDefinitions.KIND_NIP90_PEOPLE_DISCOVERY, str("Give me people"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -360,10 +345,9 @@ async def nostr_client_test_discovery_gallery(user, ptag):
tags = [relaysTag, alttag, paramTag, pTag] tags = [relaysTag, alttag, paramTag, pTag]
event = EventBuilder(EventDefinitions.KIND_NIP90_VISUAL_DISCOVERY, str("Give me visuals"), event = EventBuilder(EventDefinitions.KIND_NIP90_VISUAL_DISCOVERY, str("Give me visuals"),
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -398,10 +382,9 @@ async def nostr_client_test_image_private(prompt, cashutoken):
encrypted_tag = Tag.parse(['encrypted']) encrypted_tag = Tag.parse(['encrypted'])
nip90request = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_IMAGE, encrypted_params, nip90request = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_IMAGE, encrypted_params,
[pTag, encrypted_tag]).to_event(keys) [pTag, encrypted_tag]).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -415,8 +398,7 @@ async def nostr_client():
sk = keys.secret_key() sk = keys.secret_key()
pk = keys.public_key() pk = keys.public_key()
print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ") print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:
@@ -488,7 +470,7 @@ async def nostr_client():
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
amount_sats = 0 amount_sats = 0
status = "" status = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "amount": if tag.as_vec()[0] == "amount":
amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats
if tag.as_vec()[0] == "status": if tag.as_vec()[0] == "status":

View File

@@ -17,13 +17,7 @@ from nostr_dvm.utils.nostr_utils import check_and_set_private_key
async def test(): async def test():
relay_list = dvmconfig.DVMConfig.RELAY_LIST relay_list = dvmconfig.DVMConfig.RELAY_LIST
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
wait_for_send = False client = Client(keys)
skip_disconnected_relays = True
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=5))
.skip_disconnected_relays(skip_disconnected_relays))
signer = NostrSigner.keys(keys)
client = Client.with_opts(signer, opts)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
@@ -61,7 +55,8 @@ async def test_referred_events(client, event_id, kinds=None):
else: else:
job_id_filter = Filter().event(EventId.from_hex(event_id)) job_id_filter = Filter().event(EventId.from_hex(event_id))
events = await client.get_events_of([job_id_filter], relay_timeout) event_struct = await client.fetch_events([job_id_filter], relay_timeout)
events = event_struct.to_vec()
if len(events) > 0: if len(events) > 0:
for event in events: for event in events:
@@ -75,13 +70,8 @@ async def test_referred_events(client, event_id, kinds=None):
async def test_gallery(): async def test_gallery():
relay_list = dvmconfig.DVMConfig.RELAY_LIST relay_list = dvmconfig.DVMConfig.RELAY_LIST
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
wait_for_send = False
skip_disconnected_relays = True
opts = (Options().wait_for_send(wait_for_send).send_timeout(timedelta(seconds=5))
.skip_disconnected_relays(skip_disconnected_relays))
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client.with_opts(signer, opts)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
@@ -121,7 +111,7 @@ async def test_gallery():
# await gallery_announce_list(tags, dvm_config, client) # await gallery_announce_list(tags, dvm_config, client)
#evt = EventBuilder.delete([EventId.parse("721ac7c7d9309b6d3e6728a7274f5a1f10096b4ab17068233bcfa05cb233e84a")], #evt = EventBuilder.delete([EventId.parse("721ac7c7d9309b6d3e6728a7274f5a1f10096b4ab17068233bcfa05cb233e84a")],
# reason="deleted").to_event(keys) # reason="deleted").sign_with_keys(keys)
#await client.send_event(evt) #await client.send_event(evt)
#key1 = Keys.parse("3e99f38a8e8c59ff3683cdc0942e26471c1aae9b225eb34dd410cb9d6dde93a6") #key1 = Keys.parse("3e99f38a8e8c59ff3683cdc0942e26471c1aae9b225eb34dd410cb9d6dde93a6")
@@ -141,7 +131,8 @@ async def test_search_by_user_since_days(client, pubkey, days, prompt):
since = Timestamp.from_secs(dif) since = Timestamp.from_secs(dif)
filterts = Filter().search(prompt).author(pubkey).kinds([Kind(1)]).since(since) filterts = Filter().search(prompt).author(pubkey).kinds([Kind(1)]).since(since)
events = await client.get_events_of([filterts], relay_timeout) event_struct = await client.fetch_events([filterts], relay_timeout)
events = event_struct.to_vec()
if len(events) > 0: if len(events) > 0:
for event in events: for event in events:

View File

@@ -14,7 +14,7 @@ from nostr_dvm.utils.definitions import relay_timeout
warnings.filterwarnings('ignore') warnings.filterwarnings('ignore')
from nostr_sdk import Options, Keys, NostrSigner, Filter, PublicKey, Kind, \ from nostr_sdk import Options, Keys, NostrSigner, Filter, PublicKey, Kind, \
NegentropyOptions, NegentropyDirection, ClientBuilder, NostrDatabase SyncOptions, SyncDirection, ClientBuilder, NostrDatabase
# init_logger(LogLevel.INFO) # init_logger(LogLevel.INFO)
@@ -26,17 +26,16 @@ async def getmetadata(npub):
pk = PublicKey.parse(npub) pk = PublicKey.parse(npub)
except: except:
return "", "", "" return "", "", ""
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5)))
keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj") keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj")
signer = NostrSigner.keys(keys) client = ClientBuilder().signer(keys).build()
client = ClientBuilder().signer(signer).opts(opts).build()
await client.add_relay("wss://relay.damus.io") await client.add_relay("wss://relay.damus.io")
await client.add_relay("wss://relay.primal.net") await client.add_relay("wss://relay.primal.net")
await client.add_relay("wss://purplepag.es") await client.add_relay("wss://purplepag.es")
await client.connect() await client.connect()
profile_filter = Filter().kind(Kind(0)).author(pk).limit(1) profile_filter = Filter().kind(Kind(0)).author(pk).limit(1)
events = await client.get_events_of([profile_filter], relay_timeout) event_struct = await client.fetch_events([profile_filter], relay_timeout)
events = event_struct.to_vec()
if len(events) > 0: if len(events) > 0:
try: try:
profile = json.loads(events[0].content()) profile = json.loads(events[0].content())
@@ -53,11 +52,9 @@ async def getmetadata(npub):
async def sync_db(): async def sync_db():
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5)))
keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj") keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj")
signer = NostrSigner.keys(keys)
database = NostrDatabase.lmdb("db/nostr_followlists.db") database = NostrDatabase.lmdb("db/nostr_followlists.db")
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(keys).database(database).build()
await cli.add_relay("wss://relay.damus.io") # TODO ADD MORE await cli.add_relay("wss://relay.damus.io") # TODO ADD MORE
# await cli.add_relay("wss://relay.primal.net") # TODO ADD MORE # await cli.add_relay("wss://relay.primal.net") # TODO ADD MORE
@@ -67,8 +64,8 @@ async def sync_db():
# filter = Filter().author(keys.public_key()) # filter = Filter().author(keys.public_key())
print("Syncing Profile Database.. this might take a while..") print("Syncing Profile Database.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN) dbopts = SyncOptions().direction(SyncDirection.DOWN)
await cli.reconcile(filter1, dbopts) await cli.sync(filter1, dbopts)
print("Done Syncing Profile Database.") print("Done Syncing Profile Database.")
await cli.shutdown() await cli.shutdown()
@@ -92,7 +89,7 @@ async def analyse_users(user_ids=None):
if len(followers) > 0: if len(followers) > 0:
for follower in followers: for follower in followers:
frens = [] frens = []
for tag in follower.tags(): for tag in follower.tags().to_vec():
if tag.as_vec()[0] == "p": if tag.as_vec()[0] == "p":
frens.append(tag.as_vec()[1]) frens.append(tag.as_vec()[1])
allfriends.append(Friend(follower.author().to_hex(), frens)) allfriends.append(Friend(follower.author().to_hex(), frens))

View File

@@ -36,11 +36,10 @@ async def nostr_client_generic_test(ptag):
# We now send a 5050 Request (for Text Generation) with our tags. The content is optional. # We now send a 5050 Request (for Text Generation) with our tags. The content is optional.
event = EventBuilder(Kind(5050), "This is a test", event = EventBuilder(Kind(5050), "This is a test",
tags).to_event(keys) tags).sign_with_keys(keys)
# We create a signer with some random keys # We create a signer with some random keys
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
# We add the relays we defined above and told our DVM we would want to receive events to. # We add the relays we defined above and told our DVM we would want to receive events to.
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
@@ -58,8 +57,7 @@ async def nostr_client(target_dvm_npub):
sk = keys.secret_key() sk = keys.secret_key()
pk = keys.public_key() pk = keys.public_key()
print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ") print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:
@@ -90,7 +88,7 @@ async def nostr_client(target_dvm_npub):
print(bcolors.YELLOW + "[Nostr Client]: " + event.content() + bcolors.ENDC) print(bcolors.YELLOW + "[Nostr Client]: " + event.content() + bcolors.ENDC)
amount_sats = 0 amount_sats = 0
status = "" status = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "amount": if tag.as_vec()[0] == "amount":
amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats
if tag.as_vec()[0] == "status": if tag.as_vec()[0] == "status":

View File

@@ -31,10 +31,9 @@ async def nostr_client_generic_test(ptag):
pTag = Tag.parse(["p", PublicKey.parse(ptag).to_hex()]) pTag = Tag.parse(["p", PublicKey.parse(ptag).to_hex()])
tags = [relaysTag, alttag, pTag, paramTag] tags = [relaysTag, alttag, pTag, paramTag]
event = EventBuilder(Kind(5050), "This is a test", event = EventBuilder(Kind(5050), "This is a test",
tags).to_event(keys) tags).sign_with_keys(keys)
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
for relay in relay_list: for relay in relay_list:
await client.add_relay(relay) await client.add_relay(relay)
await client.connect() await client.connect()
@@ -47,8 +46,7 @@ async def nostr_client(target_dvm_npub):
keys = Keys.parse(check_and_set_private_key("test_client")) keys = Keys.parse(check_and_set_private_key("test_client"))
pk = keys.public_key() pk = keys.public_key()
print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ") print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
signer = NostrSigner.keys(keys) client = Client(keys)
client = Client(signer)
dvmconfig = DVMConfig() dvmconfig = DVMConfig()
for relay in dvmconfig.RELAY_LIST: for relay in dvmconfig.RELAY_LIST:
@@ -74,7 +72,7 @@ async def nostr_client(target_dvm_npub):
print(bcolors.YELLOW + "[Nostr Client]: " + event.content() + bcolors.ENDC) print(bcolors.YELLOW + "[Nostr Client]: " + event.content() + bcolors.ENDC)
amount_sats = 0 amount_sats = 0
status = "" status = ""
for tag in event.tags(): for tag in event.tags().to_vec():
if tag.as_vec()[0] == "amount": if tag.as_vec()[0] == "amount":
amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats amount_sats = int(int(tag.as_vec()[1]) / 1000) # millisats
if tag.as_vec()[0] == "status": if tag.as_vec()[0] == "status":