Skip to content

Target Relay is not honored during profile sync (publishes to default relay instead) #3

Description

@advorzhak

Problem Statement

When a user selects a specific "Target Relay" in the Profile Sync interface, the application does not actually publish the selected events to that target relay. Instead, it silently publishes them to the app's default configured relay.

Root Cause

In src/hooks/useSyncProfile.ts, the mutationFn attempted to publish events using the global nostr instance first:

await nostr.event(event, { signal: AbortSignal.timeout(15000) });

The global nostr pool (configured in NostrProvider) is hardcoded to publish to config.relayUrl (the default relay) and preset relays. It completely ignored the targetRelay parameter passed to the sync function. The custom pool that actually used targetRelay was only triggered as a fallback if the default relay failed. This meant if the default relay was writable, the event was published there, reported as a "success", and the target relay was entirely bypassed.

Impact

  • Users believing they are backing up or syncing their profile to a specific relay are actually writing to the default relay.
  • Paid or protected relays cannot be targeted because the global pool does not support NIP-42 authentication challenges.

Proposed Solution

  1. Exclusive Target Routing: Modify useSyncProfile to exclusively use a dedicated NPool configured with an eventRouter that explicitly returns [targetRelay].
  2. NIP-42 Authentication: Inject an auth callback into the NRelay1 instantiation to automatically respond to AUTH challenges (kind 22242) using the current user's signer, enabling sync to paid/protected relays.
  3. Graceful Fallback: If the target relay fails, automatically attempt to publish to the default relay as a fallback, ensuring data is not lost if the target is temporarily unreachable.
  4. Explicit Logging: Add clear, prefixed console logs to indicate exactly which relay is receiving each event.
  5. Unit Tests: Add comprehensive test coverage for successful sync, fallback, failure, NIP-42 auth, and input validation.

I have implemented this fix in my fork and am opening a PR to address this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions