fix(nip09): honour a tags in deletion requests

A kind-5 request could only name events by `e` tag. Worse, one that
carried `a` tags and no `e` tags built a filter with an empty id list,
which matched every event by that author and marked them all deleted.

Handle `a` tags per NIP-09: parse `kind:pubkey:d` (the `d` value may
contain ':'), require the pubkey to be the request author and the kind
to be replaceable or addressable, and remove only versions up to the
request's `created_at` so a later re-publication survives. An empty
`d` addresses a replaceable kind.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt
(cherry picked from commit e695f9c66881d3d520d40f0cd3e9c95d9435938c)
This commit is contained in:
Patrick Mulligan 2026-09-13 17:28:11 +02:00 • committed by Padreug
commit fd19acff97
5 changed files with 191 additions and 52 deletions

View file

@ -120,5 +120,8 @@ class NostrEvent(BaseModel):
def has_tag_value(self, tag_name: str, tag_value: str) -> bool:
return tag_value in self.tag_values(tag_name)
def has_tag_value_other_than(self, tag_name: str, value: str) -> bool:
return any(t[0] == tag_name and t[1] != value for t in self.tags if len(t) > 1)
def is_direct_message_for_pubkey(self, pubkey: str) -> bool:
return self.is_direct_message and self.has_tag_value("p", pubkey)