Add NIP-09 support for parameterized replaceable events (NIP-33)
Extended NIP-09 deletion event handling to support both regular events and parameterized replaceable events (NIP-33). **Previous behavior:** - Only handled 'e' tags (regular event IDs) - Did not support 'a' tags for addressable/replaceable events **New behavior:** - Handles both 'e' tags (event IDs) and 'a' tags (event addresses) - Parses 'a' tag format: kind:pubkey:d-identifier - Validates deletion author matches event address pubkey (NIP-09 requirement) - Creates appropriate filters for each deletion type **Implementation:** - Added parsing for 'a' tag event addresses - Extract kind, pubkey, and d-tag from address format - Build NostrFilter with authors, kinds, and d-tag parameters - Collect all event IDs to delete from both 'e' and 'a' tags - Mark matching events as deleted in single operation This enables proper deletion of parameterized replaceable events like calendar events (kind 31922-31924), long-form content (kind 30023), and other addressable event kinds. Implements NIP-09: https://github.com/nostr-protocol/nips/blob/master/09.md Supports NIP-33: https://github.com/nostr-protocol/nips/blob/master/33.md
This commit is contained in:
parent
c4efb87b70
commit
8bfd792548
1 changed files with 40 additions and 6 deletions
|
|
@ -208,12 +208,46 @@ class NostrClientConnection:
|
|||
await self.websocket.send_text(json.dumps(data))
|
||||
|
||||
async def _handle_delete_event(self, event: NostrEvent):
|
||||
# NIP 09
|
||||
nostr_filter = NostrFilter(authors=[event.pubkey])
|
||||
nostr_filter.ids = [t[1] for t in event.tags if t[0] == "e"]
|
||||
# NIP 09 - Handle both regular events (e tags) and parameterized replaceable events (a tags)
|
||||
|
||||
# Get event IDs from 'e' tags (for regular events)
|
||||
event_ids = [t[1] for t in event.tags if t[0] == "e"]
|
||||
|
||||
# Get event addresses from 'a' tags (for parameterized replaceable events)
|
||||
event_addresses = [t[1] for t in event.tags if t[0] == "a"]
|
||||
|
||||
ids_to_delete = []
|
||||
|
||||
# Handle regular event deletions (e tags)
|
||||
if event_ids:
|
||||
nostr_filter = NostrFilter(authors=[event.pubkey], ids=event_ids)
|
||||
events_to_delete = await get_events(self.relay_id, nostr_filter, False)
|
||||
ids = [e.id for e in events_to_delete if not e.is_delete_event]
|
||||
await mark_events_deleted(self.relay_id, NostrFilter(ids=ids))
|
||||
ids_to_delete.extend([e.id for e in events_to_delete if not e.is_delete_event])
|
||||
|
||||
# Handle parameterized replaceable event deletions (a tags)
|
||||
if event_addresses:
|
||||
for addr in event_addresses:
|
||||
# Parse address format: kind:pubkey:d-tag
|
||||
parts = addr.split(":")
|
||||
if len(parts) == 3:
|
||||
kind_str, addr_pubkey, d_tag = parts
|
||||
try:
|
||||
kind = int(kind_str)
|
||||
# Only delete if the address pubkey matches the deletion event author
|
||||
if addr_pubkey == event.pubkey:
|
||||
nostr_filter = NostrFilter(
|
||||
authors=[addr_pubkey],
|
||||
kinds=[kind],
|
||||
d=[d_tag]
|
||||
)
|
||||
events_to_delete = await get_events(self.relay_id, nostr_filter, False)
|
||||
ids_to_delete.extend([e.id for e in events_to_delete if not e.is_delete_event])
|
||||
except ValueError:
|
||||
logger.warning(f"Invalid kind in address: {addr}")
|
||||
|
||||
# Only mark events as deleted if we found specific IDs
|
||||
if ids_to_delete:
|
||||
await mark_events_deleted(self.relay_id, NostrFilter(ids=ids_to_delete))
|
||||
|
||||
async def _handle_request(
|
||||
self, subscription_id: str, nostr_filter: NostrFilter
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue