From bf314ff8ac316c55cdff889e3a5c99451f63fee9 Mon Sep 17 00:00:00 2001 From: Arc Date: Thu, 30 Jul 2026 23:20:16 +0100 Subject: [PATCH] feat: nip17 nip17b support --- migrations.py | 13 +++++++++++++ models.py | 9 +++++++++ services.py | 5 +++++ static/index.js | 8 ++++++++ static/index.vue | 11 +++++++++++ tests/test_crud.py | 2 ++ tests/test_schedule_notifications.py | 29 ++++++++++++++++++++++++++++ 7 files changed, 77 insertions(+) diff --git a/migrations.py b/migrations.py index 6461d57..c4a55ae 100644 --- a/migrations.py +++ b/migrations.py @@ -275,5 +275,18 @@ async def m012_chat_schedules_seen_and_notification_jobs(db): created_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}, updated_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} ); + """ + ) + + +async def m013_categories_nostr_dm_type(db): + """ + Add the Nostr direct-message type to category notifications. + """ + + await db.execute( + """ + ALTER TABLE chat.categories + ADD COLUMN notify_nostr_dm_type TEXT NOT NULL DEFAULT 'nip04'; """ ) diff --git a/models.py b/models.py index 8646bcc..7b98eca 100644 --- a/models.py +++ b/models.py @@ -1,4 +1,5 @@ from datetime import datetime, timezone +from enum import Enum from lnbits.db import FilterModel from pydantic import BaseModel, Field @@ -6,6 +7,12 @@ DEFAULT_PUBLIC_NOTE = "we aim to reply as soon as possible but it may take up to 24hrs for a reply" +class NostrDmType(str, Enum): + nip04 = "nip04" + nip17 = "nip17" + nip17b = "nip17b" + + class CreateCategories(BaseModel): name: str wallet: str | None = None @@ -20,6 +27,7 @@ class CreateCategories(BaseModel): public_note: str | None = DEFAULT_PUBLIC_NOTE notify_telegram: str | None = None notify_nostr: str | None = None + notify_nostr_dm_type: NostrDmType = NostrDmType.nip04 notify_email: str | None = None schedule_enabled: bool | None = False schedule_timezone: str | None = "Europe/London" @@ -48,6 +56,7 @@ class Categories(BaseModel): public_note: str | None = DEFAULT_PUBLIC_NOTE notify_telegram: str | None = None notify_nostr: str | None = None + notify_nostr_dm_type: NostrDmType = NostrDmType.nip04 notify_email: str | None = None schedule_enabled: bool | None = False schedule_timezone: str | None = "Europe/London" diff --git a/services.py b/services.py index f139c28..b3764d0 100644 --- a/services.py +++ b/services.py @@ -1,6 +1,7 @@ import json import math from datetime import datetime, time, timedelta, timezone +from typing import TYPE_CHECKING, cast from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from lnbits.core.crud.users import get_user @@ -43,6 +44,9 @@ CreateChatMessage, ) +if TYPE_CHECKING: + from lnbits.core.services.notifications import NostrDmType as CoreNostrDmType + MAX_PARTICIPANTS = 10 USER_EMAIL_DELAY_MINUTES = 5 TELEGRAM_REMINDER_DELAY_MINUTES = 2 @@ -288,6 +292,7 @@ async def _notify_new_chat( _parse_notify_emails(category.notify_email), message, "chat.new", + nostr_dm_types=[cast("CoreNostrDmType", category.notify_nostr_dm_type.value)], ) diff --git a/static/index.js b/static/index.js index 1c003b4..e0c952b 100644 --- a/static/index.js +++ b/static/index.js @@ -4,6 +4,11 @@ window.PageChat = { data: function () { return { currencyOptions: ['sat'], + nostrDmTypeOptions: [ + {label: 'NIP-04', value: 'nip04'}, + {label: 'NIP-17', value: 'nip17'}, + {label: 'NIP-17B', value: 'nip17b'} + ], categoriesFormDialog: { show: false, data: { @@ -21,6 +26,7 @@ window.PageChat = { 'we aim to reply as soon as possible but it may take up to 24hrs for a reply', notify_telegram: null, notify_nostr: null, + notify_nostr_dm_type: 'nip04', notify_email: null, schedule_enabled: false, schedule_timezone: 'Europe/London', @@ -266,6 +272,7 @@ window.PageChat = { 'we aim to reply as soon as possible but it may take up to 24hrs for a reply', notify_telegram: null, notify_nostr: null, + notify_nostr_dm_type: 'nip04', notify_email: null, schedule_enabled: false, schedule_timezone: 'Europe/London', @@ -284,6 +291,7 @@ window.PageChat = { async showEditCategoriesForm(data) { this.categoriesFormDialog.data = { ...data, + notify_nostr_dm_type: data.notify_nostr_dm_type || 'nip04', schedule_enabled: data.schedule_enabled === true || data.schedule_enabled === 'true', schedule_days: (data.schedule_days || '0,1,2,3,4') diff --git a/static/index.vue b/static/index.vue index 3318b41..25e154f 100644 --- a/static/index.vue +++ b/static/index.vue @@ -537,6 +537,17 @@ hint="Optional notification target" > + + tuple[str, str, str]: category = await create_categories( uuid4().hex,