diff --git a/nostr_publisher.py b/nostr_publisher.py index 2588fcb..8374a62 100644 --- a/nostr_publisher.py +++ b/nostr_publisher.py @@ -17,7 +17,7 @@ from datetime import datetime, timezone from lnbits.core.signers import NostrSigner from loguru import logger -from .models import Event +from .models import Event, effective_payment_methods from .nostr.event import NostrEvent from .nostr_timestamp import monotonic_created_at @@ -110,6 +110,11 @@ def build_nip52_event(event: Event, pubkey: str) -> NostrEvent: tags.append(["tickets_allow_fiat", "true"]) if event.fiat_currency: tags.append(["tickets_fiat_currency", event.fiat_currency]) + # Rails the organizer accepts, resolved through the same helper the + # ticket endpoint enforces with, so a client can render exactly the + # buttons that will be accepted (e.g. a card-only event) without a REST + # round-trip. Comma-separated, lowercase. + tags.append(["tickets_payment_methods", ",".join(effective_payment_methods(event))]) # NIP-52 calendar events are replaceable: this d-tag is republished # whenever inventory changes (a ticket sells). Use a strictly-monotonic diff --git a/static/js/display.js b/static/js/display.js index d8be8e9..ad7e358 100644 --- a/static/js/display.js +++ b/static/js/display.js @@ -35,13 +35,29 @@ window.PageEventsDisplay = { async created() { this.eventId = this.$route.params.id this.event = await this.getEvent() + // Default to the first rail the organizer accepts (a card-only event + // must not submit "lightning"). + this.formDialog.data.payment_method = this.paymentMethods[0] || 'lightning' }, computed: { formatDescription() { return LNbits.utils.convertMarkdown(this.event?.info || '') }, + paymentMethods() { + // Mirrors `effective_payment_methods` on the backend: an explicit + // extra.payment_methods list wins, else Lightning + fiat-if-allow_fiat. + const explicit = this.event?.extra?.payment_methods || [] + if (explicit.length) return explicit + return ['lightning', ...(this.event?.allow_fiat ? ['fiat'] : [])] + }, allowFiatCheckout() { - return Boolean(this.event?.allow_fiat) + return this.paymentMethods.includes('fiat') + }, + paymentMethodOptions() { + return this.paymentMethods.map(method => ({ + value: method, + label: method === 'fiat' ? this.fiatCheckoutLabel : 'Lightning' + })) }, fiatCheckoutLabel() { if (!this.allowFiatCheckout) return 'Fiat' @@ -78,7 +94,8 @@ window.PageEventsDisplay = { this.formDialog.data.email = '' this.formDialog.data.refund = '' this.formDialog.data.nostr_identifier = '' - this.formDialog.data.payment_method = 'lightning' + this.formDialog.data.payment_method = + this.paymentMethods[0] || 'lightning' }, closeReceiveDialog() { @@ -112,7 +129,8 @@ window.PageEventsDisplay = { this.formDialog.data.email = '' this.formDialog.data.refund = '' this.formDialog.data.nostr_identifier = '' - this.formDialog.data.payment_method = 'lightning' + this.formDialog.data.payment_method = + this.paymentMethods[0] || 'lightning' Quasar.Notify.create({ type: 'positive', message: 'Sent, thank you!', diff --git a/static/js/display.vue b/static/js/display.vue index 9b27783..5a2ed68 100644 --- a/static/js/display.vue +++ b/static/js/display.vue @@ -90,20 +90,18 @@ :hint="`If minimum tickets (${event.extra?.min_tickets}) are not met, refund will be sent.`" >
-
+
-
+
{ Quasar.Notify.create({type: 'positive', message: 'Settings saved'}) }) @@ -326,7 +322,7 @@ window.PageEvents = { LNbits.utils .confirmDialog( 'Re-emit every approved event to Nostr relays? This is safe ' + - 'to run multiple times but generates one event per approved row.' + 'to run multiple times but generates one event per approved row.' ) .onOk(() => { this.republishing = true @@ -351,9 +347,7 @@ window.PageEvents = { }, republishMyEvents() { LNbits.utils - .confirmDialog( - 'Re-emit your approved events to Nostr relays?' - ) + .confirmDialog('Re-emit your approved events to Nostr relays?') .onOk(() => { this.republishingMine = true LNbits.api @@ -420,6 +414,17 @@ window.PageEvents = { code: code.code.trim().toUpperCase() })) } + const methods = data.extra?.payment_methods || [] + if (methods.length === 0) { + Quasar.Notify.create({ + type: 'warning', + message: 'Select at least one payment method.' + }) + return + } + // allow_fiat stays the fiat-currency carrier the backend and the + // NIP-52 tags read; keep it in lockstep with the checkbox list. + data.allow_fiat = methods.includes('fiat') if (!this.isFiatCurrency(data.currency)) { if (!data.allow_fiat) { data.fiat_currency = 'GBP' @@ -439,6 +444,15 @@ window.PageEvents = { const end = this.splitDateTime(data.event_end_date) this.formDialog.data = { ...data, + extra: { + ...(data.extra || {}), + // Events created before extra.payment_methods existed carry an + // empty list; show the rails the backend actually accepts for + // them (Lightning always, fiat when allow_fiat). + payment_methods: data.extra?.payment_methods?.length + ? data.extra.payment_methods + : ['lightning', ...(data.allow_fiat ? ['fiat'] : [])] + }, event_start_day: start.day, event_start_time: start.time, event_end_day: end.day, @@ -454,6 +468,7 @@ window.PageEvents = { event_end_day: '', event_end_time: '', extra: { + payment_methods: ['lightning'], conditional: false, min_tickets: 1, email_notifications: false, @@ -473,6 +488,7 @@ window.PageEvents = { allow_fiat: false, fiat_currency: 'GBP', extra: { + payment_methods: ['lightning'], email_notifications: false, nostr_notifications: false, promo_codes: [], diff --git a/static/js/index.vue b/static/js/index.vue index 6e6891f..502d9ad 100644 --- a/static/js/index.vue +++ b/static/js/index.vue @@ -20,10 +20,10 @@
Republish to Nostr
- Re-emit every approved event so connected clients pick - up the latest tag set. Useful after the extension - publisher changes (e.g. new tickets_* tags) so existing - events don't need a per-event edit. + Re-emit every approved event so connected clients pick up the + latest tag set. Useful after the extension publisher changes + (e.g. new tickets_* tags) so existing events don't need a + per-event edit.
@@ -56,8 +56,8 @@ >
- Re-emit your approved events to Nostr relays. Useful after - a publisher upgrade or if a relay dropped your events. + Re-emit your approved events to Nostr relays. Useful after a + publisher upgrade or if a relay dropped your events.
@@ -228,7 +228,13 @@ @@ -399,7 +405,13 @@ @@ -587,15 +599,22 @@ >
- +
+
Payment methods *
+ +
+ Card / fiat checkout goes through the fiat provider configured on + this LNbits instance. Untick Lightning for a card-only event. +
+