add lmdb database, update to new sdk

This commit is contained in:
Believethehype
2024-09-10 09:20:22 +02:00
parent 131cbea6f3
commit a2f482aa06
30 changed files with 187 additions and 157 deletions

View File

@@ -65,7 +65,7 @@ async def nostr_client():
print(f"Received new event from {relay_url}: {event.as_json()}") print(f"Received new event from {relay_url}: {event.as_json()}")
if event.kind() == 7000: if event.kind() == 7000:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
elif 6000 < event.kind().as_u64() < 6999: elif 6000 < event.kind().as_u16() < 6999:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
print("[Nostr Client]: " + event.content()) print("[Nostr Client]: " + event.content())

View File

@@ -71,7 +71,7 @@ async def nostr_client():
print(f"Received new event from {relay_url}: {event.as_json()}") print(f"Received new event from {relay_url}: {event.as_json()}")
if event.kind() == 7000: if event.kind() == 7000:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
elif 6000 < event.kind().as_u64() < 6999: elif 6000 < event.kind().as_u16() < 6999:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
print("[Nostr Client]: " + event.content()) print("[Nostr Client]: " + event.content())

View File

@@ -70,7 +70,7 @@ async def nostr_client():
print(f"Received new event from {relay_url}: {event.as_json()}") print(f"Received new event from {relay_url}: {event.as_json()}")
if event.kind() == 7000: if event.kind() == 7000:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
elif 6000 < event.kind().as_u64() < 6999: elif 6000 < event.kind().as_u16() < 6999:
print("[Nostr Client " + event.author().to_bech32() + "]: " + event.as_json()) print("[Nostr Client " + event.author().to_bech32() + "]: " + event.as_json())
print("[Nostr Client " + event.author().to_bech32() + "]: " + event.content()) print("[Nostr Client " + event.author().to_bech32() + "]: " + event.content())

View File

@@ -68,7 +68,7 @@ class Bot:
kinds = [EventDefinitions.KIND_NIP90_GENERIC, EventDefinitions.KIND_FEEDBACK] kinds = [EventDefinitions.KIND_NIP90_GENERIC, EventDefinitions.KIND_FEEDBACK]
for dvm in self.dvm_config.SUPPORTED_DVMS: for dvm in self.dvm_config.SUPPORTED_DVMS:
if dvm.KIND not in kinds: if dvm.KIND not in kinds:
kinds.append(Kind(dvm.KIND.as_u64() + 1000)) kinds.append(Kind(dvm.KIND.as_u16() + 1000))
dvm_filter = (Filter().kinds(kinds).since(Timestamp.now())) dvm_filter = (Filter().kinds(kinds).since(Timestamp.now()))
await self.client.subscribe([zap_filter, dm_filter, nip17_filter, dvm_filter], None) await self.client.subscribe([zap_filter, dm_filter, nip17_filter, dvm_filter], None)
@@ -82,8 +82,8 @@ class Bot:
keys = self.keys keys = self.keys
async def handle(self, relay_url, subscription_id, nostr_event): async def handle(self, relay_url, subscription_id, nostr_event):
if (EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u64() + 1000 <= nostr_event.kind().as_u64() if (EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u16() + 1000 <= nostr_event.kind().as_u16()
<= EventDefinitions.KIND_NIP90_GENERIC.as_u64() + 1000): <= EventDefinitions.KIND_NIP90_GENERIC.as_u16() + 1000):
await handle_nip90_response_event(nostr_event) await handle_nip90_response_event(nostr_event)
elif nostr_event.kind() == EventDefinitions.KIND_FEEDBACK: elif nostr_event.kind() == EventDefinitions.KIND_FEEDBACK:
await handle_nip90_feedback(nostr_event) await handle_nip90_feedback(nostr_event)
@@ -459,7 +459,7 @@ class Bot:
return return
dvms = [x for x in self.dvm_config.SUPPORTED_DVMS if dvms = [x for x in self.dvm_config.SUPPORTED_DVMS if
x.PUBLIC_KEY == nostr_event.author().to_hex() and x.KIND.as_u64() == nostr_event.kind().as_u64() - 1000] x.PUBLIC_KEY == nostr_event.author().to_hex() and x.KIND.as_u16() == nostr_event.kind().as_u16() - 1000]
if len(dvms) > 0: if len(dvms) > 0:
dvm = dvms[0] dvm = dvms[0]
if dvm.dvm_config.EXTERNAL_POST_PROCESS_TYPE != PostProcessFunctionType.NONE: if dvm.dvm_config.EXTERNAL_POST_PROCESS_TYPE != PostProcessFunctionType.NONE:

View File

@@ -91,11 +91,11 @@ class DVM:
async def handle(self, relay_url, subscription_id, nostr_event: Event): async def handle(self, relay_url, subscription_id, nostr_event: Event):
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print(nostr_event.as_json()) print(nostr_event.as_json())
if EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u64() <= nostr_event.kind().as_u64() <= EventDefinitions.KIND_NIP90_GENERIC.as_u64(): if EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u16() <= nostr_event.kind().as_u16() <= EventDefinitions.KIND_NIP90_GENERIC.as_u16():
await handle_nip90_job_event(nostr_event) await handle_nip90_job_event(nostr_event)
elif nostr_event.kind().as_u64() == EventDefinitions.KIND_ZAP.as_u64(): elif nostr_event.kind().as_u16() == EventDefinitions.KIND_ZAP.as_u16():
await handle_zap(nostr_event) await handle_zap(nostr_event)
elif nostr_event.kind().as_u64() == EventDefinitions.KIND_NIP61_NUT_ZAP.as_u64(): elif nostr_event.kind().as_u16() == EventDefinitions.KIND_NIP61_NUT_ZAP.as_u16():
await handle_nutzap(nostr_event) await handle_nutzap(nostr_event)
async def handle_msg(self, relay_url, msg): async def handle_msg(self, relay_url, msg):
@@ -575,7 +575,7 @@ class DVM:
e_tag = Tag.parse(["e", original_event.id().to_hex()]) e_tag = Tag.parse(["e", original_event.id().to_hex()])
p_tag = Tag.parse(["p", original_event.author().to_hex()]) p_tag = Tag.parse(["p", original_event.author().to_hex()])
alt_tag = Tag.parse(["alt", "This is the result of a NIP90 DVM AI task with kind " + str( alt_tag = Tag.parse(["alt", "This is the result of a NIP90 DVM AI task with kind " + str(
original_event.kind().as_u64()) + ". The task was: " + original_event.content()]) original_event.kind().as_u16()) + ". The task was: " + original_event.content()])
status_tag = Tag.parse(["status", "success"]) status_tag = Tag.parse(["status", "success"])
reply_tags = [request_tag, e_tag, p_tag, alt_tag, status_tag] reply_tags = [request_tag, e_tag, p_tag, alt_tag, status_tag]
@@ -607,17 +607,17 @@ 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_u64() + 1000), str(content), reply_tags).to_event( reply_event = EventBuilder(Kind(original_event.kind().as_u16() + 1000), str(content), reply_tags).to_event(
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)
await send_event_outbox(reply_event, client=self.client, dvm_config=self.dvm_config) await send_event_outbox(reply_event, client=self.client, dvm_config=self.dvm_config)
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print(bcolors.GREEN + "[" + self.dvm_config.NIP89.NAME + "] " + str( print(bcolors.GREEN + "[" + self.dvm_config.NIP89.NAME + "] " + str(
original_event.kind().as_u64() + 1000) + " Job Response event sent: " + reply_event.as_json() + bcolors.ENDC) original_event.kind().as_u16() + 1000) + " Job Response event sent: " + reply_event.as_json() + bcolors.ENDC)
elif self.dvm_config.LOGLEVEL.value >= LogLevel.INFO.value: elif self.dvm_config.LOGLEVEL.value >= LogLevel.INFO.value:
print(bcolors.GREEN + "[" + self.dvm_config.NIP89.NAME + "] " + str( print(bcolors.GREEN + "[" + self.dvm_config.NIP89.NAME + "] " + str(
original_event.kind().as_u64() + 1000) + " Job Response event sent: " + reply_event.id().to_hex() + bcolors.ENDC) original_event.kind().as_u16() + 1000) + " Job Response event sent: " + reply_event.id().to_hex() + bcolors.ENDC)
async def send_job_status_reaction(original_event, status, is_paid=True, amount=0, client=None, async def send_job_status_reaction(original_event, status, is_paid=True, amount=0, client=None,
content=None, content=None,
@@ -729,10 +729,10 @@ class DVM:
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print(bcolors.YELLOW + "[" + self.dvm_config.NIP89.NAME + "]" + " Sent Kind " + str( print(bcolors.YELLOW + "[" + self.dvm_config.NIP89.NAME + "]" + " Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u64()) + " Reaction: " + status + " " + reaction_event.as_json() + bcolors.ENDC) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + status + " " + reaction_event.as_json() + bcolors.ENDC)
elif self.dvm_config.LOGLEVEL.value >= LogLevel.INFO.value: elif self.dvm_config.LOGLEVEL.value >= LogLevel.INFO.value:
print(bcolors.YELLOW + "[" + self.dvm_config.NIP89.NAME + "]" + " Sent Kind " + str( print(bcolors.YELLOW + "[" + self.dvm_config.NIP89.NAME + "]" + " Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u64()) + " Reaction: " + status + " " + reaction_event.id().to_hex() + bcolors.ENDC) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + status + " " + reaction_event.id().to_hex() + bcolors.ENDC)
return reaction_event.as_json() return reaction_event.as_json()
@@ -779,8 +779,8 @@ class DVM:
async def do_work(job_event, amount): async def do_work(job_event, amount):
if (( if ((
EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u64() <= job_event.kind().as_u64() <= EventDefinitions.KIND_NIP90_GENERIC.as_u64()) EventDefinitions.KIND_NIP90_EXTRACT_TEXT.as_u16() <= job_event.kind().as_u16() <= EventDefinitions.KIND_NIP90_GENERIC.as_u16())
or job_event.kind().as_u64() == EventDefinitions.KIND_DM.as_u64()): or job_event.kind().as_u16() == EventDefinitions.KIND_DM.as_u16()):
task = await get_task(job_event, client=self.client, dvm_config=self.dvm_config) task = await get_task(job_event, client=self.client, dvm_config=self.dvm_config)

View File

@@ -159,7 +159,7 @@ class Subscription:
reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(keys) reaction_event = EventBuilder(EventDefinitions.KIND_FEEDBACK, str(content), reply_tags).to_event(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_u64()) + " Reaction: " + "success" + " " + reaction_event.as_json()) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + "success" + " " + reaction_event.as_json())
async def pay_zap_split(nwc, overall_amount, zaps, tier, unit="msats"): async def pay_zap_split(nwc, overall_amount, zaps, tier, unit="msats"):
overallsplit = 0 overallsplit = 0

View File

@@ -112,7 +112,7 @@ class DicoverContentLatestLongForm(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(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(signer).opts(opts).build()
await cli.connect() await cli.connect()
@@ -178,7 +178,7 @@ class DicoverContentLatestLongForm(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -112,7 +112,7 @@ class DicoverContentLatestWiki(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(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(signer).opts(opts).build()
await cli.connect() await cli.connect()
@@ -178,7 +178,7 @@ class DicoverContentLatestWiki(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -109,7 +109,7 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
options = self.set_options(request_form) options = self.set_options(request_form)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
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)
@@ -175,7 +175,7 @@ class DicoverContentCurrentlyPopular(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -115,7 +115,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
#keys = Keys.parse(sk.to_hex()) #keys = Keys.parse(sk.to_hex())
#signer = NostrSigner.keys(keys) #signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
#cli = ClientBuilder().database(database).signer(signer).opts(opts).build() #cli = ClientBuilder().database(database).signer(signer).opts(opts).build()
#await cli.connect() #await cli.connect()
@@ -230,7 +230,7 @@ class DicoverContentCurrentlyPopularZaps(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -101,7 +101,7 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(signer).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)
@@ -199,7 +199,7 @@ class DicoverContentCurrentlyPopularFollowers(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -112,7 +112,7 @@ class DicoverContentCurrentlyPopularGallery(DVMTaskInterface):
ns = SimpleNamespace() ns = SimpleNamespace()
options = self.set_options(request_form) options = self.set_options(request_form)
databasegallery = await NostrDatabase.sqlite(self.db_name) databasegallery = NostrDatabase.lmdb(self.db_name)
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)
@@ -250,7 +250,7 @@ class DicoverContentCurrentlyPopularGallery(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -106,6 +106,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
from nostr_sdk import Filter from nostr_sdk import Filter
from types import SimpleNamespace from types import SimpleNamespace
ns = SimpleNamespace() ns = SimpleNamespace()
options = self.set_options(request_form) options = self.set_options(request_form)
@@ -114,9 +115,17 @@ class DicoverContentCurrentlyPopularMostr(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name)
database = NostrDatabase.lmdb(self.db_name)
try:
await database.delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since)))
except Exception as e:
print(e)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).database(database).opts(opts).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)
@@ -153,6 +162,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
# await cli.shutdown() # await cli.shutdown()
return json.dumps(result_list) return json.dumps(result_list)
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():
@@ -183,7 +193,7 @@ class DicoverContentCurrentlyPopularMostr(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:
@@ -221,7 +231,7 @@ class DicoverContentCurrentlyPopularMostr(DVMTaskInterface):
except Exception as e: except Exception as e:
print(e) print(e)
# Do not delete profiles # Do not delete profiles
await cli.database().delete(Filter().kinds([EventDefinitions.KIND_NOTE, EventDefinitions.KIND_ZAP, EventDefinitions.KIND_REPOST, EventDefinitions.KIND_REACTION]).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()
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:

View File

@@ -146,7 +146,7 @@ class DicoverContentCurrentlyPopularNonFollowers(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
if self.database is None: if self.database is None:
self.database = await NostrDatabase.sqlite(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(signer).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST: for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
@@ -230,7 +230,7 @@ class DicoverContentCurrentlyPopularNonFollowers(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -144,21 +144,26 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
options = self.set_options(request_form) options = self.set_options(request_form)
if self.database is None: if self.database is None:
self.database = await NostrDatabase.sqlite(self.db_name) self.database = NostrDatabase.lmdb(self.db_name)
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)
filter1 = Filter().kind(definitions.EventDefinitions.KIND_NOTE).since(since) filters = []
for word in self.search_list:
filter = Filter().kind(definitions.EventDefinitions.KIND_NOTE).since(since).search(word)
filters.append(filter)
events = await self.database.query([filter1])
events = await self.database.query(filters)
if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if self.dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print("[" + self.dvm_config.NIP89.NAME + "] Considering " + str(len(events)) + " Events") print("[" + self.dvm_config.NIP89.NAME + "] Considering " + str(len(events)) + " Events")
ns.finallist = {} ns.finallist = {}
for event in events: for event in events:
if all(ele in event.content().lower() for ele in self.must_list): if all(ele in event.content().lower() for ele in self.must_list):
if any(ele in event.content().lower() for ele in self.search_list): #if any(ele in event.content().lower() for ele in self.search_list):
if not any(ele in event.content().lower() for ele in self.avoid_list): if not any(ele in event.content().lower() for ele in self.avoid_list):
filt = Filter().kinds( filt = Filter().kinds(
[definitions.EventDefinitions.KIND_ZAP, definitions.EventDefinitions.KIND_REACTION, [definitions.EventDefinitions.KIND_ZAP, definitions.EventDefinitions.KIND_REACTION,
@@ -198,7 +203,7 @@ class DicoverContentCurrentlyPopularbyTopic(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -132,7 +132,7 @@ class DicoverContentDBUpdateScheduler(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
if self.database is None: if self.database is None:
self.database = await NostrDatabase.sqlite(self.db_name) self.database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(self.database).opts(opts).build() cli = ClientBuilder().signer(signer).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:

View File

@@ -77,7 +77,7 @@ class DiscoveryBotFarms(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite("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(signer).opts(opts).build()
await cli.add_relay("wss://relay.damus.io") await cli.add_relay("wss://relay.damus.io")
@@ -137,7 +137,7 @@ class DiscoveryBotFarms(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite("db/nostr_profiles.db") database = NostrDatabase.lmdb("db/nostr_profiles.db")
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).database(database).opts(opts).build()
await cli.add_relay("wss://relay.damus.io") await cli.add_relay("wss://relay.damus.io")

View File

@@ -217,7 +217,7 @@ class DiscoverPeopleMyWOT(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:
@@ -257,7 +257,7 @@ async def analyse_users(user_ids=None, dunbar=100000000):
print(npub) print(npub)
print(e) print(e)
database = await NostrDatabase.sqlite("db/nostr_followlists.db") database = NostrDatabase.lmdb("db/nostr_followlists.db")
followers_filter = Filter().authors(user_keys).kind(Kind(3)) followers_filter = Filter().authors(user_keys).kind(Kind(3))
followers = await database.query([followers_filter]) followers = await database.query([followers_filter])
allfriends = [] allfriends = []

View File

@@ -215,7 +215,7 @@ class DiscoverPeopleWOT(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).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:
@@ -255,7 +255,7 @@ async def analyse_users(user_ids=None, dunbar=100000000):
print(npub) print(npub)
print(e) print(e)
database = await NostrDatabase.sqlite("db/nostr_followlists.db") database = NostrDatabase.lmdb("db/nostr_followlists.db")
followers_filter = Filter().authors(user_keys).kind(Kind(3)) followers_filter = Filter().authors(user_keys).kind(Kind(3))
followers = await database.query([followers_filter]) followers = await database.query([followers_filter])
allfriends = [] allfriends = []

View File

@@ -83,7 +83,7 @@ class SearchUser(DVMTaskInterface):
keys = Keys.parse(sk.to_hex()) keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().database(database).signer(signer).opts(opts).build() cli = ClientBuilder().database(database).signer(signer).opts(opts).build()
await cli.add_relay(self.relay) await cli.add_relay(self.relay)
@@ -143,7 +143,7 @@ class SearchUser(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) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite(self.db_name) database = NostrDatabase.lmdb(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).database(database).opts(opts).build()
await cli.add_relay(self.relay) await cli.add_relay(self.relay)

View File

@@ -92,7 +92,7 @@ async def get_task(event, client, dvm_config):
else: else:
for dvm in dvm_config.SUPPORTED_DVMS: for dvm in dvm_config.SUPPORTED_DVMS:
if dvm.KIND.as_u64() == event.kind().as_u64(): if dvm.KIND.as_u16() == event.kind().as_u16():
return dvm.TASK return dvm.TASK
except Exception as e: except Exception as e:
print("Get task: " + str(e)) print("Get task: " + str(e))

View File

@@ -26,7 +26,7 @@ def nip89_create_d_tag(name, pubkey, image):
async def nip89_announce_tasks(dvm_config, client): async def nip89_announce_tasks(dvm_config, client):
k_tag = Tag.parse(["k", str(dvm_config.NIP89.KIND.as_u64())]) k_tag = Tag.parse(["k", str(dvm_config.NIP89.KIND.as_u16())])
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
@@ -65,7 +65,7 @@ async def fetch_nip89_parameters_for_deletion(keys, eventid, client, dvmconfig,
async def nip89_delete_announcement(eid: str, keys: Keys, dtag: str, client: Client, config): async def nip89_delete_announcement(eid: str, keys: Keys, dtag: str, client: Client, config):
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_u64()) + ":" + 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]).to_event(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)
@@ -73,8 +73,8 @@ async def nip89_delete_announcement(eid: str, keys: Keys, dtag: str, client: Cli
async def nip89_delete_announcement_pow(eid: str, keys: Keys, dtag: str, client: Client, config): async def nip89_delete_announcement_pow(eid: str, keys: Keys, dtag: str, client: Client, config):
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_u64()) + ":" + 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_pow_event(keys, 28) event = EventBuilder(Kind(5), "", [e_tag, a_tag]).pow(28).to_event(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)
@@ -91,7 +91,7 @@ async def nip89_fetch_all_dvms(client):
async def nip89_fetch_events_pubkey(client, pubkey, kind): async def nip89_fetch_events_pubkey(client, pubkey, kind):
ktags = [str(kind.as_u64())] 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.get_events_of([nip89filter], relay_timeout)

View File

@@ -6,7 +6,7 @@ from datetime import timedelta
import requests import requests
from nostr_dvm.utils.database_utils import fetch_user_metadata from nostr_dvm.utils.database_utils import fetch_user_metadata
from nostr_dvm.utils.definitions import EventDefinitions from nostr_dvm.utils.definitions import EventDefinitions, relay_timeout, relay_timeout_long
from nostr_dvm.utils.dvmconfig import DVMConfig from nostr_dvm.utils.dvmconfig import DVMConfig
from nostr_dvm.utils.nostr_utils import check_and_set_private_key from nostr_dvm.utils.nostr_utils import check_and_set_private_key
from nostr_dvm.utils.zap_utils import pay_bolt11_ln_bits, zaprequest from nostr_dvm.utils.zap_utils import pay_bolt11_ln_bits, zaprequest
@@ -14,6 +14,7 @@ from nostr_sdk import Tag, Keys, nip44_encrypt, nip44_decrypt, Nip44Version, Eve
EventId, nip04_decrypt, nip04_encrypt, Options, NostrSigner, PublicKey, init_logger, LogLevel, Metadata EventId, nip04_decrypt, nip04_encrypt, Options, NostrSigner, PublicKey, init_logger, LogLevel, Metadata
from nostr_dvm.utils.print import bcolors from nostr_dvm.utils.print import bcolors
class NutWallet(object): class NutWallet(object):
def __init__(self): def __init__(self):
self.name: str = "NutWallet" self.name: str = "NutWallet"
@@ -28,7 +29,7 @@ class NutWallet(object):
self.a: str = "" self.a: str = ""
self.legacy_encryption: bool = False # Use Nip04 instead of Nip44, for reasons, turn to False ASAP. self.legacy_encryption: bool = False # Use Nip04 instead of Nip44, for reasons, turn to False ASAP.
self.trust_unknown_mints: bool = False self.trust_unknown_mints: bool = False
self.missing_balance_strategy: str = "mint" #swap to use existing tokens from other mints (fees!) or mint to mint from lightning self.missing_balance_strategy: str = "mint" #none to do nothing until manually minted, mint to mint from lightning or swap to use existing tokens from other mints (fees!) (not working yet!)
class NutMint(object): class NutMint(object):
@@ -46,7 +47,6 @@ class NutMint(object):
return balance return balance
class NutZapWallet: class NutZapWallet:
async def client_connect(self, relay_list): async def client_connect(self, relay_list):
@@ -72,8 +72,8 @@ class NutZapWallet:
new_nut_wallet.description = description new_nut_wallet.description = description
new_nut_wallet.mints = mint_urls new_nut_wallet.mints = mint_urls
new_nut_wallet.relays = relays new_nut_wallet.relays = relays
new_nut_wallet.d = "wallet" # sha256(str(new_nut_wallet.name + new_nut_wallet.description).encode('utf-8')).hexdigest()[:16] new_nut_wallet.d = "wallet"
new_nut_wallet.a = str(Kind(7375).as_u64()) + ":" + keys.public_key().to_hex() + ":" + new_nut_wallet.d new_nut_wallet.a = str(Kind(7375).as_u16()) + ":" + keys.public_key().to_hex() + ":" + new_nut_wallet.d
print("Creating Wallet..") print("Creating Wallet..")
send_response_id = await self.create_or_update_nut_wallet_event(new_nut_wallet, client, keys) send_response_id = await self.create_or_update_nut_wallet_event(new_nut_wallet, client, keys)
@@ -120,7 +120,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())
wallets = await client.get_events_of([wallet_filter], timedelta(10)) #relay_timeout = EventSource.relays(timedelta(seconds=10))
wallets = await client.get_events_of([wallet_filter], relay_timeout_long)
if len(wallets) > 0: if len(wallets) > 0:
@@ -194,7 +195,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())
proof_events = await client.get_events_of([proof_filter], timedelta(5)) #relay_timeout = EventSource.relays(timedelta(seconds=5))
proof_events = await client.get_events_of([proof_filter], relay_timeout)
latest_proof_sec = 0 latest_proof_sec = 0
latest_proof_event_id = EventId latest_proof_event_id = EventId
@@ -247,7 +249,7 @@ class NutZapWallet:
nut_proof.amount = proof['amount'] nut_proof.amount = proof['amount']
nut_proof.C = proof['C'] nut_proof.C = proof['C']
nut_mint.proofs.append(nut_proof) nut_mint.proofs.append(nut_proof)
#print(proof) # print(proof)
mints = [x for x in nut_wallet.nutmints if x.mint_url == mint_url] mints = [x for x in nut_wallet.nutmints if x.mint_url == mint_url]
if len(mints) == 0: if len(mints) == 0:
@@ -347,8 +349,8 @@ class NutZapWallet:
"secret": proof['secret'], "secret": proof['secret'],
"C": proof['C'] "C": proof['C']
} }
#print("Mint proofs:") # print("Mint proofs:")
#print(proof) # print(proof)
new_proofs.append(proofjson) new_proofs.append(proofjson)
old_event_id = mint.previous_event_id old_event_id = mint.previous_event_id
@@ -447,7 +449,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))
preferences = await client.get_events_of([mint_info_filter], timedelta(5)) #relay_timeout = EventSource.relays(timedelta(seconds=5))
preferences = await client.get_events_of([mint_info_filter], relay_timeout)
mints = [] mints = []
relays = [] relays = []
pubkey = "" pubkey = ""
@@ -517,21 +520,23 @@ class NutZapWallet:
return await self.update_nut_wallet(nut_wallet, [mint_url], client, keys) return await self.update_nut_wallet(nut_wallet, [mint_url], client, keys)
async def handle_low_balance_on_mint(self, nut_wallet, mint_to_send, mint, amount, client, keys):
async def handle_low_balance_on_mint(self, nut_wallet, outgoing_mint_url, mint, amount, client, keys):
required_amount = amount - mint.available_balance() required_amount = amount - mint.available_balance()
if nut_wallet.missing_balance_strategy == "mint": if nut_wallet.missing_balance_strategy == "mint":
await self.mint_cashu(nut_wallet, outgoing_mint_url, client, keys, required_amount) await self.mint_cashu(nut_wallet, mint_to_send, client, keys, required_amount)
elif nut_wallet.missing_balance_strategy == "swap": elif nut_wallet.missing_balance_strategy == "swap":
for nutmint in nut_wallet.nutmints: for nutmint in nut_wallet.nutmints:
estimated_fees = 3 estimated_fees = 3
if nutmint.available_balance() > required_amount+estimated_fees: if nutmint.available_balance() > required_amount + estimated_fees:
await self.swap(required_amount, nutmint.mint_url, outgoing_mint_url) print(nutmint.mint_url)
await self.swap(required_amount, mint_to_send, nutmint.mint_url, nut_wallet)
break break
else:
print(bcolors.RED + "[" + nut_wallet.name + "] Not enough Balance on Mint, mint some tokens first. " + str(
amount) + " " + nut_wallet.unit + bcolors.ENDC)
async def send_nut_zap(self, amount, comment, nut_wallet: NutWallet, zapped_event, zapped_user, client: Client, async def send_nut_zap(self, amount, comment, nut_wallet: NutWallet, zapped_event, zapped_user, client: Client,
keys: Keys): keys: Keys):
@@ -562,7 +567,6 @@ class NutZapWallet:
if mint.available_balance() < amount: if mint.available_balance() < amount:
await self.handle_low_balance_on_mint(nut_wallet, mint_url, mint, amount, client, keys) await self.handle_low_balance_on_mint(nut_wallet, mint_url, mint, amount, client, keys)
# If that's not the case, iterate over the recipents mints and try to mint there. This might be a bit dangerous as not all mints might give cashu, so loss of ln is possible # If that's not the case, iterate over the recipents mints and try to mint there. This might be a bit dangerous as not all mints might give cashu, so loss of ln is possible
if mint_url is None: if mint_url is None:
if nut_wallet.trust_unknown_mints: if nut_wallet.trust_unknown_mints:
@@ -687,7 +691,7 @@ class NutZapWallet:
from cashu.wallet.wallet import Wallet from cashu.wallet.wallet import Wallet
from cashu.core.base import Proof from cashu.core.base import Proof
from cashu.core.crypto.keys import PrivateKey from cashu.core.crypto.keys import PrivateKey
try:
proofs = [] proofs = []
mint_url = "" mint_url = ""
amount = 0 amount = 0
@@ -719,7 +723,7 @@ class NutZapWallet:
) )
cashu_wallet.private_key = PrivateKey(bytes.fromhex(nut_wallet.privkey), raw=True) cashu_wallet.private_key = PrivateKey(bytes.fromhex(nut_wallet.privkey), raw=True)
await cashu_wallet.load_mint() await cashu_wallet.load_mint()
try:
new_proofs, _ = await cashu_wallet.redeem(proofs) new_proofs, _ = await cashu_wallet.redeem(proofs)
mint = self.get_mint(nut_wallet, mint_url) mint = self.get_mint(nut_wallet, mint_url)
print(mint.proofs) print(mint.proofs)
@@ -735,7 +739,6 @@ class NutZapWallet:
print(bcolors.RED + str(e) + bcolors.ENDC) print(bcolors.RED + str(e) + bcolors.ENDC)
return None, message, sender return None, message, sender
async def melt_cashu(self, nut_wallet, mint_url, total_amount, client, keys, lud16=None, npub=None): async def melt_cashu(self, nut_wallet, mint_url, total_amount, client, keys, lud16=None, npub=None):
from cashu.wallet.wallet import Wallet from cashu.wallet.wallet import Wallet
mint = self.get_mint(nut_wallet, mint_url) mint = self.get_mint(nut_wallet, mint_url)
@@ -774,35 +777,43 @@ class NutZapWallet:
total_amount - estimated_fees) + " (Fees: " + str(estimated_fees) + ") " + nut_wallet.unit total_amount - estimated_fees) + " (Fees: " + str(estimated_fees) + ") " + nut_wallet.unit
+ bcolors.ENDC) + bcolors.ENDC)
async def swap(self, amountinsats, outgoing_mint_url, incoming_mint_url): async def swap(self, amountinsats, incoming_mint_url, outgoing_mint_url, nut_wallet):
#TODO this doesn't seem to work yet.
from cashu.wallet.cli.cli_helpers import print_mint_balances from cashu.wallet.cli.cli_helpers import print_mint_balances
from cashu.wallet.wallet import Wallet from cashu.wallet.wallet import Wallet
# print("Select the mint to swap from:") from cashu.core.crypto.keys import PrivateKey
# outgoing_wallet = await get_mint_wallet(ctx, force_select=True)
outgoing_mint = self.get_mint(nut_wallet, outgoing_mint_url)
outgoing_wallet = await Wallet.with_db( outgoing_wallet = await Wallet.with_db(
url=outgoing_mint_url, url=outgoing_mint_url,
db="db/Sender", db="db/Cashu",
name="sender", name="outgoing",
) )
outgoing_wallet.private_key = PrivateKey(bytes.fromhex(nut_wallet.privkey), raw=True)
await outgoing_wallet.load_mint()
outgoing_wallet.proofs = outgoing_mint.proofs
print("Select the mint to swap to:") print(outgoing_wallet.available_balance)
# incoming_wallet = await get_mint_wallet(ctx, force_select=True)
incoming_mint = self.get_mint(nut_wallet, incoming_mint_url)
incoming_wallet = await Wallet.with_db( incoming_wallet = await Wallet.with_db(
url=incoming_mint_url, url=incoming_mint_url,
db="db/Receiver", db="db/Cashu",
name="reeciver", name="incoming",
) )
incoming_wallet.private_key = PrivateKey(bytes.fromhex(nut_wallet.privkey), raw=True)
await incoming_wallet.load_mint() await incoming_wallet.load_mint()
await outgoing_wallet.load_mint() incoming_wallet.proofs = incoming_mint.proofs
if incoming_wallet.url == outgoing_wallet.url: if incoming_wallet.url == outgoing_wallet.url:
raise Exception("mints for swap have to be different") raise Exception("mints for swap have to be different")
print("Incoming Mint units: " + incoming_wallet.unit.name) print("Incoming Mint units: " + incoming_wallet.unit.name)
assert amountinsats > 0, "amount is not positive" assert amountinsats > 0, "amount is not positive"
# request invoice from incoming mint # request invoice from incoming mint
@@ -816,9 +827,13 @@ class NutZapWallet:
send_proofs, fees = await outgoing_wallet.select_to_send( send_proofs, fees = await outgoing_wallet.select_to_send(
outgoing_wallet.proofs, total_amount, set_reserved=True outgoing_wallet.proofs, total_amount, set_reserved=True
) )
try:
await outgoing_wallet.melt( await outgoing_wallet.melt(
send_proofs, invoice.bolt11, quote.fee_reserve, quote.quote proofs=send_proofs, invoice=invoice.bolt11, fee_reserve_sat=quote.fee_reserve, quote_id=quote.quote
) )
except:
print("anyways..")
# mint token in incoming mint # mint token in incoming mint
await incoming_wallet.mint(amountinsats, id=invoice.id) await incoming_wallet.mint(amountinsats, id=invoice.id)

View File

@@ -318,9 +318,9 @@ async def send_job_status_reaction(original_event_id_hex, original_event_author_
if dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value: if dvm_config.LOGLEVEL.value >= LogLevel.DEBUG.value:
print(bcolors.YELLOW + "[" + dvm_config.NIP89.NAME + "]" + " Sent Kind " + str( print(bcolors.YELLOW + "[" + dvm_config.NIP89.NAME + "]" + " Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u64()) + " Reaction: " + status + " " + reaction_event.as_json() + bcolors.ENDC) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + status + " " + reaction_event.as_json() + bcolors.ENDC)
elif dvm_config.LOGLEVEL.value >= LogLevel.INFO.value: elif dvm_config.LOGLEVEL.value >= LogLevel.INFO.value:
print(bcolors.YELLOW + "[" + dvm_config.NIP89.NAME + "]" + " Sent Kind " + str( print(bcolors.YELLOW + "[" + dvm_config.NIP89.NAME + "]" + " Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK.as_u64()) + " Reaction: " + status + " " + reaction_event.id().to_hex() + bcolors.ENDC) EventDefinitions.KIND_FEEDBACK.as_u16()) + " Reaction: " + status + " " + reaction_event.id().to_hex() + bcolors.ENDC)
return reaction_event.as_json() return reaction_event.as_json()

View File

@@ -51,7 +51,7 @@ async def parse_zap_event_tags(zap_event, keys, name, client, config):
keys.secret_key(), keys.secret_key(),
zap_request_event.author()) zap_request_event.author())
decrypted_private_event = Event.from_json(decrypted_content) decrypted_private_event = Event.from_json(decrypted_content)
if decrypted_private_event.kind().as_u64() == 9733: if decrypted_private_event.kind().as_u16() == 9733:
sender = decrypted_private_event.author().to_hex() sender = decrypted_private_event.author().to_hex()
message = decrypted_private_event.content() message = decrypted_private_event.content()
# if message != "": # if message != "":

View File

@@ -8,7 +8,7 @@ print(keys.public_key().to_bech32())
async def reconcile_db(): async def reconcile_db():
# Create/open SQLite database # Create/open SQLite database
database = await NostrDatabase.sqlite("nostr.db") database = NostrDatabase.lmdb("nostr.db")
# NOT AVAILABLE ON WINDOWS AT THE MOMENT! # NOT AVAILABLE ON WINDOWS AT THE MOMENT!
# Create/open nostrdb database # Create/open nostrdb database
@@ -28,7 +28,7 @@ async def reconcile_db():
await do_some_work() await do_some_work()
async def do_some_work(): async def do_some_work():
database = await NostrDatabase.sqlite("nostr.db") database = NostrDatabase.lmdb("nostr.db")
f = Filter().author(keys.public_key()).limit(10) f = Filter().author(keys.public_key()).limit(10)
events = await database.query([f]) events = await database.query([f])

View File

@@ -37,12 +37,12 @@ rebroadcast_NIP65_Relay_List = True
update_profile = False update_profile = False
global_update_rate = 180 # set this high on first sync so db can fully sync before another process trys to. global_update_rate = 180 # set this high on first sync so db can fully sync before another process trys to.
use_logger = False use_logger = True
log_level = LogLevel.INFO log_level = LogLevel.INFO
RECONCILE_DB_RELAY_LIST = [ "wss://nostr.oxtr.dev", "wss://relay.damus.io", "wss://relay.primal.net"]
RECONCILE_DB_RELAY_LIST = [ "wss://relay.nostr.net", "wss://relay.damus.io", "wss://nostr.oxtr.dev"]
RELAY_LIST = ["wss://relay.primal.net", RELAY_LIST = ["wss://relay.primal.net",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://nostr.mom", "wss://nostr.oxtr.dev",
"wss://relay.nostr.net" "wss://relay.nostr.net"
@@ -630,7 +630,7 @@ def build_example_oneperfollow(name, identifier, admin_config, options, image, c
async def init_db(database): async def init_db(database):
return await NostrDatabase.sqlite(database) return NostrDatabase.lmdb(database)
def playground(): def playground():

View File

@@ -8,6 +8,7 @@ from duck_chat import ModelType
from nostr_sdk import Kind, Filter, PublicKey, SecretKey, Keys, NostrSigner, RelayLimits, Options, Client, Tag, \ from nostr_sdk import Kind, Filter, PublicKey, SecretKey, Keys, NostrSigner, RelayLimits, Options, Client, Tag, \
LogLevel, Timestamp, NostrDatabase LogLevel, Timestamp, NostrDatabase
from nostr_dvm.tasks.content_discovery_currently_popular_topic import DicoverContentCurrentlyPopularbyTopic
from nostr_dvm.tasks.generic_dvm import GenericDVM from nostr_dvm.tasks.generic_dvm import GenericDVM
from nostr_dvm.utils import definitions from nostr_dvm.utils import definitions
from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.admin_utils import AdminConfig
@@ -50,7 +51,7 @@ def playground(announce=False):
dvm_config = build_default_config(identifier) dvm_config = build_default_config(identifier)
dvm_config.KIND = Kind(kind) # Manually set the Kind Number (see data-vending-machines.org) dvm_config.KIND = Kind(kind) # Manually set the Kind Number (see data-vending-machines.org)
dvm_config.CUSTOM_PROCESSING_MESSAGE = "Creating a personalized feed based on the topics you write about. This might take a moment." dvm_config.CUSTOM_PROCESSING_MESSAGE = "Creating a personalized feed based on the topics you write about. This might take a moment."
dvm_config.FIX_COST = 10 dvm_config.FIX_COST = 0
admin_config.DELETE_NIP89 = True admin_config.DELETE_NIP89 = True
@@ -79,15 +80,14 @@ def playground(announce=False):
"input": "How do you call a noisy ostrich?", "input": "How do you call a noisy ostrich?",
} }
dvm = GenericDVM(name=name, dvm_config=dvm_config, nip89config=nip89config, dvm = DicoverContentCurrentlyPopularbyTopic(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options) admin_config=admin_config, options=options)
async def process_request(request_form, prompt): async def process_request(options, prompt):
result = "" result = ""
try: try:
from duck_chat import DuckChat from duck_chat import DuckChat
options = dvm.set_options(request_form)
result = "" result = ""
async with DuckChat(model=ModelType.GPT4o) as chat: async with DuckChat(model=ModelType.GPT4o) as chat:
query = prompt query = prompt
@@ -133,7 +133,7 @@ def playground(announce=False):
prompt = "Only reply with the result. Here is a list of notes, seperated by ;. Find the 20 most important keywords and return them by a comma seperated list: " + text prompt = "Only reply with the result. Here is a list of notes, seperated by ;. Find the 20 most important keywords and return them by a comma seperated list: " + text
#loop = asyncio.get_running_loop() #loop = asyncio.get_running_loop()
result = asyncio.run(process_request(request_form, prompt)) result = await process_request(options, prompt)
content = "I identified these as your topics:\n\n"+result.replace(",", ", ") + "\n\nProcessing, just a few more seconds..." content = "I identified these as your topics:\n\n"+result.replace(",", ", ") + "\n\nProcessing, just a few more seconds..."
await send_job_status_reaction(original_event_id_hex=dvm.options["request_event_id"], original_event_author_hex=dvm.options["request_event_author"], client=cli, dvm_config=dvm_config, content=content) await send_job_status_reaction(original_event_id_hex=dvm.options["request_event_id"], original_event_author_hex=dvm.options["request_event_author"], client=cli, dvm_config=dvm_config, content=content)
@@ -148,7 +148,7 @@ def playground(announce=False):
from types import SimpleNamespace from types import SimpleNamespace
ns = SimpleNamespace() ns = SimpleNamespace()
database = await NostrDatabase.sqlite("db/nostr_recent_notes.db") database = NostrDatabase.lmdb("db/nostr_recent_notes.db")
timestamp_since = Timestamp.now().as_secs() - since timestamp_since = Timestamp.now().as_secs() - since
since = Timestamp.from_secs(timestamp_since) since = Timestamp.from_secs(timestamp_since)

View File

@@ -444,18 +444,18 @@ async def nostr_client():
# await nostr_client_test_translation("44a0a8b395ade39d46b9d20038b3f0c8a11168e67c442e3ece95e4a1703e2beb", "event", "zh", 20, 20) # await nostr_client_test_translation("44a0a8b395ade39d46b9d20038b3f0c8a11168e67c442e3ece95e4a1703e2beb", "event", "zh", 20, 20)
#await nostr_client_test_image("a beautiful purple ostrich watching the sunset, eating a cashew nut") #await nostr_client_test_image("a beautiful purple ostrich watching the sunset, eating a cashew nut")
#await nostr_client_custom_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "7a63849b684d90c0de983492578b12e147e56f5d79ed6585cc64e5aa8a122744") await nostr_client_custom_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "7a63849b684d90c0de983492578b12e147e56f5d79ed6585cc64e5aa8a122744")
#"a018ba05af400b52772e33162d8326fca4a167fe7b6d3cd2382e14cac2af6841" #"a018ba05af400b52772e33162d8326fca4a167fe7b6d3cd2382e14cac2af6841"
#await nostr_client_duckduck_test(PublicKey.parse("aa8ab5b774d47e7b29a985dd739cfdcccf93451678bf7977ba1b2e094ecd8b30").to_hex() , "How do i create a dockerfile for python 3.12") # await nostr_client_duckduck_test(PublicKey.parse("7a63849b684d90c0de983492578b12e147e56f5d79ed6585cc64e5aa8a122744").to_hex() , "How do i create a dockerfile for python 3.12")
await nostr_client_flux_schnell("d57f1efb7582f58cade6f482d53eefa998d8082711b996aae3dc5f5527cbdd6e" , "topics") #await nostr_client_flux_schnell("d57f1efb7582f58cade6f482d53eefa998d8082711b996aae3dc5f5527cbdd6e" , "topics")
# await nostr_client_test_search_profile("dontbelieve") # await nostr_client_test_search_profile("dontbelieve")
#wot = ["99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64"] #wot = ["99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64"]
# await nostr_client_test_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "ab6cdf12ca3ae5109416295b8cd8a53fdec3a9d54beb7a9aee0ebfb67cb4edf7") #await nostr_client_test_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "ab6cdf12ca3ae5109416295b8cd8a53fdec3a9d54beb7a9aee0ebfb67cb4edf7")
# await nostr_client_test_discovery_gallery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "4add3944eb596a27a650f9b954f5ed8dfefeec6ca50473605b0fbb058dd11306") # await nostr_client_test_discovery_gallery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "4add3944eb596a27a650f9b954f5ed8dfefeec6ca50473605b0fbb058dd11306")
# await nostr_client_test_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", #await nostr_client_test_discovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64",
# "2cf10ff849d2769b2b021bd93a0270d03eecfd14126d07f94c6ca2269cb3f3b1") # "7a63849b684d90c0de983492578b12e147e56f5d79ed6585cc64e5aa8a122744")
# await nostr_client_test_censor_filter(wot) # await nostr_client_test_censor_filter(wot)
# await nostr_client_test_inactive_filter("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64") # await nostr_client_test_inactive_filter("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64")
@@ -486,7 +486,7 @@ async def nostr_client():
print( print(
bcolors.BLUE + f"Received new event from {relay_url}: {event.as_json()}" + bcolors.ENDC) bcolors.BLUE + f"Received new event from {relay_url}: {event.as_json()}" + bcolors.ENDC)
if event.kind().as_u64() == 7000: if event.kind().as_u16() == 7000:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
amount_sats = 0 amount_sats = 0
status = "" status = ""
@@ -512,15 +512,15 @@ async def nostr_client():
keys) keys)
elif 6000 < event.kind().as_u64() < 6999: elif 6000 < event.kind().as_u16() < 6999:
print("[Nostr Client]: " + event.as_json()) print("[Nostr Client]: " + event.as_json())
print("[Nostr Client]: " + event.content()) print("[Nostr Client]: " + event.content())
elif event.kind().as_u64() == 4: elif event.kind().as_u16() == 4:
dec_text = nip04_decrypt(sk, event.author(), event.content()) dec_text = nip04_decrypt(sk, event.author(), event.content())
print("[Nostr Client]: " + f"Received new msg: {dec_text}") print("[Nostr Client]: " + f"Received new msg: {dec_text}")
elif event.kind().as_u64() == 9735: elif event.kind().as_u16() == 9735:
print("[Nostr Client]: " + f"Received new zap:") print("[Nostr Client]: " + f"Received new zap:")
print(event.as_json()) print(event.as_json())

View File

@@ -57,7 +57,7 @@ async def sync_db():
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5))) opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=5)))
keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj") keys = Keys.parse("nsec1zmzllu40a7mr7ztl78uwfwslnp0pn0pww868adl05x52d4la237s6m8qfj")
signer = NostrSigner.keys(keys) signer = NostrSigner.keys(keys)
database = await NostrDatabase.sqlite("db/nostr_followlists.db") database = NostrDatabase.lmdb("db/nostr_followlists.db")
cli = ClientBuilder().signer(signer).database(database).opts(opts).build() cli = ClientBuilder().signer(signer).database(database).opts(opts).build()
await cli.add_relay("wss://relay.damus.io") # TODO ADD MORE await cli.add_relay("wss://relay.damus.io") # TODO ADD MORE
@@ -86,7 +86,7 @@ async def analyse_users(user_ids=None):
print(npub) print(npub)
print(e) print(e)
database = await NostrDatabase.sqlite("db/nostr_followlists.db") database = NostrDatabase.lmdb("db/nostr_followlists.db")
followers_filter = Filter().authors(user_keys).kind(Kind(3)) followers_filter = Filter().authors(user_keys).kind(Kind(3))
followers = await database.query([followers_filter]) followers = await database.query([followers_filter])
allfriends = [] allfriends = []