Commit Graph

245 Commits

Author SHA1 Message Date
Gigi
3a752a761a refactor: remove artificial timeouts from bookmark decryption
Removed all withTimeout wrappers - now matches debug page behavior:
- Direct decrypt calls with no artificial timeouts
- Let operations fail naturally and quickly
- Bunker responds instantly (success or rejection)

No timeouts needed because:
1. Account queue is disabled (requests sent immediately)
2. Only decrypting truly encrypted content (no wasted attempts)
3. Bunker either succeeds quickly or fails quickly

This makes bookmark decryption instant, just like the debug page
encryption/decryption tests.
2025-10-17 20:54:45 +02:00
Gigi
f6cc49c07a fix: only decrypt events with actual encrypted content
Use applesauce Helpers.hasHiddenContent() instead of checking for
any content. This properly detects encrypted content and avoids
sending unnecessary decrypt requests to Amber for events that just
have plain text content.

Before: (evt.content && evt.content.length > 0)
After: Helpers.hasHiddenContent(evt)

Result:
- Only events with encrypted content sent to Amber
- Reduces unnecessary decrypt requests
- Faster bookmark loading
2025-10-17 20:53:25 +02:00
Gigi
536a7ce1fa fix: disable account queue during batch decrypt operations
The applesauce BaseAccount queues requests by default, waiting for
each to complete before sending the next. This caused decrypt requests
to timeout before ever reaching Amber/bunker.

Solution:
- Set disableQueue=true before batch operations
- All decrypt requests sent immediately
- Restore original queue state after completion

This should fix the hanging/timeout issue where Amber never saw
the decrypt requests because they were stuck in the account's queue.

Ref: https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#disablequeue
2025-10-17 20:46:00 +02:00
Gigi
61072aef40 refactor: remove concurrent decryption in favor of sequential
Removed mapWithConcurrency hack:
- Simpler code with plain for loop
- More predictable behavior
- Better for bunker signers (network round-trips)
- Each decrypt happens in order, no race conditions

Sequential processing is cleaner and works better with remote signers.
2025-10-17 20:44:48 +02:00
Gigi
b7ec1fcf06 fix: add 5s timeout and smart encryption detection for bookmarks
Changes:
- Use 5-second timeout instead of 30 seconds
- Detect encryption method from content format
- NIP-04 has '?iv=' in content, NIP-44 doesn't
- Try the likely method first to avoid unnecessary timeouts
- Falls back to other method if first fails

This should:
- Prevent hanging forever (5s timeout)
- Be much faster than 30s when wrong method is tried
- Usually decrypt instantly when right method is used first
2025-10-17 20:42:46 +02:00
Gigi
d2fd8fb8fe perf: remove 30s timeout from bookmark decryption
The withTimeout wrapper was causing decrypt operations to wait
30 seconds before failing, even when bunker rejection was instant.

Now uses the same direct approach as the debug page encryption tests:
- No artificial timeouts
- Fast natural failures
- Should reduce decrypt time from 30s+ to near-instant

Fixes slow bookmark loading when bunker doesn't support nip44.
2025-10-17 20:40:07 +02:00
Gigi
a69298a3a9 perf(bunker): non-blocking bookmark decryption with concurrency limit
- Add withTimeout and mapWithConcurrency helpers in utils/async.ts
- Refactor collectBookmarksFromEvents to decrypt with 6-way concurrency
- Public bookmarks collected immediately, private decrypted in parallel
- Each decrypt wrapped with 30s timeout safety net
- Document non-blocking publish and concurrent decrypt in Amber.md
2025-10-17 13:27:50 +02:00
Gigi
a74760d804 chore(bunker): increase decrypt timeouts (probe 10s, bookmark decrypt 30s) 2025-10-17 09:36:13 +02:00
Gigi
f65f2c6597 chore(lint): remove explicit any types, add deps for useEffect, and type relay logging 2025-10-17 01:24:41 +02:00
Gigi
227def4328 chore(lint): replace empty catch blocks with warnings; keep strict rules 2025-10-17 01:22:53 +02:00
Gigi
ec45fbc5e8 debug(bunker): log signer publish/subscribe calls and relay connectivity
- Wrap NostrConnectSigner publish/subscription to log relays and filters
- Log relayPool connectivity snapshot before bookmark decryption
- Helps diagnose decrypt requests not reaching Amber
2025-10-17 00:17:00 +02:00
Gigi
53400334b2 Revert "fix: skip bookmark decryption for bunker signers"
This reverts commit af4ff7081a.
2025-10-17 00:12:20 +02:00
Gigi
af4ff7081a fix: skip bookmark decryption for bunker signers
- Bunker (NIP-46) signers don't reliably support async decrypt operations
- Skip attempting to decrypt private bookmarks when using bunker
- Users can still see all public bookmarks
- Use extension signer for access to encrypted private bookmarks
- Prevents 15+ second hangs waiting for decrypt responses that won't come
2025-10-17 00:11:20 +02:00
Gigi
55e44dcc9c debug: increase decrypt timeout to 15 seconds
- Give bunker operations more time to respond
- Will help determine if this is a timing issue or a fundamental limitation
- Still logging timeout errors for visibility
2025-10-17 00:05:53 +02:00
Gigi
f451348430 debug: add logging to bookmark decrypt error handling
- Log nip04/nip44 decrypt errors instead of silently ignoring
- Will help identify why bookmark decryption is timing out with bunker
- Timeout errors will now be visible in console
2025-10-16 23:55:30 +02:00
Gigi
685aaf43b0 fix: add timeout to bookmark decryption to prevent hanging
- Wrap nip04/nip44 decrypt calls with 5 second timeout
- Prevents UI from hanging if decrypt request doesn't receive response
- Allows graceful degradation instead of infinite wait
- With bunker, decrypt responses may not arrive if perms/relay issues
2025-10-16 23:54:31 +02:00
Gigi
d6a20b5272 debug: add [bunker] prefix to bookmark decryption logging
- Better filtering of bunker-related logs
- Track when signer candidate is being selected
2025-10-16 23:50:16 +02:00
Gigi
d8d7a19fa1 fix: pass account.signer to EventFactory instead of full account
- EventFactory expects an EventSigner interface with signEvent method
- account.signer is the actual NostrConnectSigner instance
- Add debug logging to trace signer type
- This should fix signing hanging when using bunker
2025-10-16 23:46:25 +02:00
Gigi
bcb28a63a7 refactor: cleanup after bunker signing implementation
- Remove reconnectBunkerSigner function, inline logic into App.tsx for better control
- Clean up try-catch wrapper in highlightCreationService, signing now works reliably
- Remove extra logging from signing process (already has [bunker] prefix logs)
- Simplify nostrConnect.ts to just export permissions helper
- Update api/article-og.ts to use local relay config instead of import
- All bunker signing tests now passing 
2025-10-16 23:39:31 +02:00
Gigi
a479903ce3 debug: log signer state before signing 2025-10-16 23:34:59 +02:00
Gigi
567d105261 fix: restore isConnected = true so signing doesn't hang
- Without this, requireConnection() tries to connect() again
- That breaks the entire signing flow
- Mark signer as connected after opening subscription
2025-10-16 23:33:31 +02:00
Gigi
83743c5a9f fix: remove decrypt queue that was blocking highlight signing
- The global decrypt queue in bookmarkProcessing was getting stuck
- Caused all NIP-46 operations to hang indefinitely
- Decrypt already has per-call timeouts; queue was unnecessary
- Highlights should now sign immediately without waiting for bookmarks
2025-10-16 23:30:18 +02:00
Gigi
0b8f88ea1d revert(highlight): avoid pre-connect; rely on requireConnection during sign
- Remove manual connect/open in highlight flow
- Prevent side-effects that may interfere with pending requests
2025-10-16 23:28:06 +02:00
Gigi
fadc755930 fix(highlight): ensure NIP-46 signer is open/connected before signing
- Pre-open subscription and connect() if bunker signer present
- Restores reliable highlight signing with Amber (NIP-46)
2025-10-16 23:26:28 +02:00
Gigi
f67f171e64 fix(bookmarks): serialize decrypt/unlock NIP-46 operations
- Queue decrypt/unlock to avoid overlapping requests hanging the provider
- Keep timeouts and detailed [bunker] logs
- Should stop decrypt flood from blocking highlight signing
2025-10-16 23:21:52 +02:00
Gigi
2f8a64826a debug: restore [bunker] logs around highlight signing
- Log before/after factory.sign for highlights
- Surface errors to console for fast diagnosis
2025-10-16 23:16:59 +02:00
Gigi
11cb3542ee fix: revert forced connect on reconnection to restore signing
- Remove connect(undefined, permissions) on restore
- Let requireConnection() trigger connect per op
- Keeps highlights signing working as before while we debug decrypt
2025-10-16 23:11:08 +02:00
Gigi
905296621c fix: pass permissions on reconnect to ensure decrypt allowed
- Call signer.connect(undefined, permissions) when restoring account
- Ensures bunker re-grants decrypt (nip04/nip44) if needed
- Keeps implementation aligned with applesauce examples
2025-10-16 23:06:06 +02:00
Gigi
27ff4cef22 fix: properly connect NostrConnectSigner on reconnection
- Call signer.connect() instead of forcing isConnected
- Add [bunker] logs for connect lifecycle
- Should unblock nip44/nip04 decrypt calls that were timing out
2025-10-16 22:55:17 +02:00
Gigi
a352e2616e fix: prevent decrypt hangs with timeout + fallback
- Wrap nip44/nip04 decrypt and unlockHiddenTags in timeouts
- Fallback nip44->nip04 if nip44 hangs/fails
- Add detailed [bunker] logs for each stage
- Keeps UI responsive while debugging bunker responses
2025-10-16 22:51:58 +02:00
Gigi
77cbb9394f refactor: simplify bunker implementation following applesauce patterns
- Remove bunkerFixVersion migration logic
- Simplify account loading to match applesauce examples
- Simplify reconnectBunkerSigner (no waiting, no complex logging)
- Direct nip04/nip44 exposure from signer (like ExtensionAccount)
- Clean up bookmark service account checking
- Keep debug logs for now until verified working
2025-10-16 22:48:46 +02:00
Gigi
a76b703d36 fix: cache wrapped nip04/nip44 objects instead of using getters
- Getters were returning new objects each time
- Code was getting reference then calling decrypt on it
- Now assign wrapped objects directly as properties
- This ensures our logging wrappers are actually used
2025-10-16 22:42:47 +02:00
Gigi
df51173405 debug: wrap nip04/nip44 methods with [bunker] logging
- Log when decrypt/encrypt methods are called
- Log when they complete or fail
- Show pubkey and ciphertext/plaintext lengths
- This will tell us if decrypt is hanging in the signer or never returning
2025-10-16 22:41:04 +02:00
Gigi
a79d7f9eaf debug: enable NostrConnectSigner logging to diagnose decrypt hang
- Add detailed logging for signer subscription opening
- Enable debug logs for NostrConnectSigner via localStorage
- This will show if requests are being sent and responses received
- Helps diagnose why decrypt requests hang indefinitely
2025-10-16 22:40:00 +02:00
Gigi
1032a46456 fix: wait for bunker relay connections before marking signer ready
- Decryption was hanging because relay connections weren't established
- NostrConnectSigner sends requests via relays but pool wasn't connected
- Now wait for at least one bunker relay to be connected (5s timeout)
- Prevents decrypt/sign requests from being sent to unconnected relays
- Adds detailed logging for connection status
2025-10-16 22:37:45 +02:00
Gigi
ae997758ab debug: add detailed [bunker] logs for bookmark decryption
- Log account properties and nip04/nip44 availability
- Log signer fallback logic
- Log each decryption attempt (nip44 and nip04)
- Log success/failure for hidden tags and content decryption
- Helps diagnose why bunker decryption isn't working
2025-10-16 22:36:00 +02:00
Gigi
91a827324d fix: expose nip04/nip44 on NostrConnectAccount for bookmark decryption
- NostrConnectSigner has nip04/nip44 but not exposed at account level
- ExtensionAccount exposes these via getters, NostrConnectAccount didn't
- Add properties dynamically during reconnection for compatibility
- Enables private bookmark decryption with bunker accounts
2025-10-16 22:34:18 +02:00
Gigi
bf849c9faa refactor: clean up bunker implementation for better maintainability
- Extract reconnectBunkerSigner into reusable helper function
- Reduce excessive debug logging in App.tsx (90+ lines → 30 lines)
- Simplify account restoration logic with cleaner conditionals
- Remove verbose signing logs from highlightCreationService
- Keep only essential error logs for debugging
- Follows DRY principles and applesauce patterns
2025-10-16 22:32:06 +02:00
Gigi
6a59ecfa47 debug: prefix all bunker logs with [bunker] for easy filtering
- Update App.tsx reconnection logs
- Update highlightCreationService signing logs
- Update LoginOptions error logs
- Makes it easy to filter console with 'bunker' keyword
2025-10-16 22:12:56 +02:00
Gigi
272066c6e0 debug: add comprehensive logging for bunker reconnection and signing
- Add detailed logs for active account changes and bunker detection
- Log signer status (listening, isConnected, hasRemote)
- Log each step of reconnection process
- Add signing attempt logs in highlightCreationService
- This will help diagnose where the signing process hangs
2025-10-16 22:08:14 +02:00
Gigi
c22419ba0e fix: ensure bunker signer reconnects with permissions on app restore
- Create centralized getDefaultBunkerPermissions() in nostrConnect service
- Update LoginOptions to use centralized permissions
- Add bunker reconnection logic in App.tsx on active account change
- Reconnect bunker signer with open() and connect() when restored from localStorage
- Surface permission errors to users via toast in useHighlightCreation
- Ensures highlights, reactions, settings, and bookmarks work after page reload with bunker
2025-10-16 21:56:31 +02:00
Gigi
8278fed2fb fix: request NIP-46 permissions for bunker signing
- Add explicit signing permissions for event kinds: 5, 7, 17, 9802, 30078, 39701, 0
- Add encryption/decryption permissions: nip04_encrypt/decrypt, nip44_encrypt/decrypt
- Improve error messages when bunker permissions are missing or denied
- Add debug logging hint for bunker permission issues in write service
- This ensures highlights, reactions, settings, reading positions, and web bookmarks all work with bunker
2025-10-16 21:47:59 +02:00
Gigi
c50aa3a243 fix: resolve TypeScript errors from merge
- Remove unused readingPositions and markedAsReadIds from useBookmarksData
- Remove eventStore parameter from useBookmarksData call
- Add reads and links fields to MeCache interface
2025-10-16 09:53:20 +02:00
Gigi
99df4d6761 chore: merge master into reading-progress-filters-part-two
Resolved conflicts by keeping feature branch changes:
- Kept /me/reads and /me/links routes (not /me/archive)
- Kept ReadingProgressFilters component and readingProgressUtils
- Kept readsService, linksService, and readingDataProcessor
- Restored files that were renamed/deleted in master
2025-10-16 09:49:13 +02:00
Gigi
5f6a414953 fix: resolve all linter errors and type issues
- Remove unused state variables (readsMap, linksMap) by using only setters
- Move VALID_FILTERS constant outside component to fix exhaustive-deps warning
- Remove unused isReading variable in ReadingProgressIndicator
- Remove unused extractUrlFromBookmark function and IndividualBookmark import
- Fix type errors in linksFromBookmarks by extracting metadata from tags instead of non-existent properties
2025-10-16 09:36:17 +02:00
Gigi
9d6b1f6f84 fix: call onItem callback directly for items already in reads map 2025-10-16 09:18:32 +02:00
Gigi
fddf79e0c6 feat: add named kind constants, streaming updates, and fix reads/links tabs
- Create src/config/kinds.ts with named Nostr kind constants
- Add streaming support to fetchAllReads and fetchLinks with onItem callbacks
- Update all services to use KINDS constants instead of magic numbers
- Add mergeReadItem utility for DRY state management
- Add fallbackTitleFromUrl for external links without titles
- Relax validation to allow external items without titles
- Update Me.tsx to use streaming with Map-based state for reads/links
- Fix refresh to merge new data instead of clearing state
- Fix empty states for Reads and Links tabs (no more infinite skeletons)
- Services updated: readsService, linksService, libraryService, bookmarkService, exploreService, highlights/fetchByAuthor
2025-10-16 08:27:10 +02:00
Gigi
5568437663 Revert "Add reading progress filters and split Reads/Links tabs" 2025-10-16 08:05:20 +02:00
Gigi
f44e36e4bf refactor: make code more DRY by extracting shared utilities
- Create readingProgressUtils.ts with filterByReadingProgress function
- Create readingDataProcessor.ts with shared processing functions:
  - processReadingPositions
  - processMarkedAsRead
  - filterValidItems
  - sortByReadingActivity
- Refactor readsService.ts to use shared utilities
- Refactor linksService.ts to use shared utilities
- Eliminate 100+ lines of duplicated code
- Simplify Me.tsx filter logic to 2 lines

Benefits:
- Single source of truth for reading progress filtering
- Easier to maintain and modify
- Less code duplication across services
- More testable with isolated utility functions
2025-10-16 01:36:28 +02:00
Gigi
11c7564f8c feat: split Reads tab into Reads and Links
- Reads: Only Nostr-native articles (kind:30023)
- Links: Only external URLs with reading progress
- Create linksService.ts for fetching external URL links
- Update readsService to filter only Nostr articles
- Add Links tab between Reads and Writings with same filtering
- Add /me/links route
- Update meCache to include links field
- Both tabs support reading progress filters
- Lazy loading for both tabs

This provides clear separation between native Nostr content and external web links.
2025-10-16 01:33:04 +02:00