Skip to content

Add event rebroadcasting feature to send stored events to external relays#179

Open
greenart7c3 wants to merge 2 commits into
masterfrom
claude/nostr-event-rebroadcast-qmoi39
Open

Add event rebroadcasting feature to send stored events to external relays#179
greenart7c3 wants to merge 2 commits into
masterfrom
claude/nostr-event-rebroadcast-qmoi39

Conversation

@greenart7c3

Copy link
Copy Markdown
Owner

Summary

Adds a new rebroadcasting feature that allows users to publish events already stored in the local database to a set of user-selected external relays. This enables clients and relays to discover events that may have been missed or lost.

Key Changes

  • New EventRebroadcaster service (service/EventRebroadcaster.kt):

    • Publishes stored events to external relays in batches with configurable filters (author, kinds, date range)
    • Tracks per-relay/event OK responses to count accepted, duplicate, rejected, and failed events
    • Automatically skips unreachable relays after 3 connection failures
    • Provides real-time progress tracking via MutableStateFlow<State>
    • Handles cancellation and error states gracefully
  • New RebroadcastScreen UI (ui/RebroadcastScreen.kt):

    • Form to specify rebroadcast parameters: author (npub or hex), event kinds, date range, destination relays
    • Checkbox to optionally include private event kinds (4, 9735, 21000-29999)
    • Real-time progress display with event counts and per-relay statistics
    • Confirmation dialog before starting rebroadcast
    • Cancel button to stop an in-progress rebroadcast
  • Navigation integration:

    • Added Route.Rebroadcast to navigation routes
    • Integrated rebroadcast screen into CitrineScaffold composable
    • Added "Rebroadcast events" button to HomeScreen
    • Updated CitrineTopAppBar to display title for rebroadcast route
  • String resources (strings.xml):

    • Added 20+ localized strings for UI labels, hints, validation messages, and progress reporting

Implementation Details

  • Events are queried from the database in chunks (500 at a time) and published in batches (20 events per batch) to manage memory and relay load
  • Each batch waits up to 30 seconds for OK responses from all target relays before moving to the next batch
  • Rejection reasons are collected and displayed (up to 20 most recent) to help diagnose relay compatibility issues
  • The rebroadcaster respects the includePrivateKinds flag to avoid sending sensitive events to untrusted relays
  • Uses the existing Citrine.client (NostrClient) for publishing and integrates with the app's job cancellation system
  • Progress updates are logged via EventDownloader.setProgress() for consistency with other long-running operations

https://claude.ai/code/session_017T5Y5yTGa6KuT1UodGdec4

claude added 2 commits July 17, 2026 12:55
Adds a new Rebroadcast screen (reachable from the Home screen) that
publishes events already stored in the local database to one or more
user-selected external relays, so historical events (old zap receipts,
notes, etc.) can be discovered again by standard Nostr relays and
clients without custom import scripts.

Features:
- Rebroadcast all stored events or only those authored by a selected
  account (npub or hex pubkey)
- Filter by event kind (comma-separated list) and by date range
- Select one or multiple destination relays
- Private/sensitive event kinds (NIP-04 DMs, gift wraps, app-specific
  data) are excluded by default, with an explicit opt-in checkbox
- Live progress with per event/relay counts of accepted, duplicate,
  rejected, and unanswered publishes, plus recent rejection reasons
- Duplicates are detected via the relay's "duplicate" OK reason and
  reported separately instead of as new acceptances
- Relays that repeatedly fail to connect are skipped, and the run can
  be cancelled from the screen or the progress notification
- A warning dialog explains that relays may reject old, replaceable,
  deleted, private, or unsupported events before anything is sent

The publishing pipeline (EventRebroadcaster) batches events, waits for
NIP-01 OK responses through a NostrClient connection listener, and
never modifies the local database.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017T5Y5yTGa6KuT1UodGdec4
When an author is set on the Rebroadcast screen, a new "Add author's
relays" button fills the destination list with the author's NIP-65
write relays (from the local database when stored, otherwise fetched
from the indexer relays), falling back to the kind-3 contact list
relays when no advertised relay list exists. Local/private addresses
are filtered out so the relay never rebroadcasts to itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017T5Y5yTGa6KuT1UodGdec4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants