From 68e6727afc1695a2f803b8f2bdf771e2f628aeb2 Mon Sep 17 00:00:00 2001 From: Believethehype <1097224+believethehype@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:18:29 +0100 Subject: [PATCH] option and fixes for not providing an invoice directly --- nostr_dvm/dvm.py | 8 +-- nostr_dvm/utils/dvmconfig.py | 1 + tests/otherstuff.py | 18 ++++++- ui/noogle/src/components/ImageGeneration.vue | 49 +++++-------------- ui/noogle/src/components/helper/Zap.vue | 51 ++++++++++++++++++-- 5 files changed, 79 insertions(+), 48 deletions(-) diff --git a/nostr_dvm/dvm.py b/nostr_dvm/dvm.py index dd341cd..cca37f1 100644 --- a/nostr_dvm/dvm.py +++ b/nostr_dvm/dvm.py @@ -446,7 +446,7 @@ class DVM: print("[" + self.dvm_config.NIP89.NAME + "] Payment-request fulfilled...") await send_job_status_reaction(job_event, "processing", client=self.client, content=self.dvm_config.CUSTOM_PROCESSING_MESSAGE, - dvm_config=self.dvm_config, user=user) + dvm_config=self.dvm_config) indices = [i for i, x in enumerate(self.job_list) if x.event == job_event] index = -1 @@ -696,7 +696,7 @@ class DVM: expires = original_event.created_at().as_secs() + (60 * 60 * 24) if status == "payment-required" or ( status == "processing" and not is_paid): - if dvm_config.LNBITS_INVOICE_KEY != "": + if dvm_config.LNBITS_INVOICE_KEY != "" and dvm_config.PROVIDE_INVOICE: try: bolt11, payment_hash = create_bolt11_ln_bits(amount, dvm_config) except Exception as e: @@ -707,12 +707,14 @@ class DVM: except Exception as e: print(e) bolt11 = None - elif dvm_config.LN_ADDRESS != "": + elif dvm_config.LN_ADDRESS != "" and dvm_config.PROVIDE_INVOICE: try: bolt11, payment_hash = create_bolt11_lud16(dvm_config.LN_ADDRESS, amount) except Exception as e: print(e) bolt11 = None + else: + bolt11 = None if not any(x.event == original_event for x in self.job_list): self.job_list.append( diff --git a/nostr_dvm/utils/dvmconfig.py b/nostr_dvm/utils/dvmconfig.py index 39b6070..e3192e6 100644 --- a/nostr_dvm/utils/dvmconfig.py +++ b/nostr_dvm/utils/dvmconfig.py @@ -42,6 +42,7 @@ class DVMConfig: LNBITS_INVOICE_KEY = '' # Will all automatically generated by default, or read from .env LNBITS_ADMIN_KEY = '' # In order to pay invoices, e.g. from the bot to DVMs, or reimburse users. LNBITS_URL = 'https://lnbits.com' + PROVIDE_INVOICE = True LN_ADDRESS = '' SCRIPT = '' IDENTIFIER = '' diff --git a/tests/otherstuff.py b/tests/otherstuff.py index 265cef7..d89098c 100644 --- a/tests/otherstuff.py +++ b/tests/otherstuff.py @@ -51,6 +51,7 @@ def build_sd35(name, identifier, announce): dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST + dvm_config.PROVIDE_INVOICE = False profit_in_sats = 10 dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) nip89info = { @@ -77,6 +78,7 @@ def build_sd35(name, identifier, announce): aconfig = AdminConfig() aconfig.REBROADCAST_NIP89 = announce # We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89 aconfig.REBROADCAST_NIP65_RELAY_LIST = announce + aconfig.UPDATE_PROFILE = announce aconfig.LUD16 = dvm_config.LN_ADDRESS aconfig.PRIVKEY = dvm_config.PRIVATE_KEY aconfig.MELT_ON_STARTUP = False # set this to true to melt cashu tokens to our ln address on startup @@ -93,12 +95,15 @@ def build_dalle(name, identifier, announce): admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce admin_config.REBROADCAST_NIP65_RELAY_LIST = announce + admin_config.UPDATE_PROFILE = announce + dvm_config.NEW_USER_BALANCE = 0 dvm_config.USE_OWN_VENV = False dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST profit_in_sats = 10 + dvm_config.PROVIDE_INVOICE = False dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) @@ -130,10 +135,12 @@ def build_svd(name, identifier, announce): dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST + dvm_config.PROVIDE_INVOICE = False admin_config = AdminConfig() admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce admin_config.REBROADCAST_NIP65_RELAY_LIST = announce + admin_config.UPDATE_PROFILE = announce profit_in_sats = 10 cost_in_cent = 4.0 dvm_config.FIX_COST = int(((cost_in_cent / (get_price_per_sat("USD") * 100)) + profit_in_sats)) @@ -165,6 +172,7 @@ def build_media_converter(name, identifier, announce): admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce admin_config.REBROADCAST_NIP65_RELAY_LIST = announce + admin_config.UPDATE_PROFILE = announce nip89info = { "name": name, "picture": "https://cdn.nostr.build/i/a177be1159da5aad8396a1188f686728d55647d3a7371549584daf2b5e50eec9.jpg", @@ -304,6 +312,7 @@ def build_replicate(name, identifier, model, announce): dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST + dvm_config.PROVIDE_INVOICE = False admin_config = AdminConfig() admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce @@ -341,10 +350,13 @@ def build_replicate_recraft(name, identifier, announce): dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST + dvm_config.PROVIDE_INVOICE = False admin_config = AdminConfig() admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce admin_config.REBROADCAST_NIP65_RELAY_LIST = announce + admin_config.UPDATE_PROFILE = announce + profit_in_sats = 10 dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) @@ -376,10 +388,12 @@ def build_replicate_fluxpro(name, identifier, announce): dvm_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST dvm_config.SYNC_DB_RELAY_LIST = SYNC_DB_RELAY_LIST dvm_config.RELAY_LIST = RELAY_LIST + dvm_config.PROVIDE_INVOICE = False admin_config = AdminConfig() admin_config.LUD16 = dvm_config.LN_ADDRESS admin_config.REBROADCAST_NIP89 = announce admin_config.REBROADCAST_NIP65_RELAY_LIST = announce + admin_config.UPDATE_PROFILE = announce profit_in_sats = 10 dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) @@ -442,7 +456,7 @@ def playground(announce=False): bot_config.SUPPORTED_DVMS.append(recraftreplicate) recraftreplicate.run() - + media_bringer = build_media_converter("Nostr AI DVM Media Converter", "media_converter", announce) @@ -483,6 +497,6 @@ if __name__ == '__main__': dotenv.load_dotenv(env_path, verbose=True, override=True) else: raise FileNotFoundError(f'.env file not found at {env_path} ') - announce = False + announce = True playground(announce) diff --git a/ui/noogle/src/components/ImageGeneration.vue b/ui/noogle/src/components/ImageGeneration.vue index 3f68356..e58f282 100644 --- a/ui/noogle/src/components/ImageGeneration.vue +++ b/ui/noogle/src/components/ImageGeneration.vue @@ -9,13 +9,12 @@ import VueDatePicker from "@vuepic/vue-datepicker"; import { copyurl, dvmreactions, - get_user_infos, nextInput, post_note, schedule, sleep } from "../components/helper/Helper.vue" -import {zap, zaprequest} from "../components/helper/Zap.vue" +import {zap, get_invoice} from "../components/helper/Zap.vue" import StringUtil from "@/components/helper/string.ts"; @@ -129,6 +128,7 @@ async function listen() { let status = "unknown" let jsonentry = { id: event.author.toHex(), + event_id: event.id.toHex(), kind: "", status: status, result: "", @@ -151,38 +151,7 @@ async function listen() { if (event.tags[tag].asVec().length > 2) { jsonentry.bolt11 = event.tags[tag].asVec()[2] } else { - let profiles = await get_user_infos([event.author.toHex()]) - let created = 0 - let current - console.log("NUM KIND0 FOUND " + profiles.length) - if (profiles.length > 0) { - // for (const profile of profiles){ - console.log(profiles[0].profile) - let current = profiles[0] - // if (profiles[0].profile.createdAt > created){ - // created = profile.profile.createdAt - // current = profile - // } - - - let lud16 = current.profile.lud16 - if (lud16 !== null && lud16 !== "") { - console.log("LUD16: " + lud16) - //jsonentry.bolt11 = await createBolt11Lud16(lud16, jsonentry.amount) //todo replace with zaprequest - jsonentry.bolt11 = await zaprequest(lud16, jsonentry.amount, "zapped from noogle.lol", event.id.toHex(), event.author.toHex(), store.state.relays) //Not working yet - - console.log(jsonentry.bolt11) - if (jsonentry.bolt11 === "") { - console.log("no bolt 11") - //status = "error" - } - } else { - console.log("NO LNURL") - } - - } else { - console.log("PROFILE NOT FOUND") - } + jsonentry.bolt11 = "" } } @@ -236,6 +205,7 @@ async function listen() { let status = "unknown" let jsonentry = { id: event.author.toHex(), + event_id: event.id.toHex(), kind: "", status: status, result: "", @@ -283,10 +253,13 @@ async function listen() { const urlinput = ref(""); -async function zap_local(invoice) { - let success = await zap(invoice) +async function zap_local(dvm) { + if (dvm.bolt11 == ""){ + dvm.bolt11 = await get_invoice(dvm.id, dvm.event_id, dvm.amount) + } + let success = await zap(dvm.bolt11) if (success) { - dvms.find(i => i.bolt11 === invoice).status = "paid" + dvms.find(i => i.bolt11 === dvm.bolt11).status = "paid" store.commit('set_imagedvm_results', dvms) } } @@ -419,7 +392,7 @@ const submitHandler = async () => { - diff --git a/ui/noogle/src/components/helper/Zap.vue b/ui/noogle/src/components/helper/Zap.vue index 7ae7b59..c554d04 100644 --- a/ui/noogle/src/components/helper/Zap.vue +++ b/ui/noogle/src/components/helper/Zap.vue @@ -2,7 +2,7 @@ import {requestProvider} from "webln"; import store from "@/store"; -import {copyinvoice, fetchAsync} from "@/components/helper/Helper.vue"; +import {copyinvoice, fetchAsync, get_user_infos} from "@/components/helper/Helper.vue"; import {EventBuilder, EventId, PublicKey, Tag} from "@rust-nostr/nostr-sdk"; import {bech32} from "bech32"; import {webln} from "@getalby/sdk"; @@ -86,6 +86,49 @@ export async function zap(invoice) { return false } + + +export async function get_invoice(author_hex, event_id_hex, amount_in_sats){ + let profiles = await get_user_infos([author_hex]) + let created = 0 + let current + let bolt11 = "" + console.log("NUM KIND0 FOUND " + profiles.length) + if (profiles.length > 0) { + // for (const profile of profiles){ + console.log(profiles[0].profile) + let current = profiles[0] + // if (profiles[0].profile.createdAt > created){ + // created = profile.profile.createdAt + // current = profile + // } + + + let lud16 = current.profile.lud16 + if (lud16 !== null && lud16 !== "") { + console.log("LUD16: " + lud16) + //jsonentry.bolt11 = await createBolt11Lud16(lud16, jsonentry.amount) //todo replace with zaprequest + bolt11 = await zaprequest(lud16, amount_in_sats, "zapped from noogle.lol", event_id_hex, author_hex, store.state.relays) //Not working yet + + console.log(bolt11) + + if (bolt11 === "") { + console.log("no bolt 11") + //status = "error" + } + + } else { + console.log("NO LNURL") + } + + } else { + console.log("PROFILE NOT FOUND") + } + + return bolt11 + +} + export async function zap_lud16(lud16, eventid, authorid) { if (lud16 !== null && lud16 !== "") { let invoice = await zaprequest(lud16, 21, "with love from noogle.lol", eventid, authorid, store.state.relays) @@ -153,7 +196,7 @@ export async function zaprequest(lud16, amount, content, zapped_evt_id, zapped_u const encoded_lnurl = bech32.encode('lnurl', bech32.toWords(urlBytes), 1023); - const amount_tag = ['amount', (amount * 1000).toString()]; + const amount_tag = ['amount', (amount).toString()]; let relays = ['relays'] relays.push.apply(relays, relay_list) //let relays_tag = Tag.parse(relays); @@ -194,9 +237,7 @@ export async function zaprequest(lud16, amount, content, zapped_evt_id, zapped_u try { - const queryString = `amount=${(amount * 1000).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`; - - console.log(queryString) + const queryString = `amount=${(amount).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`; let ob = await fetchAsync(`${callback}?${queryString}`) return ob["pr"] } catch (e) {