From 51f009a4890cbc3d9c0e4c0b1d2c96c3968c1ae8 Mon Sep 17 00:00:00 2001 From: Gigi Date: Thu, 2 Oct 2025 21:30:12 +0200 Subject: [PATCH] feat(bookmarks): try NIP-44 then NIP-04 for manual decryption; cache decrypted hidden tags for display/debug --- src/services/bookmarkService.ts | 73 ++++++++++++--------------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/src/services/bookmarkService.ts b/src/services/bookmarkService.ts index f67f2833..6c445e58 100644 --- a/src/services/bookmarkService.ts +++ b/src/services/bookmarkService.ts @@ -246,65 +246,44 @@ export const fetchBookmarks = async ( } // For events that have content but aren't recognized as supporting hidden tags (like kind 30001) else if (evt.content && evt.content.length > 0 && signerCandidate) { + console.log('๐Ÿ”“ Attempting manual decryption for event with unrecognized kind...') + console.log('๐Ÿ“„ Content to decrypt:', evt.content.slice(0, 100) + '...') + + // Try NIP-44 first (common for bookmark lists), then fall back to NIP-04 + let decryptedContent: string | undefined try { - console.log('๐Ÿ”“ Attempting manual decryption for event with unrecognized kind...') - console.log('๐Ÿ“„ Content to decrypt:', evt.content.slice(0, 100) + '...') - - // Try direct decryption using the signer's nip04 capabilities - console.log('๐Ÿ” Calling nip04.decrypt with:', { - pubkey: evt.pubkey, - contentLength: evt.content.length, - contentPrefix: evt.content.slice(0, 20) + '...', - signerType: typeof signerCandidate - }) - - let decryptedContent - try { - decryptedContent = await (signerCandidate as any).nip04?.decrypt(evt.pubkey, evt.content) - console.log('โœ… Successfully decrypted content manually:', decryptedContent.slice(0, 100) + '...') - } catch (decryptError) { - console.warn('โŒ Browser extension decryption failed:', decryptError) - - // Try alternative content formatting (maybe it needs to be a string) - try { - console.log('๐Ÿ”„ Trying alternative content format...') - const contentStr = String(evt.content) - decryptedContent = await (signerCandidate as any).nip04?.decrypt(evt.pubkey, contentStr) - console.log('โœ… Successfully decrypted with string format:', decryptedContent.slice(0, 100) + '...') - } catch (secondError) { - console.warn('โŒ Second decryption attempt also failed:', secondError) - - // Check if the error contains the actual response from the extension - if (decryptError?.message?.includes('result:')) { - const resultMatch = decryptError.message.match(/result:\s*(\{.*\})/) - if (resultMatch) { - const extensionResult = JSON.parse(resultMatch[1]) - console.warn('โŒ Extension returned:', extensionResult) - } - } - throw decryptError - } + if ((signerCandidate as any).nip44?.decrypt) { + console.log('๐Ÿงช Trying NIP-44 decryption...') + decryptedContent = await (signerCandidate as any).nip44.decrypt(evt.pubkey, evt.content) } + } catch (nip44Err) { + console.warn('โŒ NIP-44 manual decryption failed, will try NIP-04:', nip44Err) + } + if (!decryptedContent) { + try { + if ((signerCandidate as any).nip04?.decrypt) { + console.log('๐Ÿงช Trying NIP-04 decryption...') + decryptedContent = await (signerCandidate as any).nip04.decrypt(evt.pubkey, evt.content) + } + } catch (nip04Err) { + console.warn('โŒ NIP-04 manual decryption failed:', nip04Err) + } + } + + if (decryptedContent) { + console.log('โœ… Successfully decrypted content manually') // Parse the decrypted content as JSON (should be array of tags) try { const hiddenTags = JSON.parse(decryptedContent) console.log('๐Ÿ“‹ Decrypted hidden tags:', hiddenTags.length, 'tags') - - // Set the cached value on the event so getHiddenBookmarks can find it + // Cache so applesauce can read hidden tags downstream Reflect.set(evt, BookmarkHiddenSymbol, hiddenTags) Reflect.set(evt, 'EncryptedContentSymbol', decryptedContent) - + if (!latestContent) { latestContent = decryptedContent } } catch (parseError) { console.warn('โŒ Failed to parse decrypted content as JSON:', parseError) } - } catch (error) { - console.warn('โŒ Failed manual decryption:', error) - console.warn('โŒ Error details:', { - message: error?.message, - stack: error?.stack, - name: error?.name - }) } }