Skip to content

Fix Nostr relay race conditions blocking project scan/recovery#900

Merged
dangershony merged 2 commits into
mainfrom
fix/nostr-relay-subscription-race
Jun 23, 2026
Merged

Fix Nostr relay race conditions blocking project scan/recovery#900
dangershony merged 2 commits into
mainfrom
fix/nostr-relay-subscription-race

Conversation

@dangershony

Copy link
Copy Markdown
Member

Problem

Old projects (and intermittently new ones) fail to appear in My Projects after wallet recovery/scan. The project is found on-chain by the indexer, but the Nostr relay lookup silently fails, and no error is shown to the user.

Root Causes

  1. Subscription name collision - LookupProjectsInfoByEventIds used a hardcoded subscription name "ProjectInfoLookups". When ScanFounderProjects calls GetAllAsync twice (discovery + reload), the second call's EOSE action fails to register via TryAdd because the first call's cleanup hasn't completed. The TaskCompletionSource then only resolves via timeout, often with empty results.

  2. All-relays EOSE requirement - ProjectInfos and ProjectMetadatas wait for EOSE from every connected relay before completing. If even one relay is slow or doesn't have the data, the entire flow blocks until timeout (10s/30s), even though the needed data already arrived from other relays.

  3. Silent error swallowing - ScanFounderProjects silently discarded GetAllAsync failures with no logging. The UI showed no error, making the issue invisible.

  4. Toast on wrong thread - ToastRequested?.Invoke() was called inside Task.Run, causing an exception that was caught by the generic catch block, replacing the real error with "Failed to scan for projects".

Fixes

  • Unique subscription names - LookupProjectsInfoByEventIds now uses Guid.NewGuid() per call, matching the pattern used by every other method in RelayService
  • Early completion - ProjectInfos and ProjectMetadatas complete as soon as all requested data is received (deduplicated across relays), without waiting for remaining relays to EOSE
  • Error logging + propagation - ScanFounderProjects logs scan failures and propagates the error when no local projects exist
  • Toast on UI thread - Errors are collected from the background task and surfaced via toast on the caller thread

Files Changed

  • src/shared/Angor.Shared/Services/RelayService.cs - Unique subscription name
  • src/sdk/Angor.Sdk/Funding/Services/DocumentProjectService.cs - Early completion in ProjectInfos/ProjectMetadatas
  • src/sdk/Angor.Sdk/Funding/Founder/Operations/ScanFounderProjects.cs - Error logging + propagation
  • src/design/App/UI/Sections/MyProjects/MyProjectsViewModel.cs - Toast fix
  • src/sdk/Angor.Sdk.Tests/Funding/Founder/ScanFounderProjectsTests.cs - Updated for new constructor

- Use unique subscription name per LookupProjectsInfoByEventIds call
  instead of hardcoded 'ProjectInfoLookups' to prevent EOSE action
  collisions when GetAllAsync is called multiple times

- Complete ProjectInfos/ProjectMetadatas early once all requested
  data is received, instead of waiting for EOSE from all relays.
  A single slow/unresponsive relay was blocking the entire flow.

- Log scan failures in ScanFounderProjects instead of silently
  swallowing them, and propagate the error when no local projects
  exist

- Surface scan errors to the user via toast, and fix the toast
  invocation to run on the UI thread instead of inside Task.Run
Show a spinning 'Claiming Funds...' modal overlay while the SDK builds
and broadcasts the claim transaction. Previously the claim modal would
dismiss and the user saw a blank screen for ~1s before the success popup.

- Add IsClaiming-bound spinner overlay between fee selection and success
- Set IsClaiming=true before hiding claim modal to prevent frame gap
@dangershony dangershony merged commit e099ff9 into main Jun 23, 2026
3 checks passed
@dangershony dangershony deleted the fix/nostr-relay-subscription-race branch June 23, 2026 22:12
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.

1 participant