feat(media): encrypted file sharing in desktop DMs (NIP-17 Phase 6)

Add full send + receive encrypted media support in desktop DM chat:
- Paperclip attach button and drag-and-drop in ChatPane (NIP-17 mode only)
- AES-GCM encryption before upload to Blossom server
- ChatMessageEncryptedFileHeaderEvent (kind 15) wrapped in GiftWrap
- sendNip17EncryptedFile() added to IAccount interface and implementations
- DesktopUploadOrchestrator.uploadEncrypted() with proper encrypted hash
- DesktopBlossomClient ByteArray upload overload for encrypted blobs
- LRU cache in EncryptedMediaService to avoid re-downloading
- Error handling: retry on failure, disable send during upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
nrobi144
2026-03-19 06:53:36 +02:00
parent c90bf8f610
commit 24d4073b9b
9 changed files with 343 additions and 27 deletions
@@ -97,9 +97,9 @@ Branch has 13 commits implementing Phases 0-9 of desktop media: image display, u
| # | Test | Steps | Expected | Status |
|---|------|-------|----------|--------|
| 6.1 | DM file attach | Open DM → attach file | Encryption indicator visible | ⬜ BLOCKED — no attach button in DM input (send not implemented) |
| 6.2 | Send encrypted | Attach file in DM → send | File uploads encrypted to Blossom | ⬜ BLOCKED — send not implemented |
| 6.3 | Receive encrypted | Receive DM with encrypted file from another client | File downloads and decrypts; displays correctly | ⬜ TODO |
| 6.1 | DM file attach | Open DM → click paperclip → select file | File thumbnail with lock icon visible above input | ⬜ TODO — implemented, needs manual test |
| 6.2 | Send encrypted | Attach file in DM → send | File uploads encrypted to Blossom, kind 15 in GiftWrap | ⬜ TODO — implemented, needs manual test |
| 6.3 | Receive encrypted | Receive DM with encrypted file from another client | File downloads and decrypts; displays correctly | ⬜ TODO — ChatFileAttachment implemented |
| 6.4 | Wrong key | (If testable) Attempt to view another user's encrypted media | Decryption fails gracefully | ⬜ TODO |
---
@@ -1,7 +1,7 @@
---
title: "feat: Desktop DM Encrypted Media (NIP-17)"
type: feat
status: active
status: completed
date: 2026-03-18
deepened: 2026-03-18
origin: docs/brainstorms/2026-03-18-desktop-dm-encrypted-media-brainstorm.md
@@ -728,20 +728,20 @@ object EncryptedMediaService {
## Acceptance Criteria
- [ ] Paperclip attach button visible in DM chat input (NIP-17 mode only)
- [ ] File picker opens, supports image/video/audio selection
- [ ] Selected files show as thumbnails above input with X to remove
- [ ] Drag-and-drop files onto chat area adds to attachments (visual drop indicator)
- [ ] Send encrypts files with AES-GCM before upload to Blossom
- [ ] Kind 15 `ChatMessageEncryptedFileHeaderEvent` sent wrapped in GiftWrap
- [ ] Lock icon overlay visible on attachment thumbnails before send
- [ ] Received encrypted media downloads, decrypts, displays inline
- [ ] Lock icon overlay on received encrypted media in chat bubbles
- [ ] Wrong key / failed decryption shows error state, no crash
- [ ] Upload progress indicator during encrypt + upload
- [ ] No attach button when in NIP-04 mode
- [ ] `canSend` true when files attached (even without text)
- [ ] Send button disabled during active upload
- [x] Paperclip attach button visible in DM chat input (NIP-17 mode only)
- [x] File picker opens, supports image/video/audio selection
- [x] Selected files show as thumbnails above input with X to remove
- [x] Drag-and-drop files onto chat area adds to attachments (visual drop indicator)
- [x] Send encrypts files with AES-GCM before upload to Blossom
- [x] Kind 15 `ChatMessageEncryptedFileHeaderEvent` sent wrapped in GiftWrap
- [x] Lock icon overlay visible on attachment thumbnails before send
- [x] Received encrypted media downloads, decrypts, displays inline
- [x] Lock icon overlay on received encrypted media in chat bubbles
- [x] Wrong key / failed decryption shows error state, no crash
- [x] Upload progress indicator during encrypt + upload
- [x] No attach button when in NIP-04 mode
- [x] `canSend` true when files attached (even without text)
- [x] Send button disabled during active upload
## Test Plan (from Phase 6 testing plan)