- Import NostrEvent type from nostr-tools
- Replace any[] with NostrEvent[] for events array
- Replace Map<string, any> with Map<string, NostrEvent> for eventsMap
- Resolves ESLint warnings about explicit any usage
- loadUserRelayList accepts onUpdate callback to stream first user relay list
- App.tsx applies interim relay set on first event, keeps alive, then recomputes with blocked relays
- Keeps startup non-blocking and matches Debug page behavior
- Add onEvent streaming callback to relayListService queryEvents call
- Process events as they arrive instead of waiting for all relays to respond
- Deduplicate events by id and keep most recent version
- Remove artificial delay since streaming provides immediate results
- Should resolve hanging issue where debug works but app query hangs
- Add relayListService to load kind:10002 (user relay list) and kind:10006 (blocked relays)
- Add relayManager to compute active relay set and dynamically manage pool membership
- Update App.tsx to fetch and apply user relays on login, reset on logout
- Replace all hardcoded RELAYS usages with dynamic getActiveRelayUrls() across services and components
- Always preserve localhost relays (ws://localhost:10547, ws://localhost:4869) regardless of user blocks
- Merge bunker relays, user relays, and hardcoded relays while excluding blocked relays
- Update keep-alive subscription and address loaders to use dynamic relay set
- Modified files: App.tsx, relayListService.ts (new), relayManager.ts (new), readsService.ts, readingProgressController.ts, archiveController.ts, libraryService.ts, reactionService.ts, writeService.ts, HighlightItem.tsx, ContentPanel.tsx, BookmarkList.tsx, Profile.tsx