Skip to content

Conversation

@alltheseas
Copy link
Collaborator

@alltheseas alltheseas commented Dec 18, 2025

Summary

Per NIP-18, quote posts use q tags: ["q", "<event-id>", "<relay-url>", "<pubkey>"]. Third-party Nostr clients may only include the q tag without a separate p tag for the quoted note's author. This causes Damus to miss quote notifications because the existing notification filter only uses #p (pubkey) matching.

This fix adds quote notification detection by:

  1. Loading our quotable note IDs from nostrdb at startup (text, longform, highlight)
  2. Adding a second notification filter using #q with our note IDs
  3. Updating handle_notification() to accept events that either reference our pubkey OR quote one of our notes
  4. Tracking new notes we post during the session with debounced subscription refresh
  5. FIFO eviction to cap tracked note IDs at 1000 for bounded memory growth

Checklist

Standard PR Checklist

  • I have read (or I am familiar with) the Contribution Guidelines
  • I have tested the changes in this PR
  • I have profiled the changes to ensure there are no performance regressions, or I do not need to profile the changes.
    • If not needed, provide reason: Changes add minimal overhead (Set lookups, nostrdb query at startup)
  • I have opened or referred to an existing github issue related to this change.
  • My PR is either small, or I have split it into smaller logical commits that are easier to review
  • I have added the signoff line to all my commits. See Signing off your work
  • I have added appropriate changelog entries for the changes in this PR. See Adding changelog entries
  • I have added appropriate Closes: or Fixes: tags in the commit messages wherever applicable, or made sure those are not needed. See Submitting patches

Test report

Device: iPhone 17 Pro Simulator

iOS: iOS 26

Damus: Commit 4085b5a

Setup: Test account configured with existing posts that can be quoted

Steps:

  1. Build and run on iOS 26 iPhone 17 simulator
  2. Post a note from test account
  3. Quote the note from a third-party client (without p tag)
  4. Observe notifications tab in Damus
  5. Run unit tests: QuoteNotificationTests (5 tests)

Results:

  • PASS
    • Quote notifications observed in notifications tab
    • All 5 unit tests pass

Screenshots

image image image

Other notes

This PR also includes 5 regression tests in QuoteNotificationTests.swift covering:

  • Standard p-tag notification detection
  • Quote event detection via q-tag
  • Combined notification relevance logic
  • Negative cases (events not referencing us)

Closes #3447
Closes #3449
Closes #3450

alltheseas and others added 2 commits December 17, 2025 23:16
Per NIP-18, quote posts use q tags: ["q", "<event-id>", "<relay-url>", "<pubkey>"].
Third-party Nostr clients may only include the q tag without a separate p tag
for the quoted note's author. This causes Damus to miss quote notifications
because the existing notification filter only uses #p (pubkey) matching.

This fix adds quote notification detection by:

1. Loading our quotable note IDs from nostrdb at startup (text, longform, highlight)
2. Adding a second notification filter using #q with our note IDs
3. Updating handle_notification() to accept events that either:
   - Reference our pubkey in a p tag (existing behavior)
   - OR quote one of our notes via a q tag (new behavior)
4. Tracking new notes we post during the session
5. Refreshing the notification subscription (debounced) when we post new notes
   so quotes of newly posted notes are also detected

Key implementation details:
- quotableKinds: Defines which event kinds can be quoted (text, longform, highlight)
- subscribe_to_notifications(): Extracted method that can be called to refresh
  the subscription when our note IDs change
- notifications_resub_debouncer: Prevents excessive resubscription when posting
  multiple notes in quick succession
- our_note_ids_order: Tracks insertion order for FIFO eviction when cap exceeded
- maxOurNoteIds: Caps set at 1000 to prevent unbounded growth during long sessions

The implementation uses nevernesting with guard clauses for clean control flow.

Changelog-Fixed: Fixed missing quote notifications from third-party clients

Closes damus-io#3447
Closes damus-io#3449
Closes damus-io#3450
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Adds QuoteNotificationTests.swift with 5 tests to verify:

1. testEventHasOurPubkey - Standard p-tag detection still works
2. testEventDoesNotHaveOurPubkey - Events without our pubkey are rejected
3. testQuoteEventReferencesOurNote - Quote events with q-tag are detected
4. testQuoteEventDoesNotReferenceOurNote - Unrelated quotes are rejected
5. testCombinedNotificationRelevanceCheck - Both p-tag and q-tag paths work

These tests ensure the quote notification fix works correctly and prevents
regression. The tests verify the core validation logic that determines
whether an event is relevant as a notification.

Note: These tests cover the event validation helpers (event_has_our_pubkey,
referenced_quote_ids) but not the subscription wiring (subscribe_to_notifications).
Integration testing of subscription refresh would require a more complex test
harness with mock network components.

Closes damus-io#3447
Closes damus-io#3449
Closes damus-io#3450
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@alltheseas alltheseas added reposts Quote reposts, reposts, etc notifications labels Dec 18, 2025
@alltheseas alltheseas changed the title fix: detect quote notifications from third-party clients fix: (detect) quote notifications (from third-party clients) Dec 18, 2025
@danieldaquino danieldaquino added the pr-in-queue This PR is waiting in a queue behind their other PRs marked with the label `pr-active-review`. label Dec 20, 2025
@alltheseas alltheseas force-pushed the fix/quote-notifications branch from bb70c24 to 4085b5a Compare December 22, 2025 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

notifications pr-in-queue This PR is waiting in a queue behind their other PRs marked with the label `pr-active-review`. reposts Quote reposts, reposts, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

notify me if my longform article is quoted notify me if my highlight or quote highlight is quoted quote notifications are broken

2 participants