feat: event proposal and approval workflow #9
1 changed files with 47 additions and 0 deletions
feat: publish NIP-52 events on approve/create/update/cancel/delete
Some checks failed
lint.yml / feat: publish NIP-52 events on approve/create/update/cancel/delete (pull_request) Failing after 0s
Some checks failed
lint.yml / feat: publish NIP-52 events on approve/create/update/cancel/delete (pull_request) Failing after 0s
- On approve: publish kind 31922 calendar event to Nostr - On admin create (auto-approved): publish immediately - On update (approved event): republish (kind 31922 is replaceable) - On cancel/delete: publish kind 5 delete event - All Nostr calls are wrapped in try/except for graceful degradation - Event creator's Account keypair used for signing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
commit
2db0102857
47
views_api.py
47
views_api.py
|
|
@ -35,11 +35,38 @@ from .crud import (
|
|||
update_ticket,
|
||||
)
|
||||
from .models import CreateEvent, CreateTicket, Ticket
|
||||
from .nostr_publisher import publish_event_to_nostr
|
||||
from .services import refund_tickets, set_ticket_paid
|
||||
|
||||
events_api_router = APIRouter()
|
||||
|
||||
|
||||
async def _publish_or_delete_nostr_event(event, delete=False):
|
||||
"""Publish (or delete) a NIP-52 calendar event using the creator's keypair."""
|
||||
try:
|
||||
from lnbits.core.crud.wallets import get_wallet
|
||||
from lnbits.core.crud.users import get_account
|
||||
|
||||
from . import nostr_client
|
||||
|
||||
wallet_obj = await get_wallet(event.wallet)
|
||||
if not wallet_obj:
|
||||
return
|
||||
account = await get_account(wallet_obj.user)
|
||||
if not account or not account.pubkey or not account.prvkey:
|
||||
return
|
||||
|
||||
nostr_event = await publish_event_to_nostr(
|
||||
nostr_client, event, account.pubkey, account.prvkey, delete=delete
|
||||
)
|
||||
if nostr_event and not delete:
|
||||
event.nostr_event_id = nostr_event.id
|
||||
event.nostr_event_created_at = nostr_event.created_at
|
||||
await update_event(event)
|
||||
except Exception as e:
|
||||
logger.warning(f"[EVENTS] Nostr publish failed: {e}")
|
||||
|
||||
|
||||
@events_api_router.get("/api/v1/events")
|
||||
async def api_events(
|
||||
all_wallets: bool = Query(False),
|
||||
|
|
@ -96,6 +123,10 @@ async def api_event_create(
|
|||
for k, v in data.dict().items():
|
||||
setattr(event, k, v)
|
||||
event = await update_event(event)
|
||||
|
||||
# Republish to Nostr if event is approved (kind 31922 is replaceable)
|
||||
if event.status == "approved" and event.nostr_event_id:
|
||||
await _publish_or_delete_nostr_event(event)
|
||||
else:
|
||||
if not data.wallet:
|
||||
data.wallet = wallet.wallet.id
|
||||
|
|
@ -111,6 +142,10 @@ async def api_event_create(
|
|||
data.status = "proposed"
|
||||
event = await create_event(data)
|
||||
|
||||
# Publish to Nostr if auto-approved (admin-created)
|
||||
if event.status == "approved":
|
||||
await _publish_or_delete_nostr_event(event)
|
||||
|
||||
return event.dict()
|
||||
|
||||
|
||||
|
|
@ -131,6 +166,10 @@ async def api_event_cancel(
|
|||
event = await update_event(event)
|
||||
await refund_tickets(event.id)
|
||||
|
||||
# Delete NIP-52 event from Nostr if it was published
|
||||
if event.nostr_event_id:
|
||||
await _publish_or_delete_nostr_event(event, delete=True)
|
||||
|
||||
return event.dict()
|
||||
|
||||
|
||||
|
|
@ -147,6 +186,10 @@ async def api_form_delete(
|
|||
if event.wallet != wallet.wallet.id:
|
||||
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your event.")
|
||||
|
||||
# Delete NIP-52 event from Nostr if it was published
|
||||
if event.nostr_event_id:
|
||||
await _publish_or_delete_nostr_event(event, delete=True)
|
||||
|
||||
await delete_event(event_id)
|
||||
await delete_event_tickets(event_id)
|
||||
return "", HTTPStatus.NO_CONTENT
|
||||
|
|
@ -197,6 +240,10 @@ async def api_event_approve(
|
|||
)
|
||||
event.status = "approved"
|
||||
event = await update_event(event)
|
||||
|
||||
# Publish NIP-52 calendar event to Nostr
|
||||
await _publish_or_delete_nostr_event(event)
|
||||
|
||||
return event.dict()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue