mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-04-10 04:39:16 +02:00
Merge branch 'main' into nserver-modules
This commit is contained in:
commit
c422b18ba3
12
.env_example
12
.env_example
@ -1,8 +1,13 @@
|
||||
# Optional LNBITS options to create invoices (if empty, it will use the lud16 from profile)
|
||||
# Admin Key is (only) required for bot or if any payments should be made
|
||||
LNBITS_INVOICE_KEY = ""
|
||||
|
||||
#Create an account with a lnbits instance of your choice, add the admin key and id here. This account will be used to create a new lnbits wallet for each dvm/bot
|
||||
LNBITS_ADMIN_KEY = "" # In order to pay invoices, e.g. from the bot to DVMs, or reimburse users. Keep this secret and use responsibly.
|
||||
LNBITS_ADMIN_ID = ""
|
||||
LNBITS_HOST = "https://lnbits.com"
|
||||
# In order to create a zappable lightning address, host nostdress on your domain or use this preinstalled domain.
|
||||
# We will use the api to create and manage zapable lightning addresses
|
||||
NOSTDRESS_DOMAIN = "nostrdvm.com"
|
||||
|
||||
#Backend Specific Options for tasks that require them. A DVM needing these should only be started if these are set.
|
||||
|
||||
@ -14,4 +19,7 @@ N_SERVER = "" # Enter the address of a n-server instance, locally or on a machi
|
||||
|
||||
# We will automatically create dtags and private keys based on the identifier variable in main.
|
||||
# If your DVM already has a dtag and private key you can replace it here before publishing the DTAG to not create a new one.
|
||||
# The name and NIP90 info of the DVM can be changed but the identifier must stay the same in order to not create a different dtag.
|
||||
# The name and NIP90 info of the DVM can be changed but the identifier must stay the same in order to not create a different dtag.
|
||||
|
||||
# We will also create new wallets on the given lnbits instance for each dvm. If you want to use an existing wallet, you can replace the parameters here as well.
|
||||
# Make sure you backup this file to keep access to your wallets
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -166,8 +166,10 @@ outputs
|
||||
app_deploy.py
|
||||
app.py
|
||||
app_deploy.py
|
||||
db/Cashu/wallet.sqlite3
|
||||
|
||||
db/*
|
||||
.idea/misc.xml
|
||||
.idea/misc.xml
|
||||
backends/nserver/cache/*
|
||||
backends/nserver/modules/image_upscale/weights/*
|
||||
backends/nserver/venv
|
||||
backends/nserver/cache
|
||||
backends/nserver/modules/image_upscale/weights
|
||||
|
@ -11,7 +11,7 @@ This means the project is in alpha status, interfaces might still change/break a
|
||||
|
||||
Create a new venv by running `"python -m venv venv"`
|
||||
- Place .env file (based on .env_example) in main folder.
|
||||
- the feamework will automatically create keys for your dvms in this file.
|
||||
- the framework will automatically create keys for your dvms in this file.
|
||||
- Install requirements.txt
|
||||
- Run python main.py.
|
||||
|
||||
|
42
bot/bot.py
42
bot/bot.py
@ -298,6 +298,7 @@ class Bot:
|
||||
print("Receiver has no Lightning address")
|
||||
return
|
||||
try:
|
||||
print(bolt11)
|
||||
payment_hash = pay_bolt11_ln_bits(bolt11, self.dvm_config)
|
||||
self.job_list[self.job_list.index(entry)]['is_paid'] = True
|
||||
print("[" + self.NAME + "] payment_hash: " + payment_hash +
|
||||
@ -366,16 +367,39 @@ class Bot:
|
||||
self.keys, self.NAME,
|
||||
self.client, self.dvm_config)
|
||||
|
||||
user = get_or_add_user(self.dvm_config.DB, sender, client=self.client, config=self.dvm_config)
|
||||
if zapped_event is not None:
|
||||
if not anon:
|
||||
print("[" + self.NAME + "] Note Zap received for Bot balance: " + str(
|
||||
invoice_amount) + " Sats from " + str(
|
||||
user.name))
|
||||
update_user_balance(self.dvm_config.DB, sender, invoice_amount, client=self.client,
|
||||
config=self.dvm_config)
|
||||
etag = ""
|
||||
for tag in zap_event.tags():
|
||||
if tag.as_vec()[0] == "e":
|
||||
etag = tag.as_vec()[1]
|
||||
|
||||
# a regular note
|
||||
|
||||
user = get_or_add_user(self.dvm_config.DB, sender, client=self.client, config=self.dvm_config)
|
||||
|
||||
|
||||
entry = next((x for x in self.job_list if x['event_id'] == etag), None)
|
||||
print(entry)
|
||||
#print(entry['dvm_key'])
|
||||
# print(str(zapped_event.pubkey().to_hex()))
|
||||
# print(str(zap_event.pubkey().to_hex()))
|
||||
print(sender)
|
||||
if entry is not None and entry['is_paid'] is True and entry['dvm_key'] == sender:
|
||||
# if we get a bolt11, we pay and move on
|
||||
user = get_or_add_user(db=self.dvm_config.DB, npub=entry["npub"],
|
||||
client=self.client, config=self.dvm_config)
|
||||
|
||||
print("HELLO: " + user.name)
|
||||
sender = user.npub
|
||||
#print(zap_event.as_json())
|
||||
|
||||
if zapped_event is not None:
|
||||
if not anon:
|
||||
print("[" + self.NAME + "] Note Zap received for Bot balance: " + str(
|
||||
invoice_amount) + " Sats from " + str(
|
||||
user.name))
|
||||
update_user_balance(self.dvm_config.DB, sender, invoice_amount, client=self.client,
|
||||
config=self.dvm_config)
|
||||
|
||||
# a regular note
|
||||
elif not anon:
|
||||
print("[" + self.NAME + "] Profile Zap received for Bot balance: " + str(
|
||||
invoice_amount) + " Sats from " + str(
|
||||
|
58
core/dvm.py
58
core/dvm.py
@ -15,7 +15,8 @@ from utils.database_utils import create_sql_table, get_or_add_user, update_user_
|
||||
from utils.mediasource_utils import input_data_file_duration
|
||||
from utils.nostr_utils import get_event_by_id, get_referenced_event_by_id, send_event, check_and_decrypt_tags
|
||||
from utils.output_utils import build_status_reaction
|
||||
from utils.zap_utils import check_bolt11_ln_bits_is_paid, create_bolt11_ln_bits, parse_zap_event_tags
|
||||
from utils.zap_utils import check_bolt11_ln_bits_is_paid, create_bolt11_ln_bits, parse_zap_event_tags, \
|
||||
parse_amount_from_bolt11_invoice, zap, pay_bolt11_ln_bits
|
||||
from utils.cashu_utils import redeem_cashu
|
||||
|
||||
use_logger = False
|
||||
@ -115,7 +116,8 @@ class DVM:
|
||||
cashu_redeemed = False
|
||||
if cashu != "":
|
||||
print(cashu)
|
||||
cashu_redeemed, cashu_message, redeem_amount, fees = redeem_cashu(cashu, self.dvm_config, self.client, int(amount))
|
||||
cashu_redeemed, cashu_message, redeem_amount, fees = redeem_cashu(cashu, self.dvm_config,
|
||||
self.client, int(amount))
|
||||
print(cashu_message)
|
||||
if cashu_message != "success":
|
||||
send_job_status_reaction(nip90_event, "error", False, amount, self.client, cashu_message,
|
||||
@ -131,7 +133,10 @@ class DVM:
|
||||
send_job_status_reaction(nip90_event, "processing", True, 0,
|
||||
client=self.client, dvm_config=self.dvm_config)
|
||||
|
||||
do_work(nip90_event)
|
||||
# when we reimburse users on error make sure to not send anything if it was free
|
||||
if user.iswhitelisted or task_is_free:
|
||||
amount = 0
|
||||
do_work(nip90_event, amount)
|
||||
# if task is directed to us via p tag and user has balance, do the job and update balance
|
||||
elif p_tag_str == self.dvm_config.PUBLIC_KEY and user.balance >= int(amount):
|
||||
balance = max(user.balance - int(amount), 0)
|
||||
@ -147,7 +152,7 @@ class DVM:
|
||||
send_job_status_reaction(nip90_event, "processing", True, 0,
|
||||
client=self.client, dvm_config=self.dvm_config)
|
||||
|
||||
do_work(nip90_event)
|
||||
do_work(nip90_event, amount)
|
||||
|
||||
# else send a payment required event to user
|
||||
elif p_tag_str == "" or p_tag_str == self.dvm_config.PUBLIC_KEY:
|
||||
@ -228,10 +233,10 @@ class DVM:
|
||||
# If payment-required appears before processing
|
||||
self.job_list.pop(index)
|
||||
print("Starting work...")
|
||||
do_work(job_event)
|
||||
do_work(job_event, invoice_amount)
|
||||
else:
|
||||
print("Job not in List, but starting work...")
|
||||
do_work(job_event)
|
||||
do_work(job_event, invoice_amount)
|
||||
|
||||
else:
|
||||
send_job_status_reaction(job_event, "payment-rejected",
|
||||
@ -314,17 +319,14 @@ class DVM:
|
||||
|
||||
task = get_task(original_event, self.client, self.dvm_config)
|
||||
for dvm in self.dvm_config.SUPPORTED_DVMS:
|
||||
if task == dvm.TASK:
|
||||
try:
|
||||
post_processed = dvm.post_process(data, original_event)
|
||||
send_nostr_reply_event(post_processed, original_event.as_json())
|
||||
except Exception as e:
|
||||
send_job_status_reaction(original_event, "error", content=str(e),
|
||||
if task == dvm.TASK:
|
||||
try:
|
||||
post_processed = dvm.post_process(data, original_event)
|
||||
send_nostr_reply_event(post_processed, original_event.as_json())
|
||||
except Exception as e:
|
||||
send_job_status_reaction(original_event, "error", content=str(e),
|
||||
dvm_config=self.dvm_config,
|
||||
)
|
||||
|
||||
|
||||
|
||||
)
|
||||
|
||||
def send_nostr_reply_event(content, original_event_as_str):
|
||||
original_event = Event.from_json(original_event_as_str)
|
||||
@ -443,7 +445,7 @@ class DVM:
|
||||
EventDefinitions.KIND_FEEDBACK) + " Reaction: " + status + " " + reaction_event.as_json())
|
||||
return reaction_event.as_json()
|
||||
|
||||
def do_work(job_event):
|
||||
def do_work(job_event, amount):
|
||||
if ((EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= job_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC)
|
||||
or job_event.kind() == EventDefinitions.KIND_DM):
|
||||
|
||||
@ -460,14 +462,27 @@ class DVM:
|
||||
send_nostr_reply_event(post_processed, job_event.as_json())
|
||||
except Exception as e:
|
||||
send_job_status_reaction(job_event, "error", content=str(e),
|
||||
dvm_config=self.dvm_config,
|
||||
)
|
||||
dvm_config=self.dvm_config)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
# we could send the exception here to the user, but maybe that's not a good idea after all.
|
||||
send_job_status_reaction(job_event, "error", content="An error occurred",
|
||||
dvm_config=self.dvm_config)
|
||||
# TODO send sats back on error
|
||||
# Zapping back the user on error
|
||||
if amount > 0:
|
||||
user = get_or_add_user(self.dvm_config.DB, job_event.pubkey().to_hex(),
|
||||
client=self.client, config=self.dvm_config)
|
||||
print(user.lud16 + " " + str(amount))
|
||||
bolt11 = zap(user.lud16, amount, "Couldn't finish job, returning sats", job_event,
|
||||
self.keys, self.dvm_config, zaptype="private")
|
||||
if bolt11 is None:
|
||||
print("Receiver has no Lightning address, can't zap back.")
|
||||
return
|
||||
try:
|
||||
payment_hash = pay_bolt11_ln_bits(bolt11, self.dvm_config)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
return
|
||||
|
||||
@ -484,7 +499,8 @@ class DVM:
|
||||
client=self.client,
|
||||
dvm_config=self.dvm_config)
|
||||
print("[" + self.dvm_config.NIP89.NAME + "] doing work from joblist")
|
||||
do_work(job.event)
|
||||
amount = parse_amount_from_bolt11_invoice(job.bolt11)
|
||||
do_work(job.event, amount)
|
||||
elif ispaid is None: # invoice expired
|
||||
self.job_list.remove(job)
|
||||
|
||||
|
14
main.py
14
main.py
@ -19,6 +19,8 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.external_dvm_utils import build_external_dvm
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.output_utils import PostProcessFunctionType
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
|
||||
def playground():
|
||||
@ -26,10 +28,13 @@ def playground():
|
||||
# Note this is very basic for now and still under development
|
||||
bot_config = DVMConfig()
|
||||
bot_config.PRIVATE_KEY = check_and_set_private_key("bot")
|
||||
bot_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
bot_config.LNBITS_ADMIN_KEY = os.getenv("LNBITS_ADMIN_KEY") # The bot will forward zaps for us, use responsibly
|
||||
npub = Keys.from_sk_str(bot_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_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 back
|
||||
bot_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
|
||||
|
||||
# Generate an optional Admin Config, in this case, whenever we give our DVMs this config, they will (re)broadcast
|
||||
# their NIP89 announcement
|
||||
# You can create individual admins configs and hand them over when initializing the dvm,
|
||||
@ -37,10 +42,13 @@ def playground():
|
||||
# If you use this global config, options will be set for all dvms that use it.
|
||||
admin_config = AdminConfig()
|
||||
admin_config.REBROADCAST_NIP89 = False
|
||||
admin_config.LUD16 = lnaddress
|
||||
# Set rebroadcast to true once you have set your NIP89 descriptions and d tags. You only need to rebroadcast once you
|
||||
# want to update your NIP89 descriptions
|
||||
|
||||
# Update the DVMs (not the bot) profile. For example after you updated the NIP89 or the lnaddress, you can automatically update profiles here.
|
||||
admin_config.UPDATE_PROFILE = False
|
||||
admin_config.LUD16 = ""
|
||||
|
||||
|
||||
# Spawn some DVMs in the playground and run them
|
||||
# You can add arbitrary DVMs there and instantiate them here
|
||||
|
@ -17,6 +17,7 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import get_event_by_id, check_and_set_private_key
|
||||
from utils.output_utils import post_process_list_to_users, post_process_list_to_events
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
|
||||
"""
|
||||
This File contains a Module to search for notes
|
||||
@ -143,8 +144,12 @@ class AdvancedSearch(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
# Add NIP89
|
||||
nip90params = {
|
||||
"user": {
|
||||
|
@ -15,6 +15,8 @@ from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.mediasource_utils import organize_input_media_data
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.output_utils import upload_media_to_hoster
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to call Google Translate Services locally on the DVM Machine
|
||||
@ -87,8 +89,12 @@ class MediaConverter(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
# Add NIP89
|
||||
nip90params = {
|
||||
"media_format": {
|
||||
|
@ -17,6 +17,7 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import get_event_by_id, check_and_set_private_key
|
||||
from utils.output_utils import post_process_list_to_users
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
|
||||
"""
|
||||
This File contains a Module to find inactive follows for a user on nostr
|
||||
@ -174,8 +175,12 @@ class DiscoverInactiveFollows(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
# Add NIP89
|
||||
nip90params = {
|
||||
"user": {
|
||||
|
@ -15,7 +15,8 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.output_utils import upload_media_to_hoster
|
||||
from utils.zap_utils import get_price_per_sat
|
||||
from utils.zap_utils import get_price_per_sat, check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to transform Text input on OpenAI's servers with DALLE-3 and receive results back.
|
||||
@ -127,8 +128,12 @@ class ImageGenerationDALLE(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
profit_in_sats = 10
|
||||
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
|
||||
|
||||
|
@ -15,7 +15,8 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.output_utils import upload_media_to_hoster
|
||||
from utils.zap_utils import get_price_per_sat
|
||||
from utils.zap_utils import get_price_per_sat, check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to transform Text input on NOVA-Server and receive results back.
|
||||
@ -122,8 +123,12 @@ class ImageGenerationReplicateSDXL(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
profit_in_sats = 10
|
||||
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
|
||||
|
||||
|
@ -14,6 +14,8 @@ from utils.mediasource_utils import organize_input_media_data
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.definitions import EventDefinitions
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to transform a media file input on Google Cloud
|
||||
@ -133,8 +135,12 @@ class SpeechToTextGoogle(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
options = {'api_key': None}
|
||||
# A module might have options it can be initialized with, here we set a default model, and the server
|
||||
# address it should use. These parameters can be freely defined in the task component
|
||||
|
@ -12,6 +12,8 @@ from utils.definitions import EventDefinitions
|
||||
from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import get_event_by_id, check_and_set_private_key
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to extract Text from a PDF file locally on the DVM Machine
|
||||
@ -96,8 +98,12 @@ class TextExtractionPDF(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
# Add NIP89
|
||||
nip90params = {}
|
||||
nip89info = {
|
||||
|
@ -11,6 +11,8 @@ from utils.definitions import EventDefinitions
|
||||
from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id, check_and_set_private_key
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to call Google Translate Services locally on the DVM Machine
|
||||
@ -113,8 +115,12 @@ class TranslationGoogle(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
|
||||
nip90params = {
|
||||
"language": {
|
||||
|
@ -12,6 +12,8 @@ from utils.definitions import EventDefinitions
|
||||
from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id, check_and_set_private_key
|
||||
from utils.zap_utils import check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to call Google Translate Services locally on the DVM Machine
|
||||
@ -110,8 +112,12 @@ class TranslationLibre(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
|
||||
options = {'libre_end_point': os.getenv("LIBRE_TRANSLATE_ENDPOINT"),
|
||||
'libre_api_key': os.getenv("LIBRE_TRANSLATE_API_KEY")}
|
||||
|
@ -16,7 +16,8 @@ from utils.dvmconfig import DVMConfig
|
||||
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||
from utils.nostr_utils import check_and_set_private_key
|
||||
from utils.output_utils import upload_media_to_hoster
|
||||
from utils.zap_utils import get_price_per_sat
|
||||
from utils.zap_utils import get_price_per_sat, check_and_set_ln_bits_keys
|
||||
from nostr_sdk import Keys
|
||||
|
||||
"""
|
||||
This File contains a Module to transform an image to a short video clip using Stable Video Diffusion with replicate
|
||||
@ -113,8 +114,12 @@ class VideoGenerationReplicateSVD(DVMTaskInterface):
|
||||
def build_example(name, identifier, admin_config):
|
||||
dvm_config = DVMConfig()
|
||||
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||
npub = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_bech32()
|
||||
invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys(identifier, npub)
|
||||
dvm_config.LNBITS_INVOICE_KEY = invoice_key
|
||||
dvm_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
|
||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||
admin_config.LUD16 = lnaddress
|
||||
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))
|
||||
@ -136,6 +141,7 @@ def build_example(name, identifier, admin_config):
|
||||
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)
|
||||
|
||||
|
||||
|
@ -150,9 +150,9 @@ def update_profile(dvm_config, client, lud16=""):
|
||||
.set_display_name(name) \
|
||||
.set_about(about) \
|
||||
.set_picture(image) \
|
||||
.set_lud16(lud16)
|
||||
.set_lud16(lud16) \
|
||||
.set_nip05(lud16)
|
||||
# .set_banner("https://example.com/banner.png") \
|
||||
# .set_nip05("username@example.com") \
|
||||
|
||||
print(f"Setting profile metadata for {keys.public_key().to_bech32()}...")
|
||||
print(metadata.as_json())
|
||||
|
@ -1,18 +1,29 @@
|
||||
# LIGHTNING/CASHU/ZAP FUNCTIONS
|
||||
# LIGHTNING/ZAP FUNCTIONS
|
||||
import json
|
||||
import os
|
||||
import urllib.parse
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
from bech32 import bech32_decode, convertbits, bech32_encode
|
||||
from nostr_sdk import nostr_sdk, PublicKey, SecretKey, Event, EventBuilder, Tag, Keys
|
||||
from utils.dvmconfig import DVMConfig
|
||||
from utils.nostr_utils import get_event_by_id, check_and_decrypt_own_tags
|
||||
from utils.nostr_utils import get_event_by_id, check_and_decrypt_own_tags, update_profile
|
||||
import lnurl
|
||||
from hashlib import sha256
|
||||
import dotenv
|
||||
|
||||
|
||||
# TODO tor connection to lnbits
|
||||
# proxies = {
|
||||
# 'http': 'socks5h://127.0.0.1:9050',
|
||||
# 'https': 'socks5h://127.0.0.1:9050'
|
||||
# }
|
||||
|
||||
proxies = {}
|
||||
|
||||
def parse_zap_event_tags(zap_event, keys, name, client, config):
|
||||
zapped_event = None
|
||||
invoice_amount = 0
|
||||
@ -116,12 +127,34 @@ def create_bolt11_lud16(lud16, amount):
|
||||
except:
|
||||
return None
|
||||
|
||||
def create_lnbits_account(name):
|
||||
if os.getenv("LNBITS_ADMIN_ID") is None or os.getenv("LNBITS_ADMIN_ID") == "":
|
||||
print("No admin id set, no wallet created.")
|
||||
return
|
||||
data = {
|
||||
'admin_id': os.getenv("LNBITS_ADMIN_ID"),
|
||||
'wallet_name': name,
|
||||
'user_name': name,
|
||||
}
|
||||
try:
|
||||
json_object = json.dumps(data)
|
||||
url = os.getenv("LNBITS_HOST") + '/usermanager/api/v1/users'
|
||||
print(url)
|
||||
headers = {'X-API-Key': os.getenv("LNBITS_ADMIN_KEY"), 'Content-Type': 'application/json', 'charset': 'UTF-8'}
|
||||
r = requests.post(url, data=json_object, headers=headers, proxies=proxies)
|
||||
walletjson = json.loads(r.text)
|
||||
print(walletjson)
|
||||
if walletjson.get("wallets"):
|
||||
return walletjson['wallets'][0]['inkey'], walletjson['wallets'][0]['adminkey'], walletjson['wallets'][0]['id'], walletjson['id'], "success"
|
||||
except:
|
||||
print("error creating wallet")
|
||||
|
||||
|
||||
def check_bolt11_ln_bits_is_paid(payment_hash: str, config: DVMConfig):
|
||||
url = config.LNBITS_URL + "/api/v1/payments/" + payment_hash
|
||||
headers = {'X-API-Key': config.LNBITS_INVOICE_KEY, 'Content-Type': 'application/json', 'charset': 'UTF-8'}
|
||||
try:
|
||||
res = requests.get(url, headers=headers)
|
||||
res = requests.get(url, headers=headers, proxies=proxies)
|
||||
obj = json.loads(res.text)
|
||||
if obj.get("paid"):
|
||||
return obj["paid"]
|
||||
@ -264,3 +297,74 @@ def get_price_per_sat(currency):
|
||||
price_currency_per_sat = 0.0004
|
||||
|
||||
return price_currency_per_sat
|
||||
|
||||
|
||||
|
||||
def make_ln_address_nostdress(identifier, npub, pin, nostdressdomain):
|
||||
#env_path = Path('.env')
|
||||
#if env_path.is_file():
|
||||
# dotenv.load_dotenv(env_path, verbose=True, override=True)
|
||||
|
||||
|
||||
print(os.getenv("LNBITS_INVOICE_KEY_" + identifier.upper()))
|
||||
data = {
|
||||
'name': identifier,
|
||||
'domain': nostdressdomain,
|
||||
'kind': "lnbits",
|
||||
'host': os.getenv("LNBITS_HOST"),
|
||||
'key': os.getenv("LNBITS_INVOICE_KEY_" + identifier.upper()),
|
||||
'pin': pin,
|
||||
'npub': npub,
|
||||
'currentname': " "
|
||||
}
|
||||
|
||||
|
||||
try:
|
||||
url = "https://" + nostdressdomain + "/api/easy/"
|
||||
res = requests.post(url, data=data)
|
||||
print(res.text)
|
||||
obj = json.loads(res.text)
|
||||
|
||||
if obj.get("ok"):
|
||||
return identifier + "@" + nostdressdomain, obj["pin"]
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return "", ""
|
||||
|
||||
def check_and_set_ln_bits_keys(identifier, npub):
|
||||
|
||||
if not os.getenv("LNBITS_INVOICE_KEY_" + identifier.upper()):
|
||||
invoicekey, adminkey, walletid, userid, success = create_lnbits_account(identifier)
|
||||
add_key_to_env_file("LNBITS_INVOICE_KEY_" + identifier.upper(), invoicekey)
|
||||
add_key_to_env_file("LNBITS_ADMIN_KEY_" + identifier.upper(), adminkey)
|
||||
add_key_to_env_file("LNBITS_USER_ID_" + identifier.upper(), userid)
|
||||
add_key_to_env_file("LNBITS_WALLET_ID_" + identifier.upper(), userid)
|
||||
|
||||
lnaddress = ""
|
||||
pin = ""
|
||||
if os.getenv("NOSTDRESS_DOMAIN"):
|
||||
print(os.getenv("NOSTDRESS_DOMAIN"))
|
||||
lnaddress, pin = make_ln_address_nostdress(identifier, npub, " ", os.getenv("NOSTDRESS_DOMAIN"))
|
||||
add_key_to_env_file("LNADDRESS_" + identifier.upper(), lnaddress)
|
||||
add_key_to_env_file("LNADDRESS_PIN_" + identifier.upper(), pin)
|
||||
|
||||
return invoicekey, adminkey, userid, walletid, lnaddress
|
||||
else:
|
||||
return (os.getenv("LNBITS_INVOICE_KEY_" + identifier.upper()),
|
||||
os.getenv("LNBITS_ADMIN_KEY_" + identifier.upper()),
|
||||
os.getenv("LNBITS_USER_ID_" + identifier.upper()),
|
||||
os.getenv("LNBITS_WALLET_ID_" + identifier.upper()),
|
||||
os.getenv("LNADDRESS_" + identifier.upper()))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def add_key_to_env_file(value, oskey):
|
||||
env_path = Path('.env')
|
||||
if env_path.is_file():
|
||||
dotenv.load_dotenv(env_path, verbose=True, override=True)
|
||||
dotenv.set_key(env_path, value, oskey)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user