mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-09-27 21:36:30 +02:00
add nwc to noogle
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
"type-check": "vue-tsc --build --force"
|
"type-check": "vue-tsc --build --force"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@getalby/sdk": "^3.4.0",
|
||||||
"@rust-nostr/nostr-sdk": "^0.11.1",
|
"@rust-nostr/nostr-sdk": "^0.11.1",
|
||||||
"@vuepic/vue-datepicker": "^7.4.1",
|
"@vuepic/vue-datepicker": "^7.4.1",
|
||||||
"@vueuse/core": "^10.7.2",
|
"@vueuse/core": "^10.7.2",
|
||||||
|
BIN
ui/noogle/public/Alby.jpg
Normal file
BIN
ui/noogle/public/Alby.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
ui/noogle/public/Mutiny.png
Normal file
BIN
ui/noogle/public/Mutiny.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
BIN
ui/noogle/public/NWA.png
Normal file
BIN
ui/noogle/public/NWA.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
BIN
ui/noogle/public/NWC.png
Normal file
BIN
ui/noogle/public/NWC.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
@@ -26,11 +26,14 @@ import { ref } from "vue";
|
|||||||
import ModalComponent from "../components/Newnote.vue";
|
import ModalComponent from "../components/Newnote.vue";
|
||||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||||
import {timestamp} from "@vueuse/core";
|
import {timestamp} from "@vueuse/core";
|
||||||
import {post_note, schedule, copyinvoice, copyurl, sleep, nextInput, get_user_infos, createBolt11Lud16, zaprequest} from "../components/helper/Helper.vue"
|
import {post_note, schedule, copyinvoice, copyurl, sleep, nextInput, get_user_infos} from "../components/helper/Helper.vue"
|
||||||
|
import {zap, createBolt11Lud16, zaprequest} from "../components/helper/Zap.vue"
|
||||||
|
|
||||||
import StringUtil from "@/components/helper/string.ts";
|
import StringUtil from "@/components/helper/string.ts";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let dvms =[]
|
let dvms =[]
|
||||||
let hasmultipleinputs = false
|
let hasmultipleinputs = false
|
||||||
|
|
||||||
@@ -268,34 +271,13 @@ const urlinput = ref("");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function zap(invoice) {
|
async function zap_local(invoice) {
|
||||||
let webln;
|
let success = await zap(invoice)
|
||||||
|
if (success){
|
||||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||||
//this.dvminvoice = invoice
|
store.commit('set_imagedvm_results', dvms)
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
webln = await requestProvider();
|
|
||||||
} catch (err) {
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (webln) {
|
|
||||||
try{
|
|
||||||
let response = await webln.sendPayment(invoice)
|
|
||||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
|
||||||
store.commit('set_imagedvm_results', dvms)
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
console.log(err)
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
@@ -417,7 +399,7 @@ const submitHandler = async () => {
|
|||||||
<button v-if="dvm.status === 'finished'" className="btn">Done</button>
|
<button v-if="dvm.status === 'finished'" className="btn">Done</button>
|
||||||
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
||||||
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
||||||
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap_local(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="flex" v-if="!zapped" @click="zap(lud16, id, authorid)">
|
<div class="flex" v-if="!zapped" @click="zap_local(lud16, id, authorid)">
|
||||||
<div style="margin-left: auto; margin-right: 5px; float: left;">
|
<div style="margin-left: auto; margin-right: 5px; float: left;">
|
||||||
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" fill="currentColor" class="bi bi-lightning" viewBox="0 0 16 20">
|
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" fill="currentColor" class="bi bi-lightning" viewBox="0 0 16 20">
|
||||||
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/>
|
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<p style="float: left;">{{zapAmount/1000}}</p>
|
<p style="float: left;">{{zapAmount/1000}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex" v-if="zapped" @click="zap(lud16, id, authorid)" >
|
<div class="flex" v-if="zapped" @click="zap_local(lud16, id, authorid)" >
|
||||||
<div style="margin-left: auto; margin-right: 5px;">
|
<div style="margin-left: auto; margin-right: 5px;">
|
||||||
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" class="bi bi-lightning fill-amber-400" viewBox="0 0 16 20">
|
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" class="bi bi-lightning fill-amber-400" viewBox="0 0 16 20">
|
||||||
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641z"/>
|
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641z"/>
|
||||||
@@ -91,6 +91,7 @@ import {copyinvoice, createBolt11Lud16, parseandreplacenpubs, zaprequest} from "
|
|||||||
import {requestProvider} from "webln";
|
import {requestProvider} from "webln";
|
||||||
import {Event, EventBuilder, EventId, PublicKey} from "@rust-nostr/nostr-sdk";
|
import {Event, EventBuilder, EventId, PublicKey} from "@rust-nostr/nostr-sdk";
|
||||||
import amberSignerService from "@/components/android-signer/AndroidSigner";
|
import amberSignerService from "@/components/android-signer/AndroidSigner";
|
||||||
|
import zap, {zap_lud16} from "@/components/helper/Zap.vue";
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -145,56 +146,16 @@ async function react(eventid, authorid){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function zap(lud16, eventid, authorid){
|
async function zap_local(lud16, eventid, authorid){
|
||||||
|
|
||||||
if(lud16 != Null && lud16 != ""){
|
let success = await zap_lud16(lud16, eventid, authorid)
|
||||||
let invoice = await zaprequest(lud16, 21 , "with love from noogle.lol", eventid, authorid, store.state.relays) //Not working yet
|
if (success){
|
||||||
// let invoice = await createBolt11Lud16(lud16, 21)
|
let objects = props.data.find(x=> x.id === eventid)
|
||||||
let webln;
|
|
||||||
try {
|
|
||||||
webln = await requestProvider();
|
|
||||||
} catch (err) {
|
|
||||||
if (invoice === null){
|
|
||||||
invoice = await createBolt11Lud16(lud16, 21)
|
|
||||||
}
|
|
||||||
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
if (webln) {
|
|
||||||
try{
|
|
||||||
let response = await webln.sendPayment(invoice)
|
|
||||||
if(response.preimage != null && response.preimage != ""){
|
|
||||||
|
|
||||||
|
|
||||||
let objects = (props.data.find(x=> x.id === eventid))
|
|
||||||
if (objects !== undefined){
|
if (objects !== undefined){
|
||||||
// console.log(objects.zapped)
|
|
||||||
objects.zapped = true
|
objects.zapped = true
|
||||||
objects.zapAmount += 21000
|
objects.zapAmount += 21000
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (objects != undefined && objects.length > 0){
|
|
||||||
console.log(objects[0])
|
|
||||||
props.data.find(x=> x.id === eventid).zapped.push.apply(props.data.find(x=> x.id === eventid).zapped, true)
|
|
||||||
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// miniToastr.showMessage("Zapped " + author , "Success" , VueNotifications.types.warn)
|
|
||||||
console.log(response)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
console.log(err)
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,15 +5,10 @@
|
|||||||
:items="store.state.profile_results" >
|
:items="store.state.profile_results" >
|
||||||
<template #item-content="{ author, authorurl, avatar}">
|
<template #item-content="{ author, authorurl, avatar}">
|
||||||
<div class="playeauthor-wrapper" >
|
<div class="playeauthor-wrapper" >
|
||||||
|
|
||||||
<img class="avatar" v-if="avatar" :src="avatar" alt="Avatar" onerror="this.src='https://noogle.lol/favicon.ico'" />
|
<img class="avatar" v-if="avatar" :src="avatar" alt="Avatar" onerror="this.src='https://noogle.lol/favicon.ico'" />
|
||||||
<img class="avatar" v-else src="@/assets/nostr-purple.svg" />
|
<img class="avatar" v-else src="@/assets/nostr-purple.svg" />
|
||||||
|
<a class="white" :href="authorurl" target="_blank">{{ author }}</a>
|
||||||
<a class="white" :href="authorurl" target="_blank">{{ author }}</a>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <p>{{content}}</p> -->
|
<!-- <p>{{content}}</p> -->
|
||||||
</template>
|
</template>
|
||||||
|
@@ -11,7 +11,7 @@ import {
|
|||||||
EventBuilder,
|
EventBuilder,
|
||||||
Tag,
|
Tag,
|
||||||
EventId,
|
EventId,
|
||||||
Nip19Event, Alphabet, Keys, nip04_decrypt, SecretKey, Duration
|
Nip19Event, Alphabet, Keys, nip04_decrypt, SecretKey, Duration, SingleLetterTag
|
||||||
} from "@rust-nostr/nostr-sdk";
|
} from "@rust-nostr/nostr-sdk";
|
||||||
import store from '../store';
|
import store from '../store';
|
||||||
import miniToastr from "mini-toastr";
|
import miniToastr from "mini-toastr";
|
||||||
@@ -22,7 +22,9 @@ import {data} from "autoprefixer";
|
|||||||
import {requestProvider} from "webln";
|
import {requestProvider} from "webln";
|
||||||
import Newnote from "@/components/Newnote.vue";
|
import Newnote from "@/components/Newnote.vue";
|
||||||
import SummarizationGeneration from "@/components/SummarizationGeneration.vue"
|
import SummarizationGeneration from "@/components/SummarizationGeneration.vue"
|
||||||
import {post_note, schedule, copyurl, copyinvoice, sleep, getEvents, get_user_infos, get_zaps, zaprequest, get_reactions, nextInput, createBolt11Lud16, getEventsOriginalOrder, parseandreplacenpubsName} from "../components/helper/Helper.vue"
|
import {post_note, schedule, copyurl, copyinvoice, sleep, getEvents, get_user_infos, get_zaps, get_reactions, nextInput, getEventsOriginalOrder, parseandreplacenpubsName} from "../components/helper/Helper.vue"
|
||||||
|
import {zap, createBolt11Lud16, zaprequest} from "../components/helper/Zap.vue"
|
||||||
|
|
||||||
import amberSignerService from "./android-signer/AndroidSigner";
|
import amberSignerService from "./android-signer/AndroidSigner";
|
||||||
import StringUtil from "@/components/helper/string.ts";
|
import StringUtil from "@/components/helper/string.ts";
|
||||||
|
|
||||||
@@ -100,9 +102,6 @@ async function generate_feed(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function listen() {
|
async function listen() {
|
||||||
let client = store.state.client
|
let client = store.state.client
|
||||||
let pubkey = store.state.pubkey
|
let pubkey = store.state.pubkey
|
||||||
@@ -228,7 +227,7 @@ async function listen() {
|
|||||||
authors.push(evt.author)
|
authors.push(evt.author)
|
||||||
}
|
}
|
||||||
catch(error){
|
catch(error){
|
||||||
console.log(error)
|
//console.log(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -242,7 +241,11 @@ async function listen() {
|
|||||||
|
|
||||||
let ids = []
|
let ids = []
|
||||||
for (let evt of events){
|
for (let evt of events){
|
||||||
ids.push(evt.id)
|
try {ids.push(evt.id)}
|
||||||
|
catch(error){
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
let zaps = await get_zaps(ids)
|
let zaps = await get_zaps(ids)
|
||||||
let items = []
|
let items = []
|
||||||
@@ -323,22 +326,18 @@ async function listen() {
|
|||||||
client.handleNotifications(handle);
|
client.handleNotifications(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const urlinput = ref("");
|
|
||||||
|
|
||||||
|
|
||||||
async function addAllContentDVMs() {
|
async function addAllContentDVMs() {
|
||||||
|
|
||||||
let relevent_dvms = []
|
let relevant_dvms = []
|
||||||
for (const el of store.state.nip89dvms) {
|
for (const el of store.state.nip89dvms) {
|
||||||
for (const tag of JSON.parse(el.event).tags) {
|
for (const tag of JSON.parse(el.event).tags) {
|
||||||
if (tag[0] === "k" && tag[1] === "5300") {
|
if (tag[0] === "k" && tag[1] === "5300") {
|
||||||
relevent_dvms.push(PublicKey.parse(el.id))
|
relevant_dvms.push(PublicKey.parse(el.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let active_dvms = []
|
let active_dvms = []
|
||||||
for (let id of relevent_dvms) {
|
for (let id of relevant_dvms) {
|
||||||
let jsonentry = {
|
let jsonentry = {
|
||||||
id: id.toHex(),
|
id: id.toHex(),
|
||||||
last_active: 0
|
last_active: 0
|
||||||
@@ -349,7 +348,7 @@ async function addAllContentDVMs() {
|
|||||||
|
|
||||||
console.log(active_dvms)
|
console.log(active_dvms)
|
||||||
|
|
||||||
const filtera = new Filter().authors(relevent_dvms).kinds([6300, 7000])
|
const filtera = new Filter().authors(relevant_dvms).kinds([6300, 7000])
|
||||||
let client = store.state.client
|
let client = store.state.client
|
||||||
let activities = await client.getEventsOf([filtera], Duration.fromSecs(1))
|
let activities = await client.getEventsOf([filtera], Duration.fromSecs(1))
|
||||||
|
|
||||||
@@ -367,10 +366,10 @@ async function addAllContentDVMs() {
|
|||||||
|
|
||||||
// console.log(last_active)
|
// console.log(last_active)
|
||||||
// If DVM hasn't been active for 3 weeks, don't consider it.
|
// If DVM hasn't been active for 3 weeks, don't consider it.
|
||||||
console.log(active_dvms)
|
//console.log(active_dvms)
|
||||||
let final_dvms = []
|
let final_dvms = []
|
||||||
for (let element of active_dvms) {
|
for (let element of active_dvms) {
|
||||||
if (element.last_active > Timestamp.now().asSecs() - 60 * 60 * 24 * 7) {
|
if (element.last_active > Timestamp.now().asSecs() - 60 * 60 * 24 * 21) {
|
||||||
final_dvms.push(store.state.nip89dvms.find(x => x.id === element.id))
|
final_dvms.push(store.state.nip89dvms.find(x => x.id === element.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +388,8 @@ async function addAllContentDVMs() {
|
|||||||
amount: el.amount,
|
amount: el.amount,
|
||||||
bolt11: "",
|
bolt11: "",
|
||||||
lud16: el.lud16,
|
lud16: el.lud16,
|
||||||
subscription: ""
|
subscription: "",
|
||||||
|
nip88: el.nip88
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -503,21 +503,75 @@ async function addDVM(event){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function subscribe(lud16, days, amountperday, eventid, authorid) {
|
|
||||||
if (lud16 !== "") {
|
|
||||||
let profiles = await get_user_infos([PublicKey.parse(authorid)])
|
async function subscribe(zaps, amount, cadence, activesubscriptioneventid, tierevent, tiereventid, dvmid) {
|
||||||
if (profiles.length > 0) {
|
|
||||||
let current = profiles[0]
|
// We only arrive here if no subscription exists, we might create a 7001 if it doesnt exist and we zap it
|
||||||
lud16 = current.profile.lud16
|
let client = store.state.client
|
||||||
|
|
||||||
|
console.log(dvmid)
|
||||||
|
console.log(tiereventid)
|
||||||
|
console.log(JSON.stringify(tierevent))
|
||||||
|
console.log(amount)
|
||||||
|
console.log(activesubscriptioneventid)
|
||||||
|
|
||||||
|
|
||||||
|
if (activesubscriptioneventid === ""){
|
||||||
|
console.log("Creating 7001 event")
|
||||||
|
let tags = [
|
||||||
|
Tag.parse([ "p", dvmid]),
|
||||||
|
Tag.parse([ "e" , tiereventid]),
|
||||||
|
Tag.parse([ "event", JSON.stringify(tierevent)]),
|
||||||
|
Tag.parse([ "amount", (amount).toString(), "msats", cadence]),
|
||||||
|
// Zap-splits todo order and splits
|
||||||
|
// Tag.parse([ "zap", authorid, "19" ]), // 95%
|
||||||
|
// Tag.parse([ "zap", "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52", "1" ]), // 5% to client developer where subscription was created
|
||||||
|
]
|
||||||
|
|
||||||
|
for(let zap of zaps){
|
||||||
|
let zaptag = Tag.parse([ "zap", zap.key, zap.split])
|
||||||
|
tags.push(zaptag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(tags)
|
||||||
|
let evt = new EventBuilder(7001, "Subscription from noogle.lol", tags)
|
||||||
|
let res = await client.sendEventBuilder(evt);
|
||||||
|
activesubscriptioneventid = res.toHex()
|
||||||
|
|
||||||
}
|
}
|
||||||
let invoice = await zaprequest(lud16, days * amountperday, "paid from noogle.lol", eventid, authorid, store.state.relays)
|
|
||||||
console.log(invoice)
|
let overallsplit = 0
|
||||||
await zap(invoice)
|
for (let zap of zaps){
|
||||||
|
overallsplit += parseInt(zap.split)
|
||||||
|
}
|
||||||
|
for (let zap of zaps){
|
||||||
|
let profiles = await get_user_infos([PublicKey.parse(zap.key)])
|
||||||
|
if (profiles.length > 0) {
|
||||||
|
let current = profiles[0]
|
||||||
|
let lud16 = current.profile.lud16
|
||||||
|
let splitted_amount = Math.floor((zap.split/overallsplit) * amount/1000)
|
||||||
|
console.log(splitted_amount)
|
||||||
|
console.log(overallsplit)
|
||||||
|
console.log(activesubscriptioneventid)
|
||||||
|
let invoice = await zaprequest(lud16, splitted_amount, "paid for " + cadence + " from noogle.lol", activesubscriptioneventid, dvmid, store.state.relays)
|
||||||
|
console.log(invoice)
|
||||||
|
await zapSubscription(invoice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dvms.find(x => x.nip88.eventid === tiereventid ).hasActiveSubscription = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// next, the dvm should listen to these 7001 events addressed to it and (or rather 9735 tagging the 7001 and the subscription should be considered valid for both)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function zap(invoice) {
|
async function zapSubscription(invoice) {
|
||||||
let webln;
|
let webln;
|
||||||
|
|
||||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
||||||
@@ -531,8 +585,9 @@ async function zap(invoice) {
|
|||||||
if (webln) {
|
if (webln) {
|
||||||
try{
|
try{
|
||||||
let response = await webln.sendPayment(invoice)
|
let response = await webln.sendPayment(invoice)
|
||||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
|
||||||
store.commit('set_recommendation_dvms', dvms)
|
//dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||||
|
// store.commit('set_recommendation_dvms', dvms)
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
console.log(err)
|
console.log(err)
|
||||||
@@ -542,6 +597,17 @@ async function zap(invoice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function zap_local(invoice) {
|
||||||
|
|
||||||
|
let success = await zap(invoice)
|
||||||
|
if (success){
|
||||||
|
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||||
|
store.commit('set_recommendation_dvms', dvms)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
msg: {
|
msg: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -554,6 +620,7 @@ import ModalComponent from "../components/Newnote.vue";
|
|||||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||||
import {timestamp} from "@vueuse/core";
|
import {timestamp} from "@vueuse/core";
|
||||||
import NoteTable from "@/components/NoteTable.vue";
|
import NoteTable from "@/components/NoteTable.vue";
|
||||||
|
import {nostrzapper_nwc} from "@rust-nostr/nostr-sdk/pkg/nostr_sdk_js_bg.wasm.js";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -667,37 +734,22 @@ const submitHandler = async () => {
|
|||||||
|
|
||||||
|
|
||||||
<button v-if="dvm.status !== 'finished' && dvm.status !== 'paid' && dvm.status !== 'payment-required' && dvm.status !== 'subscription-required' && dvm.status !== 'subscription-success' && dvm.status !== 'error' && dvm.status !== 'announced'" className="btn">{{dvm.status}}</button>
|
<button v-if="dvm.status !== 'finished' && dvm.status !== 'paid' && dvm.status !== 'payment-required' && dvm.status !== 'subscription-required' && dvm.status !== 'subscription-success' && dvm.status !== 'error' && dvm.status !== 'announced'" className="btn">{{dvm.status}}</button>
|
||||||
<button v-if="dvm.status === 'finished'" class="bg-base-200 text-bg-base200" @click="generate_feed(dvm.id)" className="btn">Done</button>
|
<button v-if="dvm.status === 'finished'" @click="generate_feed(dvm.id)" className="request-Button">Done, again?</button>
|
||||||
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
||||||
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
||||||
|
|
||||||
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap_local(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
||||||
<!-- <button v-if="dvm.status === 'subscription-required'" className="sub-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button> d -->
|
<h3 v-if="dvm.status === 'subscription-required'" className="sub-Button" >Subscription required</h3>
|
||||||
<div class="playeauthor-wrapper" v-if="dvm.status === 'subscription-required'">
|
|
||||||
|
|
||||||
<div className="dropdown">
|
|
||||||
<div tabIndex={0} role="button" class="sub-Button" >
|
|
||||||
<p>Subscribe</p>
|
|
||||||
</div>
|
|
||||||
<div tabIndex={0} className="dropdown-content -start-56 z-[1] horizontal card card-compact w-64 p-2 shadow bg-orange-500 text-primary-content">
|
|
||||||
<div className="card-body">
|
|
||||||
<h3 className="card-title">Subscribe for a day</h3>
|
|
||||||
|
|
||||||
<button className="sub-Button" @click="subscribe(dvm.lud16, 1, dvm.amount/1000, dvm.laststatusid, dvm.id)">{{ dvm.amount/1000 }} Sats</button>
|
|
||||||
|
|
||||||
<h3 className="card-title">Subscribe for a month</h3>
|
|
||||||
<!--<p>Sign out</p> -->
|
|
||||||
<button className="sub-Button" @click="subscribe(dvm.lud16, 30, dvm.amount/1000, dvm.laststatusid, dvm.id)">{{ 30 * dvm.amount/1000 }} Sats</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--<p>{{ this.current_user }}</p> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button v-if="dvm.status === 'subscription-success'" className="sub-Button" @click="generate_feed(dvm.id);">Subscribed. Request job</button>
|
<button v-if="dvm.status === 'subscription-success'" className="sub-Button" @click="generate_feed(dvm.id);">Subscribed. Request job</button>
|
||||||
|
|
||||||
<button v-if="dvm.status === 'announced'" className="request-Button" @click="generate_feed(dvm.id);">Request</button>
|
<!-- <button v-if="dvm.status === 'announced'" className="request-Button" @click="generate_feed(dvm.id);">Request</button> -->
|
||||||
|
<button v-if="dvm.status === 'announced'" @click="generate_feed(dvm.id);" class="relative inline-flex items-center justify-center p-0.5 mb-2 me-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800">
|
||||||
|
<span class="relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0">
|
||||||
|
Request
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!--<h3 v-if="dvm.amount.toString().toLowerCase()==='free'" class="bg-nostr btn rounded-full" >{{ "Free" }}</h3> -->
|
<!--<h3 v-if="dvm.amount.toString().toLowerCase()==='free'" class="bg-nostr btn rounded-full" >{{ "Free" }}</h3> -->
|
||||||
|
|
||||||
@@ -723,13 +775,85 @@ const submitHandler = async () => {
|
|||||||
|
|
||||||
<div style="margin-left: auto; margin-right: 3px;">
|
<div style="margin-left: auto; margin-right: 3px;">
|
||||||
<p v-if="dvm.subscription ==='' && dvm.amount.toString().toLowerCase()==='free'" class="text-sm text-gray-600 rounded" >Free</p>
|
<p v-if="dvm.subscription ==='' && dvm.amount.toString().toLowerCase()==='free'" class="text-sm text-gray-600 rounded" >Free</p>
|
||||||
<p v-if="dvm.subscription ==='' && dvm.amount.toString().toLowerCase()==='flexible'" class="text-sm text-gray-600 rounded" >Flexible</p>
|
<p v-if="dvm.subscription ==='' && dvm.amount.toString().toLowerCase()==='flexible'" class="text-sm text-gray-600 tracking-wide rounded" >Flexible</p>
|
||||||
<p v-if="dvm.subscription ==='' && dvm.amount.toString().toLowerCase()==='subscription'" class="text-sm text-gray-600 rounded">Subscription</p>
|
</div>
|
||||||
<div className="dropdown">
|
<div>
|
||||||
<div tabIndex={0} role="button" class="Button" >
|
<div class="playeauthor-wrapper" v-if="dvm.nip88">
|
||||||
|
|
||||||
|
<div v-if="!dvm.nip88.hasActiveSubscription" className="dropdown" >
|
||||||
|
<div tabIndex={0} role="button" >
|
||||||
|
<!-- <p class=" text-sm sub-Button text-orange-400"> Subscription </p> -->
|
||||||
|
<button class="relative inline-flex items-center justify-center p-0.5 mb-2 me-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-pink-500 to-orange-400 group-hover:from-pink-500 group-hover:to-orange-400 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-pink-200 dark:focus:ring-pink-800">
|
||||||
|
<span class="relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0">Subscription
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div style="z-index: 10000" tabIndex={0} className="dropdown-content -start-56 z-[1] horizontal card card-compact w-96 p-2 shadow bg-orange-500 text-primary-content">
|
||||||
|
<img style="flex: content" :src="dvm.nip88.image"></img>
|
||||||
|
<div class="glass" className="card-body">
|
||||||
|
|
||||||
|
<h3 className="card-title">{{dvm.nip88.title}}</h3>
|
||||||
|
|
||||||
|
<h3 style="text-align: left">{{dvm.nip88.description}}</h3>
|
||||||
|
<div v-for="index in dvm.nip88.amounts">
|
||||||
|
<br>
|
||||||
|
<h3 >Subscribe and pay {{index.cadence}}</h3>
|
||||||
|
<button className="sub-Button" @click="subscribe(dvm.nip88.zaps, index.amount, index.cadence, dvm.nip88.subscriptionId, dvm.nip88.event, dvm.nip88.eventid, dvm.id)">{{ index.amount/1000 }} Sats</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="dvm.nip88.hasActiveSubscription" className="dropdown" >
|
||||||
|
<div tabIndex={0} role="button" >
|
||||||
|
<button class=" relative inline-flex items-center justify-center p-0.5 mb-2 me-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-pink-500 to-orange-400 group-hover:from-pink-500 group-hover:to-orange-400 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-pink-200 dark:focus:ring-pink-800">
|
||||||
|
<span class="relative px-5 py-2.5 transition-all ease-in duration-75 rounded-md group-hover:bg-opacity-0">
|
||||||
|
Active Subscription
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<!-- <p class=" text-sm sub-Button text-orange-400"> Active Subscription </p> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="z-index: 10000" tabIndex={0} className="dropdown-content start-12 z-[1] horizontal card card-compact w-96 p-2 shadow bg-orange-500 text-primary-content">
|
||||||
|
<img style="flex: content" :src="dvm.nip88.image"></img>
|
||||||
|
<div class="glass" className="card-body">
|
||||||
|
|
||||||
|
<h3 className="card-title">{{dvm.nip88.title}}</h3>
|
||||||
|
|
||||||
|
<h3 style="text-align: left">{{dvm.nip88.description}}</h3>
|
||||||
|
<br>
|
||||||
|
<h3 className="card-title">Perks:</h3>
|
||||||
|
<div v-for="perk in dvm.nip88.perks">
|
||||||
|
<p style="text-align: left">{{perk}}</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<h3>Subscription active until
|
||||||
|
{{Timestamp.fromSecs(parseInt(dvm.nip88.subscribedUntil)).toHumanDatetime().split("T")[0].split("-")[2].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.nip88.subscribedUntil)).toHumanDatetime().split("T")[0].split("-")[1].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.nip88.subscribedUntil)).toHumanDatetime().split("T")[0].split("-")[0].trim().slice(2)}} {{Timestamp.fromSecs(parseInt(dvm.nip88.subscribedUntil)).toHumanDatetime().split("T")[1].split("Z")[0].trim()}}</h3>
|
||||||
|
<!-- <div v-for="index in dvm.nip88.amounts">
|
||||||
|
<br>
|
||||||
|
<h3 >Subscribe and pay {{index.cadence}}</h3>
|
||||||
|
<button className="sub-Button" @click="subscribe(dvm.lud16, index.amount, index.cadence, dvm.event, dvm.eventid, dvm.id)">{{ index.amount/1000 }} Sats</button>
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- <br>
|
||||||
|
<button class="btn">Unsubscribe (todo)</button> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <div tabIndex={0} role="button" class="Button" >
|
||||||
<p v-if="dvm.subscription!==''" class="text-sm text-gray-600 rounded" >Subscription active until
|
<p v-if="dvm.subscription!==''" class="text-sm text-gray-600 rounded" >Subscription active until
|
||||||
{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[2].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[1].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[0].trim().slice(2)}} {{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[1].split("Z")[0].trim()}}</p>
|
{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[2].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[1].trim()}}.{{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[0].split("-")[0].trim().slice(2)}} {{Timestamp.fromSecs(parseInt(dvm.subscription)).toHumanDatetime().split("T")[1].split("Z")[0].trim()}}</p>
|
||||||
</div>
|
</div> -->
|
||||||
<!-- <div tabIndex={0} style="z-index: 100000;" className="dropdown-content -start-56 z-[1] horizontal card card-compact w-64 p-2 shadow bg-orange-500 text-primary-content">
|
<!-- <div tabIndex={0} style="z-index: 100000;" className="dropdown-content -start-56 z-[1] horizontal card card-compact w-64 p-2 shadow bg-orange-500 text-primary-content">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h3 className="card-title">Subscribe for a day</h3>
|
<h3 className="card-title">Subscribe for a day</h3>
|
||||||
@@ -740,11 +864,11 @@ const submitHandler = async () => {
|
|||||||
|
|
||||||
<button className="sub-Button" @click="subscribe(dvm.lud16, 30, dvm.amount/1000, dvm.laststatusid, dvm.id)">{{ 30 * dvm.amount/1000 }} Sats</button>
|
<button className="sub-Button" @click="subscribe(dvm.lud16, 30, dvm.amount/1000, dvm.laststatusid, dvm.id)">{{ 30 * dvm.amount/1000 }} Sats</button>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>-->
|
||||||
<p v-if="dvm.amount.toString()===''" ></p>
|
<p v-if="dvm.amount.toString()===''" ></p>
|
||||||
|
|
||||||
<p v-if="dvm.subscription ==='' && !isNaN(parseInt(dvm.amount)) && dvm.status !='subscription-required' && dvm.status !='subscription-success'" class="text-sm text-gray-600 rounded" ><div class="flex"><svg style="margin-top:3px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" fill="currentColor" class="bi bi-lightning" viewBox="0 0 16 20">
|
<p v-if="dvm.subscription ==='' && !isNaN(parseInt(dvm.amount)) && dvm.status !=='subscription-required' && dvm.status !=='subscription-success'" class="text-sm text-gray-600 rounded" ><div class="flex"><svg style="margin-top:3px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" fill="currentColor" class="bi bi-lightning" viewBox="0 0 16 20">
|
||||||
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/></svg> {{dvm.amount/1000}}</div></p>
|
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/></svg> {{dvm.amount/1000}}</div></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -787,6 +911,7 @@ const submitHandler = async () => {
|
|||||||
|
|
||||||
.sub-Button{
|
.sub-Button{
|
||||||
@apply btn hover:bg-nostr border-orange-500 text-base;
|
@apply btn hover:bg-nostr border-orange-500 text-base;
|
||||||
|
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -308,31 +308,19 @@ async function addDVM(event){
|
|||||||
store.commit('set_recommendation_dvms', dvms)
|
store.commit('set_recommendation_dvms', dvms)
|
||||||
|
|
||||||
}
|
}
|
||||||
async function zap(invoice) {
|
|
||||||
let webln;
|
|
||||||
|
|
||||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
async function zap_local(invoice) {
|
||||||
//this.dvminvoice = invoice
|
|
||||||
try {
|
|
||||||
webln = await requestProvider();
|
|
||||||
} catch (err) {
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webln) {
|
let success = await zap(invoice)
|
||||||
try{
|
if (success){
|
||||||
let response = await webln.sendPayment(invoice)
|
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
|
||||||
store.commit('set_recommendation_results', dvms)
|
store.commit('set_recommendation_results', dvms)
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
console.log(err)
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
msg: {
|
msg: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -345,6 +333,7 @@ import ModalComponent from "../components/Newnote.vue";
|
|||||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||||
import {timestamp} from "@vueuse/core";
|
import {timestamp} from "@vueuse/core";
|
||||||
import NoteTable from "@/components/NoteTable.vue";
|
import NoteTable from "@/components/NoteTable.vue";
|
||||||
|
import zap from "@/components/helper/Zap.vue";
|
||||||
|
|
||||||
const isModalOpened = ref(false);
|
const isModalOpened = ref(false);
|
||||||
const modalcontent = ref("");
|
const modalcontent = ref("");
|
||||||
@@ -456,7 +445,7 @@ const submitHandler = async () => {
|
|||||||
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
||||||
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
||||||
|
|
||||||
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap_local(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -28,6 +28,7 @@ import ModalComponent from "../components/Newnote.vue";
|
|||||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||||
import {timestamp} from "@vueuse/core";
|
import {timestamp} from "@vueuse/core";
|
||||||
import NoteTable from "@/components/NoteTable.vue";
|
import NoteTable from "@/components/NoteTable.vue";
|
||||||
|
import {zap} from "@/components/helper/Zap.vue";
|
||||||
|
|
||||||
let dvms =[]
|
let dvms =[]
|
||||||
async function summarizefeed(eventids) {
|
async function summarizefeed(eventids) {
|
||||||
@@ -245,36 +246,16 @@ async function listen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function zap(invoice) {
|
async function zap_local(invoice) {
|
||||||
let webln;
|
|
||||||
|
|
||||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
let success = await zap(invoice)
|
||||||
//this.dvminvoice = invoice
|
if (success){
|
||||||
|
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||||
|
store.commit('set_summarization_dvms', dvms)
|
||||||
try {
|
|
||||||
webln = await requestProvider();
|
|
||||||
} catch (err) {
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (webln) {
|
|
||||||
try{
|
|
||||||
let response = await webln.sendPayment(invoice)
|
|
||||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
|
||||||
store.commit('set_summarization_dvms', dvms)
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
console.log(err)
|
|
||||||
await copyinvoice(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
events: {
|
events: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -364,7 +345,7 @@ const submitHandler = async () => {
|
|||||||
<button v-if="dvm.status === 'finished'" className="btn">Done</button>
|
<button v-if="dvm.status === 'finished'" className="btn">Done</button>
|
||||||
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
||||||
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
||||||
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap_local(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,7 +2,19 @@
|
|||||||
import {defineComponent} from 'vue'
|
import {defineComponent} from 'vue'
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import amberSignerService from "@/components/android-signer/AndroidSigner";
|
import amberSignerService from "@/components/android-signer/AndroidSigner";
|
||||||
import {Duration, Event, EventBuilder, EventId, Filter, Keys, PublicKey, Tag, Timestamp} from "@rust-nostr/nostr-sdk";
|
import {
|
||||||
|
Alphabet,
|
||||||
|
Duration,
|
||||||
|
Event,
|
||||||
|
EventBuilder,
|
||||||
|
EventId,
|
||||||
|
Filter,
|
||||||
|
Keys,
|
||||||
|
PublicKey,
|
||||||
|
SingleLetterTag,
|
||||||
|
Tag,
|
||||||
|
Timestamp
|
||||||
|
} from "@rust-nostr/nostr-sdk";
|
||||||
import miniToastr from "mini-toastr/mini-toastr";
|
import miniToastr from "mini-toastr/mini-toastr";
|
||||||
import VueNotifications from "vue-notifications";
|
import VueNotifications from "vue-notifications";
|
||||||
import {bech32} from "bech32";
|
import {bech32} from "bech32";
|
||||||
@@ -349,7 +361,7 @@ export async function parseandreplacenpubsName(note){
|
|||||||
return finalnote.trimEnd()
|
return finalnote.trimEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAsync (url) {
|
export async function fetchAsync (url) {
|
||||||
let response = await fetch(url);
|
let response = await fetch(url);
|
||||||
let data = await response.json();
|
let data = await response.json();
|
||||||
return data;
|
return data;
|
||||||
@@ -357,151 +369,202 @@ async function fetchAsync (url) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function zaprequest(lud16, amount, content, zapped_event_id, zapped_user_id, relay_list){
|
export async function hasActiveSubscription(pubkeystring, tiereventid, tierauthorid, amounts) {
|
||||||
let url = ""
|
console.log("Checking for subscription")
|
||||||
|
let client = store.state.client
|
||||||
console.log(lud16)
|
let subscriptionstatus = {
|
||||||
console.log(PublicKey.parse(zapped_user_id).toBech32())
|
isActive: false,
|
||||||
console.log(EventId.parse(zapped_event_id).toBech32())
|
validuntil: 0,
|
||||||
console.log(zapped_event_id)
|
subscriptionId: "",
|
||||||
|
|
||||||
|
|
||||||
zapped_user_id = PublicKey.parse(zapped_user_id).toHex()
|
|
||||||
zapped_event_id = EventId.parse(zapped_event_id).toHex()
|
|
||||||
|
|
||||||
//overwrite for debug
|
|
||||||
//lud16 = "hype@bitcoinfixesthis.org"
|
|
||||||
//zapped_user_id = PublicKey.parse("npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8").toHex()
|
|
||||||
//zapped_event_id = EventId.parse("note1xsw95cp4ynelxdujd3xrh6kmre3y0lk699xn09z52mjenmktdllq9vtwyn").toHex()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (lud16 !== "" && lud16.toString().includes('@')){
|
|
||||||
url = `https://${lud16.split('@')[1]}/.well-known/lnurlp/${lud16.split('@')[0]}`;
|
|
||||||
console.log(url)
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
|
|
||||||
let ob = await fetchAsync(url)
|
|
||||||
let callback = ob["callback"]
|
|
||||||
console.log(callback)
|
|
||||||
|
|
||||||
|
|
||||||
const urlBytes = new TextEncoder().encode(url);
|
|
||||||
const encoded_lnurl = bech32.encode('lnurl', bech32.toWords(urlBytes), 1023);
|
|
||||||
|
|
||||||
|
|
||||||
const amount_tag = ['amount', (amount * 1000).toString()];
|
|
||||||
let relays = ['relays']
|
|
||||||
relays.push.apply(relays, relay_list)
|
|
||||||
//let relays_tag = Tag.parse(relays);
|
|
||||||
|
|
||||||
const lnurl_tag = ['lnurl', encoded_lnurl];
|
|
||||||
|
|
||||||
let tags = []
|
|
||||||
let p_tag = ['p', zapped_user_id]
|
|
||||||
if (zapped_event_id !== null){
|
|
||||||
let e_tag = ['e', zapped_event_id]
|
|
||||||
tags = [amount_tag, relays, p_tag, e_tag, lnurl_tag]
|
|
||||||
}
|
|
||||||
|
|
||||||
else{
|
|
||||||
tags = [amount_tag, relays, p_tag, lnurl_tag]
|
|
||||||
}
|
|
||||||
/*if (zaptype === "private") {
|
|
||||||
const key_str = keys.secret_key().to_hex() + zapped_event.id().to_hex() + zapped_event.created_at().as_secs().toString();
|
|
||||||
const encryption_key = sha256(key_str).toString('hex');
|
|
||||||
const zap_request = new EventBuilder(9733, content, [p_tag, e_tag]).to_event(keys).as_json();
|
|
||||||
keys = Keys.parse(encryption_key);
|
|
||||||
const encrypted_content = enrypt_private_zap_message(zap_request, keys.secret_key(), zapped_event.author());
|
|
||||||
const anon_tag = Tag.parse(['anon', encrypted_content]);
|
|
||||||
tags.push(anon_tag);
|
|
||||||
content = "";
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let signer = store.state.signer
|
|
||||||
let zap_request = ""
|
|
||||||
|
|
||||||
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
|
||||||
let draft = {
|
|
||||||
content: content,
|
|
||||||
kind: 9734,
|
|
||||||
pubkey: store.state.pubkey.toHex(),
|
|
||||||
tags: tags,
|
|
||||||
createdAt: Date.now()
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = await amberSignerService.signEvent(draft)
|
|
||||||
zap_request = JSON.stringify(res)
|
|
||||||
//await sleep(3000)
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let tags_t = []
|
|
||||||
for (let tag of tags){
|
|
||||||
tags_t.push(Tag.parse(tag))
|
|
||||||
}
|
|
||||||
let noteevent = new EventBuilder(9734, content, tags_t).toUnsignedEvent(store.state.pubkey)
|
|
||||||
let signedEvent = await signer.signEvent(noteevent)
|
|
||||||
zap_request = signedEvent.asJson()
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
|
|
||||||
const queryString = `amount=${(amount * 1000).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`;
|
|
||||||
|
|
||||||
console.log(queryString)
|
|
||||||
let ob = await fetchAsync(`${callback}?${queryString}`)
|
|
||||||
return ob["pr"]
|
|
||||||
}
|
|
||||||
catch(e){
|
|
||||||
console.log("HELLO" + e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(error){
|
|
||||||
console.log("ZAP REQUEST: " + error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let event7001id = EventId
|
||||||
|
console.log(pubkeystring)
|
||||||
|
// look if user has 7001 event, and if 7001 has been canceled by 7002
|
||||||
|
const filter = new Filter().kind(7001).author(PublicKey.parse(pubkeystring)).pubkey(PublicKey.parse(tierauthorid)).event(EventId.parse(tiereventid)) //only get latest with these conditions
|
||||||
|
let evts = await client.getEventsOf([filter], Duration.fromSecs(5))
|
||||||
|
console.log(evts)
|
||||||
|
if (evts.length > 0) {
|
||||||
|
|
||||||
|
//console.log("7001: " + evts[0].asJson())
|
||||||
|
let checkispaid = []
|
||||||
|
for (let tag of evts[0].tags){
|
||||||
|
/*if (tag.asVec()[0] === "e"){
|
||||||
|
console.log("sanity check")
|
||||||
|
const filtercheck = new Filter().kind(37001).id(EventId.parse(tag.asVec()[1])).limit(1) // get latest with these conditons # customTag(SingleLetterTag.lowercase(Alphabet.A), [eventid])
|
||||||
|
let sanityevents = await client.getEventsOf([filtercheck], Duration.fromSecs(5))
|
||||||
|
if (sanityevents.length === 0){
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
return subscriptionstatus
|
||||||
|
}
|
||||||
|
else{console.log(sanityevents[0].asJson())
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
if (tag.asVec()[0] === "zap"){
|
||||||
|
checkispaid.push(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let splitids = []
|
||||||
|
for (let tag of checkispaid){
|
||||||
|
splitids.push(PublicKey.parse(tag.asVec()[1]))
|
||||||
|
console.log(tag.asVec())
|
||||||
|
}
|
||||||
|
if (checkispaid.length === 0){
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
return subscriptionstatus
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let evt in evts){
|
||||||
|
event7001id = evts[0].id
|
||||||
|
}
|
||||||
|
|
||||||
|
event7001id = evts[0].id
|
||||||
|
|
||||||
|
const filter = new Filter().kind(7002).pubkey(PublicKey.parse(tierauthorid)).event(event7001id).limit(1) // get latest with these conditons # customTag(SingleLetterTag.lowercase(Alphabet.A), [eventid])
|
||||||
|
let cancelevts = await client.getEventsOf([filter], Duration.fromSecs(5))
|
||||||
|
if (cancelevts.length > 0) {
|
||||||
|
if (cancelevts[0].createdAt.asSecs() > evts[0].createdAt.asSecs()) {
|
||||||
|
console.log("A subscription exists, but has been canceled")
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
return subscriptionstatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("A subscription exists, checking payment status")
|
||||||
|
|
||||||
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
const zapfilter = new Filter().kind(9735).pubkeys(splitids).event(event7001id).limit(checkispaid.length)
|
||||||
|
let zapevents = await client.getEventsOf([zapfilter], Duration.fromSecs(5))
|
||||||
|
if (zapevents.length > 0) {
|
||||||
|
console.log(zapevents)
|
||||||
|
let timeofourlastzap = 0
|
||||||
|
|
||||||
|
let overallamount = 0
|
||||||
|
|
||||||
|
let overall = 0
|
||||||
|
for (let tag of checkispaid){
|
||||||
|
let split = parseInt(tag.asVec()[2])
|
||||||
|
overall += split
|
||||||
|
}
|
||||||
|
for(let zapevent of zapevents) {
|
||||||
|
|
||||||
|
|
||||||
|
if (zapevent.createdAt.asSecs() > timeofourlastzap) {
|
||||||
|
timeofourlastzap = zapevent.createdAt.asSecs()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let tag of zapevent.tags) {
|
||||||
|
if (tag.asVec()[0] === "description") {
|
||||||
|
|
||||||
|
let event9734 = Event.fromJson(tag.asVec()[1])
|
||||||
|
|
||||||
|
|
||||||
|
for (let tag of event9734.tags) {
|
||||||
|
if (tag.asVec()[0] === "amount") {
|
||||||
|
let amount = parseInt(tag.asVec()[1])
|
||||||
|
console.log("AMOUNT: " + amount)
|
||||||
|
overallamount = overallamount + amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let entry
|
||||||
|
for (let index in amounts){
|
||||||
|
if(parseInt(amounts[index].amount) === overallamount ){
|
||||||
|
entry = amounts[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!entry){
|
||||||
|
console.log("Undefined amount")
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
//subscriptionstatus.validuntil = zapevent.createdAt.asSecs() + 24*60*60
|
||||||
|
return subscriptionstatus
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log(entry.amount + " " + entry.cadence)
|
||||||
|
if (entry.cadence === "daily"){
|
||||||
|
if (timeofourlastzap + 24*60*60 > Timestamp.now().asSecs()){
|
||||||
|
console.log("A daily subscription exists, and is active")
|
||||||
|
subscriptionstatus.isActive = true
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
subscriptionstatus.validuntil = timeofourlastzap + 24*60*60
|
||||||
|
return subscriptionstatus
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entry.cadence === "monthly"){
|
||||||
|
if (timeofourlastzap + 31*24*60*60 > Timestamp.now().asSecs()){
|
||||||
|
console.log("A monthly subscription exists, and is active")
|
||||||
|
subscriptionstatus.isActive = true
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
subscriptionstatus.validuntil = timeofourlastzap + 31*24*60*60
|
||||||
|
return subscriptionstatus
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entry.cadence === "yearly"){
|
||||||
|
if (timeofourlastzap + 366*24*60*60 > Timestamp.now().asSecs()){
|
||||||
|
console.log("A yearly subscription exists, and is active")
|
||||||
|
subscriptionstatus.isActive = true
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
subscriptionstatus.validuntil = timeofourlastzap + 366*24*60*60
|
||||||
|
return subscriptionstatus
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*else if (tag.asVec()[0] === "bolt11"){
|
||||||
|
let lnurl = tag.asVec()[1]
|
||||||
|
console.log(lnurl)
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// todo check that subscription is within the range
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log("A subscription exists, but no payment has been made")
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
subscriptionstatus.subscriptionId = event7001id.toHex()
|
||||||
|
return subscriptionstatus
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
export async function createBolt11Lud16(lud16, amount) {
|
|
||||||
if (lud16 === null || lud16 === ""){
|
else {
|
||||||
return null;
|
console.log("No subscription exists")
|
||||||
|
subscriptionstatus.isActive = false
|
||||||
|
return subscriptionstatus
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let url;
|
|
||||||
if (lud16.includes('@')) { // LNaddress
|
|
||||||
const parts = lud16.split('@');
|
|
||||||
url = `https://${parts[1]}/.well-known/lnurlp/${parts[0]}`;
|
|
||||||
} else { // No lud16 set or format invalid
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(url);
|
|
||||||
const response = await fetch(url);
|
|
||||||
const ob = await response.json();
|
|
||||||
const callback = ob.callback;
|
|
||||||
const amountInSats = parseInt(amount) * 1000;
|
|
||||||
const callbackResponse = await fetch(`${callback}?amount=${amountInSats}`);
|
|
||||||
const obCallback = await callbackResponse.json();
|
|
||||||
return obCallback.pr;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.log(`LUD16: ${e}`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
270
ui/noogle/src/components/helper/Zap.vue
Normal file
270
ui/noogle/src/components/helper/Zap.vue
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
import {requestProvider} from "webln";
|
||||||
|
import store from "@/store";
|
||||||
|
import {copyinvoice, fetchAsync} from "@/components/helper/Helper.vue";
|
||||||
|
import {EventBuilder, EventId, PublicKey, Tag} from "@rust-nostr/nostr-sdk";
|
||||||
|
import {bech32} from "bech32";
|
||||||
|
import {webln} from "@getalby/sdk";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function zap_nwc(invoice){
|
||||||
|
|
||||||
|
|
||||||
|
const nwc = new webln.NostrWebLNProvider({
|
||||||
|
nostrWalletConnectUrl: loadNWCUrl(),
|
||||||
|
}); // loadNWCUrl is some function to get the NWC URL from some (encrypted) storage
|
||||||
|
|
||||||
|
|
||||||
|
// connect to the relay
|
||||||
|
await nwc.enable();
|
||||||
|
|
||||||
|
// now you can send payments by passing in the invoice
|
||||||
|
const response = await nwc.sendPayment(invoice);
|
||||||
|
console.log(response)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function loadNWCObject() {
|
||||||
|
if (localStorage.getItem("nwc")){
|
||||||
|
if(JSON.parse(localStorage.getItem("nwc")).nwcUrl.startsWith("nostr+walletconnect://")){
|
||||||
|
return JSON.parse(localStorage.getItem("nwc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNWCUrl() {
|
||||||
|
if (localStorage.getItem("nwc")){
|
||||||
|
if(JSON.parse(localStorage.getItem("nwc")).nwcUrl.startsWith("nostr+walletconnect://")){
|
||||||
|
return JSON.parse(localStorage.getItem("nwc")).nwcUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function zap(invoice){
|
||||||
|
let nwcstring = loadNWCUrl()
|
||||||
|
if (nwcstring.startsWith("nostr+walletconnect://"))
|
||||||
|
{
|
||||||
|
return zap_nwc(invoice)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
let webln;
|
||||||
|
|
||||||
|
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
webln = await requestProvider();
|
||||||
|
} catch (err) {
|
||||||
|
await copyinvoice(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webln) {
|
||||||
|
try{
|
||||||
|
let response = await webln.sendPayment(invoice)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch(err){
|
||||||
|
console.log(err)
|
||||||
|
await copyinvoice(invoice)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
let nwcstring = loadNWCUrl()
|
||||||
|
if (nwcstring.startsWith("nostr+walletconnect://"))
|
||||||
|
{
|
||||||
|
return zap_nwc(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
let webln;
|
||||||
|
try {
|
||||||
|
webln = await requestProvider();
|
||||||
|
} catch (err) {
|
||||||
|
if (invoice === null){
|
||||||
|
invoice = await createBolt11Lud16(lud16, 21)
|
||||||
|
}
|
||||||
|
|
||||||
|
await copyinvoice(invoice)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (webln) {
|
||||||
|
try {
|
||||||
|
let response = await webln.sendPayment(invoice)
|
||||||
|
if (response.preimage != null && response.preimage !== "") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(err){
|
||||||
|
console.log(err)
|
||||||
|
await copyinvoice(invoice)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function zaprequest(lud16, amount, content, zapped_evt_id, zapped_usr_id, relay_list){
|
||||||
|
let url = ""
|
||||||
|
|
||||||
|
console.log(lud16)
|
||||||
|
console.log(zapped_evt_id)
|
||||||
|
|
||||||
|
|
||||||
|
let zapped_user_id = PublicKey.parse(zapped_usr_id).toHex()
|
||||||
|
let zapped_event_id = EventId.parse(zapped_evt_id).toHex()
|
||||||
|
|
||||||
|
|
||||||
|
if (lud16 !== "" && lud16.toString().includes('@')){
|
||||||
|
url = `https://${lud16.split('@')[1]}/.well-known/lnurlp/${lud16.split('@')[0]}`;
|
||||||
|
console.log(url)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
|
||||||
|
let ob = await fetchAsync(url)
|
||||||
|
let callback = ob["callback"]
|
||||||
|
console.log(callback)
|
||||||
|
|
||||||
|
|
||||||
|
const urlBytes = new TextEncoder().encode(url);
|
||||||
|
const encoded_lnurl = bech32.encode('lnurl', bech32.toWords(urlBytes), 1023);
|
||||||
|
|
||||||
|
|
||||||
|
const amount_tag = ['amount', (amount * 1000).toString()];
|
||||||
|
let relays = ['relays']
|
||||||
|
relays.push.apply(relays, relay_list)
|
||||||
|
//let relays_tag = Tag.parse(relays);
|
||||||
|
|
||||||
|
const lnurl_tag = ['lnurl', encoded_lnurl];
|
||||||
|
|
||||||
|
let tags = []
|
||||||
|
let p_tag = ['p', zapped_user_id]
|
||||||
|
if (zapped_event_id !== null){
|
||||||
|
let e_tag = ['e', zapped_event_id]
|
||||||
|
tags = [amount_tag, relays, p_tag, e_tag, lnurl_tag]
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
tags = [amount_tag, relays, p_tag, lnurl_tag]
|
||||||
|
}
|
||||||
|
/*if (zaptype === "private") {
|
||||||
|
const key_str = keys.secret_key().to_hex() + zapped_event.id().to_hex() + zapped_event.created_at().as_secs().toString();
|
||||||
|
const encryption_key = sha256(key_str).toString('hex');
|
||||||
|
const zap_request = new EventBuilder(9733, content, [p_tag, e_tag]).to_event(keys).as_json();
|
||||||
|
keys = Keys.parse(encryption_key);
|
||||||
|
const encrypted_content = enrypt_private_zap_message(zap_request, keys.secret_key(), zapped_event.author());
|
||||||
|
const anon_tag = Tag.parse(['anon', encrypted_content]);
|
||||||
|
tags.push(anon_tag);
|
||||||
|
content = "";
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let signer = store.state.signer
|
||||||
|
let zap_request = ""
|
||||||
|
|
||||||
|
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
||||||
|
let draft = {
|
||||||
|
content: content,
|
||||||
|
kind: 9734,
|
||||||
|
pubkey: store.state.pubkey.toHex(),
|
||||||
|
tags: tags,
|
||||||
|
createdAt: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = await amberSignerService.signEvent(draft)
|
||||||
|
zap_request = JSON.stringify(res)
|
||||||
|
//await sleep(3000)
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let tags_t = []
|
||||||
|
for (let tag of tags){
|
||||||
|
tags_t.push(Tag.parse(tag))
|
||||||
|
}
|
||||||
|
let noteevent = new EventBuilder(9734, content, tags_t).toUnsignedEvent(store.state.pubkey)
|
||||||
|
let signedEvent = await signer.signEvent(noteevent)
|
||||||
|
zap_request = signedEvent.asJson()
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
const queryString = `amount=${(amount * 1000).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`;
|
||||||
|
|
||||||
|
console.log(queryString)
|
||||||
|
let ob = await fetchAsync(`${callback}?${queryString}`)
|
||||||
|
return ob["pr"]
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
console.log("HELLO" + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
console.log("ZAP REQUEST: " + error)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
export async function createBolt11Lud16(lud16, amount) {
|
||||||
|
if (lud16 === null || lud16 === "") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url;
|
||||||
|
if (lud16.includes('@')) { // LNaddress
|
||||||
|
const parts = lud16.split('@');
|
||||||
|
url = `https://${parts[1]}/.well-known/lnurlp/${parts[0]}`;
|
||||||
|
} else { // No lud16 set or format invalid
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(url);
|
||||||
|
const response = await fetch(url);
|
||||||
|
const ob = await response.json();
|
||||||
|
const callback = ob.callback;
|
||||||
|
const amountInSats = parseInt(amount) * 1000;
|
||||||
|
const callbackResponse = await fetch(`${callback}?amount=${amountInSats}`);
|
||||||
|
const obCallback = await callbackResponse.json();
|
||||||
|
return obCallback.pr;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`LUD16: ${e}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
Reference in New Issue
Block a user