some fixes, updated readme

This commit is contained in:
Believethehype
2023-11-20 23:18:05 +01:00
parent 13bffaea96
commit 2e1920a940
6 changed files with 249 additions and 241 deletions

View File

@@ -10,3 +10,11 @@ Place .env file (based on .env_example) in main folder, install requirements.txt
Use vendata.io to create a nip89 announcement of your dvm and save the dtag in your .env config. Use vendata.io to create a nip89 announcement of your dvm and save the dtag in your .env config.
A tutorial on how to add additional tasks, as well as the larger server backend will be added soon. A tutorial on how to add additional tasks, as well as the larger server backend will be added soon.
Known Issues:
- After refactoring DVMs work independent from each other for the most part.
- They currently still share a joblist and might act weird together (TODO rework joblist)
- Some functions might work easier than they did before (need some refactoring)
- Bot currently not implemented
- Some basic functionality is still missing, e.g. handling various mediasources
- Interface might still change a lot and brick things.

452
dvm.py
View File

@@ -60,161 +60,159 @@ class DVM:
def handle(self, relay_url, nostr_event): def handle(self, relay_url, nostr_event):
print(f"[Nostr] Received new NIP90 Job Request from {relay_url}: {nostr_event.as_json()}") print(f"[Nostr] Received new NIP90 Job Request from {relay_url}: {nostr_event.as_json()}")
if EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= nostr_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC: if EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= nostr_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC:
self.handle_nip90_job_event(nostr_event) handle_nip90_job_event(nostr_event)
elif nostr_event.kind() == EventDefinitions.KIND_ZAP: elif nostr_event.kind() == EventDefinitions.KIND_ZAP:
self.handle_zap(nostr_event) handle_zap(nostr_event)
def handle_msg(self, relay_url, msg): def handle_msg(self, relay_url, msg):
return return
def handle_nip90_job_event(self, nip90_event): def handle_nip90_job_event(nip90_event):
user = get_or_add_user(nip90_event.pubkey().to_hex()) user = get_or_add_user(nip90_event.pubkey().to_hex())
task_supported, task, duration = check_task_is_supported(nip90_event, client=self.client, task_supported, task, duration = check_task_is_supported(nip90_event, client=self.client,
get_duration=(not user.iswhitelisted), get_duration=(not user.iswhitelisted),
config=self.dvm_config) config=self.dvm_config)
print(task) print(task)
if user.isblacklisted: if user.isblacklisted:
send_job_status_reaction(nip90_event, "error", client=self.client, config=self.dvm_config) send_job_status_reaction(nip90_event, "error", client=self.client, config=self.dvm_config)
print("[Nostr] Request by blacklisted user, skipped") print("[Nostr] Request by blacklisted user, skipped")
elif task_supported: elif task_supported:
print("Received new Task: " + task) print("Received new Task: " + task)
amount = get_amount_per_task(task, self.dvm_config, duration) amount = get_amount_per_task(task, self.dvm_config, duration)
if amount is None: if amount is None:
return return
task_is_free = False task_is_free = False
for dvm in self.dvm_config.SUPPORTED_TASKS: for dvm in self.dvm_config.SUPPORTED_TASKS:
if dvm.TASK == task and dvm.COST == 0: if dvm.TASK == task and dvm.COST == 0:
task_is_free = True task_is_free = True
if user.iswhitelisted or task_is_free: if user.iswhitelisted or task_is_free:
print("[Nostr] Free or Whitelisted for task " + task + ". Starting processing..") print("[Nostr] Free or Whitelisted for task " + task + ". Starting processing..")
send_job_status_reaction(nip90_event, "processing", True, 0, client=self.client, send_job_status_reaction(nip90_event, "processing", True, 0, client=self.client,
config=self.dvm_config) config=self.dvm_config)
do_work(nip90_event, is_from_bot=False) do_work(nip90_event, is_from_bot=False)
# otherwise send payment request # otherwise send payment request
else:
bid = 0
for tag in nip90_event.tags():
if tag.as_vec()[0] == 'bid':
bid = int(tag.as_vec()[1])
print("[Nostr][Payment required] New Nostr " + task + " Job event: " + nip90_event.as_json())
if bid > 0:
bid_offer = int(bid / 1000)
if bid_offer >= amount:
send_job_status_reaction(nip90_event, "payment-required", False,
amount, # bid_offer
client=self.client, config=self.dvm_config)
else: # If there is no bid, just request server rate from user
print("[Nostr] Requesting payment for Event: " + nip90_event.id().to_hex())
send_job_status_reaction(nip90_event, "payment-required",
False, amount, client=self.client, config=self.dvm_config)
else: else:
print("Task not supported on this DVM, skipping..") bid = 0
for tag in nip90_event.tags():
if tag.as_vec()[0] == 'bid':
bid = int(tag.as_vec()[1])
def handle_zap(self, event): print("[Nostr][Payment required] New Nostr " + task + " Job event: " + nip90_event.as_json())
zapped_event = None if bid > 0:
invoice_amount = 0 bid_offer = int(bid / 1000)
anon = False if bid_offer >= amount:
sender = event.pubkey() send_job_status_reaction(nip90_event, "payment-required", False,
amount, # bid_offer
client=self.client, config=self.dvm_config)
try: else: # If there is no bid, just request server rate from user
for tag in event.tags(): print("[Nostr] Requesting payment for Event: " + nip90_event.id().to_hex())
if tag.as_vec()[0] == 'bolt11': send_job_status_reaction(nip90_event, "payment-required",
invoice_amount = parse_bolt11_invoice(tag.as_vec()[1]) False, amount, client=self.client, config=self.dvm_config)
elif tag.as_vec()[0] == 'e': else:
zapped_event = get_event_by_id(tag.as_vec()[1], config=self.dvm_config) print("Task not supported on this DVM, skipping..")
elif tag.as_vec()[0] == 'description':
zap_request_event = Event.from_json(tag.as_vec()[1])
sender = check_for_zapplepay(zap_request_event.pubkey().to_hex(),
zap_request_event.content())
for ztag in zap_request_event.tags():
if ztag.as_vec()[0] == 'anon':
if len(ztag.as_vec()) > 1:
print("Private Zap received.")
decrypted_content = decrypt_private_zap_message(ztag.as_vec()[1],
self.keys.secret_key(),
zap_request_event.pubkey())
decrypted_private_event = Event.from_json(decrypted_content)
if decrypted_private_event.kind() == 9733:
sender = decrypted_private_event.pubkey().to_hex()
message = decrypted_private_event.content()
if message != "":
print("Zap Message: " + message)
else:
anon = True
print("Anonymous Zap received. Unlucky, I don't know from whom, and never will")
user = get_or_add_user(sender)
print(str(user))
if zapped_event is not None: def handle_zap(event):
if zapped_event.kind() == EventDefinitions.KIND_FEEDBACK: # if a reaction by us got zapped zapped_event = None
if not self.dvm_config.IS_BOT: invoice_amount = 0
print("Zap received for NIP90 task: " + str(invoice_amount) + " Sats from " + str( anon = False
user.name)) sender = event.pubkey()
amount = 0 print("Zap received")
job_event = None
for tag in zapped_event.tags():
if tag.as_vec()[0] == 'amount':
amount = int(float(tag.as_vec()[1]) / 1000)
elif tag.as_vec()[0] == 'e':
job_event = get_event_by_id(tag.as_vec()[1], config=self.dvm_config)
task_supported, task, duration = check_task_is_supported(job_event, client=self.client, try:
get_duration=False, for tag in event.tags():
config=self.dvm_config) if tag.as_vec()[0] == 'bolt11':
if job_event is not None and task_supported: invoice_amount = parse_bolt11_invoice(tag.as_vec()[1])
if amount <= invoice_amount: elif tag.as_vec()[0] == 'e':
print("[Nostr] Payment-request fulfilled...") zapped_event = get_event_by_id(tag.as_vec()[1], config=self.dvm_config)
send_job_status_reaction(job_event, "processing", client=self.client, elif tag.as_vec()[0] == 'description':
config=self.dvm_config) zap_request_event = Event.from_json(tag.as_vec()[1])
indices = [i for i, x in enumerate(job_list) if sender = check_for_zapplepay(zap_request_event.pubkey().to_hex(),
x.event_id == job_event.id().to_hex()] zap_request_event.content())
index = -1 for ztag in zap_request_event.tags():
if len(indices) > 0: if ztag.as_vec()[0] == 'anon':
index = indices[0] if len(ztag.as_vec()) > 1:
if index > -1: print("Private Zap received.")
if job_list[index].is_processed: # If payment-required appears a processing decrypted_content = decrypt_private_zap_message(ztag.as_vec()[1],
job_list[index].is_paid = True self.keys.secret_key(),
check_and_return_event(job_list[index].result, zap_request_event.pubkey())
str(job_event.as_json()), decrypted_private_event = Event.from_json(decrypted_content)
dvm_key=self.dvm_config.PRIVATE_KEY) if decrypted_private_event.kind() == 9733:
elif not (job_list[index]).is_processed: sender = decrypted_private_event.pubkey().to_hex()
# If payment-required appears before processing message = decrypted_private_event.content()
job_list.pop(index) if message != "":
print("Starting work...") print("Zap Message: " + message)
do_work(job_event, is_from_bot=False) else:
else: anon = True
print("Job not in List, but starting work...") print("Anonymous Zap received. Unlucky, I don't know from whom, and never will")
do_work(job_event, is_from_bot=False) user = get_or_add_user(sender)
print(str(user))
else: if zapped_event is not None:
send_job_status_reaction(job_event, "payment-rejected", if zapped_event.kind() == EventDefinitions.KIND_FEEDBACK: # if a reaction by us got zapped
False, invoice_amount, client=self.client, print("Zap received for NIP90 task: " + str(invoice_amount) + " Sats from " + str(
config=self.dvm_config) user.name))
print("[Nostr] Invoice was not paid sufficiently") amount = 0
job_event = None
for tag in zapped_event.tags():
if tag.as_vec()[0] == 'amount':
amount = int(float(tag.as_vec()[1]) / 1000)
elif tag.as_vec()[0] == 'e':
job_event = get_event_by_id(tag.as_vec()[1], config=self.dvm_config)
elif zapped_event.kind() in EventDefinitions.ANY_RESULT: task_supported, task, duration = check_task_is_supported(job_event, client=self.client,
print("Someone zapped the result of an exisiting Task. Nice") get_duration=False,
elif not anon and not self.dvm_config.PASSIVE_MODE: config=self.dvm_config)
print("Note Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str( if job_event is not None and task_supported:
user.name)) if amount <= invoice_amount:
update_user_balance(sender, invoice_amount, config=self.dvm_config) print("[Nostr] Payment-request fulfilled...")
send_job_status_reaction(job_event, "processing", client=self.client,
config=self.dvm_config)
indices = [i for i, x in enumerate(job_list) if
x.event_id == job_event.id().to_hex()]
index = -1
if len(indices) > 0:
index = indices[0]
if index > -1:
if job_list[index].is_processed: # If payment-required appears a processing
job_list[index].is_paid = True
check_and_return_event(job_list[index].result,
str(job_event.as_json()),
dvm_key=self.dvm_config.PRIVATE_KEY)
elif not (job_list[index]).is_processed:
# If payment-required appears before processing
job_list.pop(index)
print("Starting work...")
do_work(job_event, is_from_bot=False)
else:
print("Job not in List, but starting work...")
do_work(job_event, is_from_bot=False)
# a regular note else:
elif not anon and not self.dvm_config.PASSIVE_MODE: send_job_status_reaction(job_event, "payment-rejected",
print("Profile Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str( False, invoice_amount, client=self.client,
config=self.dvm_config)
print("[Nostr] Invoice was not paid sufficiently")
elif zapped_event.kind() in EventDefinitions.ANY_RESULT:
print("Someone zapped the result of an exisiting Task. Nice")
elif not anon:
print("Note Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str(
user.name)) user.name))
update_user_balance(sender, invoice_amount, config=self.dvm_config) update_user_balance(sender, invoice_amount, config=self.dvm_config)
except Exception as e: # a regular note
print(f"Error during content decryption: {e}") elif not anon:
print("Profile Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str(
user.name))
update_user_balance(sender, invoice_amount, config=self.dvm_config)
except Exception as e:
print(f"Error during content decryption: {e}")
def check_event_has_not_unfinished_job_input(nevent, append, client, dvmconfig): def check_event_has_not_unfinished_job_input(nevent, append, client, dvmconfig):
task_supported, task, duration = check_task_is_supported(nevent, client, False, config=dvmconfig) task_supported, task, duration = check_task_is_supported(nevent, client, False, config=dvmconfig)
@@ -237,14 +235,12 @@ class DVM:
job = RequiredJobToWatch(event=nevent, timestamp=Timestamp.now().as_secs()) job = RequiredJobToWatch(event=nevent, timestamp=Timestamp.now().as_secs())
jobs_on_hold_list.append(job) jobs_on_hold_list.append(job)
send_job_status_reaction(nevent, "chain-scheduled", True, 0, client=client, send_job_status_reaction(nevent, "chain-scheduled", True, 0, client=client,
config=dvmconfig) config=dvmconfig)
return False return False
else: else:
return True return True
def check_and_return_event(data, original_event_str: str, dvm_key=""): def check_and_return_event(data, original_event_str: str, dvm_key=""):
original_event = Event.from_json(original_event_str) original_event = Event.from_json(original_event_str)
keys = Keys.from_sk_str(dvm_key) keys = Keys.from_sk_str(dvm_key)
@@ -258,10 +254,10 @@ class DVM:
if self.dvm_config.SHOWRESULTBEFOREPAYMENT and not is_paid: if self.dvm_config.SHOWRESULTBEFOREPAYMENT and not is_paid:
send_nostr_reply_event(data, original_event_str, key=keys) send_nostr_reply_event(data, original_event_str, key=keys)
send_job_status_reaction(original_event, "success", amount, send_job_status_reaction(original_event, "success", amount,
config=self.dvm_config) # or payment-required, or both? config=self.dvm_config) # or payment-required, or both?
elif not self.dvm_config.SHOWRESULTBEFOREPAYMENT and not is_paid: elif not self.dvm_config.SHOWRESULTBEFOREPAYMENT and not is_paid:
send_job_status_reaction(original_event, "success", amount, send_job_status_reaction(original_event, "success", amount,
config=self.dvm_config) # or payment-required, or both? config=self.dvm_config) # or payment-required, or both?
if self.dvm_config.SHOWRESULTBEFOREPAYMENT and is_paid: if self.dvm_config.SHOWRESULTBEFOREPAYMENT and is_paid:
job_list.remove(x) job_list.remove(x)
@@ -337,97 +333,98 @@ class DVM:
send_event(evt, key=keys) send_event(evt, key=keys)
def send_job_status_reaction(original_event, status, is_paid=True, amount=0, client=None, def send_job_status_reaction(original_event, status, is_paid=True, amount=0, client=None,
content=None, content=None,
config=None, config=None,
key=None): key=None):
dvmconfig = config dvmconfig = config
alt_description = "This is a reaction to a NIP90 DVM AI task. " alt_description = "This is a reaction to a NIP90 DVM AI task. "
task = get_task(original_event, client=client, dvmconfig=dvmconfig) task = get_task(original_event, client=client, dvmconfig=dvmconfig)
if status == "processing": if status == "processing":
alt_description = "NIP90 DVM AI task " + task + " started processing. " alt_description = "NIP90 DVM AI task " + task + " started processing. "
reaction = alt_description + emoji.emojize(":thumbs_up:") reaction = alt_description + emoji.emojize(":thumbs_up:")
elif status == "success": elif status == "success":
alt_description = "NIP90 DVM AI task " + task + " finished successfully. " alt_description = "NIP90 DVM AI task " + task + " finished successfully. "
reaction = alt_description + emoji.emojize(":call_me_hand:") reaction = alt_description + emoji.emojize(":call_me_hand:")
elif status == "chain-scheduled": elif status == "chain-scheduled":
alt_description = "NIP90 DVM AI task " + task + " Chain Task scheduled" alt_description = "NIP90 DVM AI task " + task + " Chain Task scheduled"
reaction = alt_description + emoji.emojize(":thumbs_up:") reaction = alt_description + emoji.emojize(":thumbs_up:")
elif status == "error": elif status == "error":
alt_description = "NIP90 DVM AI task " + task + " had an error. " alt_description = "NIP90 DVM AI task " + task + " had an error. "
if content is None: if content is None:
reaction = alt_description + emoji.emojize(":thumbs_down:")
else:
reaction = alt_description + emoji.emojize(":thumbs_down:") + content
elif status == "payment-required":
alt_description = "NIP90 DVM AI task " + task + " requires payment of min " + str(
amount) + " Sats. "
reaction = alt_description + emoji.emojize(":orange_heart:")
elif status == "payment-rejected":
alt_description = "NIP90 DVM AI task " + task + " payment is below required amount of " + str(
amount) + " Sats. "
reaction = alt_description + emoji.emojize(":thumbs_down:")
elif status == "user-blocked-from-service":
alt_description = "NIP90 DVM AI task " + task + " can't be performed. User has been blocked from Service. "
reaction = alt_description + emoji.emojize(":thumbs_down:") reaction = alt_description + emoji.emojize(":thumbs_down:")
else: else:
reaction = emoji.emojize(":thumbs_down:") reaction = alt_description + emoji.emojize(":thumbs_down:") + content
e_tag = Tag.parse(["e", original_event.id().to_hex()]) elif status == "payment-required":
p_tag = Tag.parse(["p", original_event.pubkey().to_hex()])
alt_tag = Tag.parse(["alt", alt_description])
status_tag = Tag.parse(["status", status])
tags = [e_tag, p_tag, alt_tag, status_tag]
if status == "success" or status == "error": # alt_description = "NIP90 DVM AI task " + task + " requires payment of min " + str(
for x in job_list: amount) + " Sats. "
if x.event_id == original_event.id(): reaction = alt_description + emoji.emojize(":orange_heart:")
is_paid = x.is_paid
amount = x.amount
break
bolt11 = "" elif status == "payment-rejected":
payment_hash = "" alt_description = "NIP90 DVM AI task " + task + " payment is below required amount of " + str(
expires = original_event.created_at().as_secs() + (60 * 60 * 24) amount) + " Sats. "
if status == "payment-required" or (status == "processing" and not is_paid): reaction = alt_description + emoji.emojize(":thumbs_down:")
if dvmconfig.LNBITS_INVOICE_KEY != "": elif status == "user-blocked-from-service":
try: alt_description = "NIP90 DVM AI task " + task + " can't be performed. User has been blocked from Service. "
bolt11, payment_hash = create_bolt11_ln_bits(amount, dvmconfig) reaction = alt_description + emoji.emojize(":thumbs_down:")
except Exception as e: else:
print(e) reaction = emoji.emojize(":thumbs_down:")
if not any(x.event_id == original_event.id().to_hex() for x in job_list): e_tag = Tag.parse(["e", original_event.id().to_hex()])
job_list.append( p_tag = Tag.parse(["p", original_event.pubkey().to_hex()])
JobToWatch(event_id=original_event.id().to_hex(), alt_tag = Tag.parse(["alt", alt_description])
timestamp=original_event.created_at().as_secs(), status_tag = Tag.parse(["status", status])
amount=amount, tags = [e_tag, p_tag, alt_tag, status_tag]
is_paid=is_paid,
status=status, result="", is_processed=False, bolt11=bolt11,
payment_hash=payment_hash,
expires=expires, from_bot=False))
print(str(job_list))
if status == "payment-required" or status == "payment-rejected" or (
status == "processing" and not is_paid) or (
status == "success" and not is_paid):
if dvmconfig.LNBITS_INVOICE_KEY != "": if status == "success" or status == "error": #
amount_tag = Tag.parse(["amount", str(amount * 1000), bolt11]) for x in job_list:
else: if x.event_id == original_event.id():
amount_tag = Tag.parse(["amount", str(amount * 1000)]) # to millisats is_paid = x.is_paid
tags.append(amount_tag) amount = x.amount
if key is not None: break
keys = Keys.from_sk_str(key)
bolt11 = ""
payment_hash = ""
expires = original_event.created_at().as_secs() + (60 * 60 * 24)
if status == "payment-required" or (status == "processing" and not is_paid):
if dvmconfig.LNBITS_INVOICE_KEY != "":
try:
bolt11, payment_hash = create_bolt11_ln_bits(amount, dvmconfig)
except Exception as e:
print(e)
if not any(x.event_id == original_event.id().to_hex() for x in job_list):
job_list.append(
JobToWatch(event_id=original_event.id().to_hex(),
timestamp=original_event.created_at().as_secs(),
amount=amount,
is_paid=is_paid,
status=status, result="", is_processed=False, bolt11=bolt11,
payment_hash=payment_hash,
expires=expires, from_bot=False))
print(str(job_list))
if status == "payment-required" or status == "payment-rejected" or (
status == "processing" and not is_paid) or (
status == "success" and not is_paid):
if dvmconfig.LNBITS_INVOICE_KEY != "":
amount_tag = Tag.parse(["amount", str(amount * 1000), bolt11])
else: else:
keys = Keys.from_sk_str(dvmconfig.PRIVATE_KEY) amount_tag = Tag.parse(["amount", str(amount * 1000)]) # to millisats
event = EventBuilder(EventDefinitions.KIND_FEEDBACK, reaction, tags).to_event(keys) tags.append(amount_tag)
if key is not None:
keys = Keys.from_sk_str(key)
else:
keys = Keys.from_sk_str(dvmconfig.PRIVATE_KEY)
event = EventBuilder(EventDefinitions.KIND_FEEDBACK, reaction, tags).to_event(keys)
send_event(event, key=keys)
print(
"[Nostr] Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK) + " Reaction: " + status + " " + event.as_json())
return event.as_json()
send_event(event, key=keys)
print(
"[Nostr] Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK) + " Reaction: " + status + " " + event.as_json())
return event.as_json()
def do_work(job_event, is_from_bot=False): def do_work(job_event, is_from_bot=False):
if (( if ((
EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= job_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC) EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= job_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC)
@@ -442,7 +439,7 @@ class DVM:
self.dvm_config) self.dvm_config)
result = dvm.process(request_form) result = dvm.process(request_form)
check_and_return_event(result, str(job_event.as_json()), check_and_return_event(result, str(job_event.as_json()),
dvm_key=self.dvm_config.PRIVATE_KEY) dvm_key=self.dvm_config.PRIVATE_KEY)
except Exception as e: except Exception as e:
print(e) print(e)
@@ -458,8 +455,8 @@ class DVM:
event = get_event_by_id(job.event_id, config=self.dvm_config) event = get_event_by_id(job.event_id, config=self.dvm_config)
if event is not None: if event is not None:
send_job_status_reaction(event, "processing", True, 0, send_job_status_reaction(event, "processing", True, 0,
client=self.client, client=self.client,
config=self.dvm_config) config=self.dvm_config)
print("do work from joblist") print("do work from joblist")
do_work(event, is_from_bot=False) do_work(event, is_from_bot=False)
@@ -477,15 +474,14 @@ class DVM:
for job in jobs_on_hold_list: for job in jobs_on_hold_list:
if check_event_has_not_unfinished_job_input(job.event, False, client=self.client, if check_event_has_not_unfinished_job_input(job.event, False, client=self.client,
dvmconfig=self.dvm_config): dvmconfig=self.dvm_config):
# handle_nip90_job_event(event=job.event) handle_nip90_job_event(nip90_event=job.event)
try: try:
jobs_on_hold_list.remove(job) jobs_on_hold_list.remove(job)
except: except:
continue continue
if Timestamp.now().as_secs() > job.timestamp + 60 * 20: # remove jobs to look for after 20 minutes.. if Timestamp.now().as_secs() > job.timestamp + 60 * 20: # remove jobs to look for after 20 minutes..
jobs_on_hold_list.remove(job) jobs_on_hold_list.remove(job)
time.sleep(1.0) time.sleep(2.0)

16
main.py
View File

@@ -67,20 +67,18 @@ def run_nostr_dvm_with_local_config():
dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY) dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY)
dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST) dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST)
unstableartist = ImageGenerationSDXL("Unstable Diffusion", dvm_config, "unstable") #unstableartist = ImageGenerationSDXL("Unstable Diffusion", dvm_config, "unstable")
d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG) #d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG)
content = "{\"name\":\"" + unstableartist.NAME + ("\",\"image\":\"https://image.nostr.build" #content = "{\"name\":\"" + unstableartist.NAME + ("\",\"image\":\"https://image.nostr.build"
"/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg" # "/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg"
"\",\"about\":\"I draw images based on a prompt with a Model called unstable diffusion.\",\"nip90Params\":{}}") # "\",\"about\":\"I draw images based on a prompt with a Model called unstable diffusion.\",\"nip90Params\":{}}")
dvm_config.NIP89s.append(unstableartist.NIP89_announcement(d_tag, content)) #dvm_config.NIP89s.append(unstableartist.NIP89_announcement(d_tag, content))
# Spawn another Instance of text-to-image but use a different model and lora this time.
dvm_config = DVMConfig() dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = "73b262d31edc6ea1316dffcc7daa772651d661e6475761b7b78291482c1bf5cb" dvm_config.PRIVATE_KEY = "73b262d31edc6ea1316dffcc7daa772651d661e6475761b7b78291482c1bf5cb"
dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY) dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY)
dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST) dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST)
# Spawn another Instance of text-to-image but use a different model and lora this time.
sketcher = ImageGenerationSDXL("Sketcher", dvm_config, "mohawk", "timburton") sketcher = ImageGenerationSDXL("Sketcher", dvm_config, "mohawk", "timburton")
d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG2) d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG2)
content = "{\"name\":\"" + sketcher.NAME + ("\",\"image\":\"https://image.nostr.build" content = "{\"name\":\"" + sketcher.NAME + ("\",\"image\":\"https://image.nostr.build"

View File

@@ -21,7 +21,7 @@ class ImageGenerationSDXL(DVMTaskInterface):
NAME: str NAME: str
KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
TASK: str = "text-to-image" TASK: str = "text-to-image"
COST: int = 50 COST: int = 5
PK: str PK: str
def __init__(self, name, dvm_config, default_model=None, default_lora=None): def __init__(self, name, dvm_config, default_model=None, default_lora=None):

View File

@@ -10,6 +10,8 @@ import pandas
''' '''
Post process results to either given output format or a Nostr readable plain text. Post process results to either given output format or a Nostr readable plain text.
''' '''
def post_process_result(anno, original_event): def post_process_result(anno, original_event):
print("post-processing...") print("post-processing...")
if isinstance(anno, pandas.DataFrame): # if input is an anno we parse it to required output format if isinstance(anno, pandas.DataFrame): # if input is an anno we parse it to required output format
@@ -85,13 +87,15 @@ def post_process_result(anno, original_event):
elif isinstance(anno, NoneType): elif isinstance(anno, NoneType):
return "An error occurred" return "An error occurred"
else: else:
result = replace_broken_words(anno) #TODO result = replace_broken_words(anno) # TODO
return result return result
''' '''
Convenience function to replace words like Noster with Nostr Convenience function to replace words like Noster with Nostr
''' '''
def replace_broken_words(text): def replace_broken_words(text):
result = (text.replace("Noster", "Nostr").replace("Nostra", "Nostr").replace("no stir", "Nostr"). result = (text.replace("Noster", "Nostr").replace("Nostra", "Nostr").replace("no stir", "Nostr").
replace("Nostro", "Nostr").replace("Impub", "npub").replace("sets", "Sats")) replace("Nostro", "Nostr").replace("Impub", "npub").replace("sets", "Sats"))
@@ -103,12 +107,14 @@ Function to upload to Nostr.build and if it fails to Nostrfiles.dev
Larger files than these hosters allow and fallback is catbox currently. Larger files than these hosters allow and fallback is catbox currently.
Will probably need to switch to another system in the future. Will probably need to switch to another system in the future.
''' '''
def uploadMediaToHoster(filepath): def uploadMediaToHoster(filepath):
print("Uploading image: " + filepath) print("Uploading image: " + filepath)
try: try:
files = {'file': open(filepath, 'rb')} files = {'file': open(filepath, 'rb')}
file_stats = os.stat(filepath) file_stats = os.stat(filepath)
sizeinmb = file_stats.st_size / (1024*1024) sizeinmb = file_stats.st_size / (1024 * 1024)
print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.") print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.")
if sizeinmb > 25: if sizeinmb > 25:
uploader = CatboxUploader(filepath) uploader = CatboxUploader(filepath)

View File

@@ -43,7 +43,7 @@ def create_bolt11_ln_bits(sats, config):
obj = json.loads(res.text) obj = json.loads(res.text)
return obj["payment_request"], obj["payment_hash"] return obj["payment_request"], obj["payment_hash"]
except Exception as e: except Exception as e:
print(e) print("LNBITS: " + str(e))
return None return None