Files
grimoire/src/lib/dm-debug.ts
Alejandro Gómez cfeb40f42d fix: Improve NIP-17 inbox relay detection and UX
This commit refines the NIP-17 encrypted messaging implementation with
better relay detection, cleaner UI, and comprehensive documentation.

## Core Fixes

### 1. Fix Missing User Inbox Relays (nip-17-adapter.ts)
- **Problem**: When creating conversations, user's own inbox relays were
  only checked from cache, not actively fetched if cache was empty
- **Result**: Send failures with "missing relays" even when relays were
  fetched and connected elsewhere
- **Solution**: Actively fetch user's inbox relays if cache is empty,
  with fallback to cached value for performance
- **Impact**: Reliable relay detection for sending messages

### 2. Improve View-Only Detection (ChatViewer.tsx)
- **Problem**: Used stale `unreachableParticipants` metadata set at
  conversation creation time, causing false warnings even after relay
  lists loaded
- **Solution**: Added dynamic `canSendMessage` useMemo that checks
  current state of `participantInboxRelays` in real-time
- **Impact**: Send button correctly enables/disables as relay lists load

### 3. Cleaner UI (ChatViewer.tsx)
- Removed large yellow warning banners about view-only mode
- Removed "Sending disabled - waiting for relay lists" text in composer
- Send button now simply disables when relay lists are missing
- **Impact**: Less intrusive, cleaner messaging interface

## Additional Improvements

### Cache Readiness Check (gift-wrap.ts)
- Added `waitForCacheReady()` to prevent race condition on page reload
- Waits up to 1s for encrypted content cache to be accessible before
  processing conversations
- **Impact**: Fixes "inbox appears empty" issue on page reload

### Simplified Event Caching (nip-17-adapter.ts)
- Removed redundant `syntheticEventCache` WeakMap
- Uses eventStore as single source of truth with O(1) lookup
- **Impact**: Reduced complexity, eventStore already handles deduplication

### Removed Self-Chat Workaround (nip-17-adapter.ts)
- Deleted 70-line custom gift wrap construction for self-chat
- Applesauce's `SendWrappedMessage` works fine for self-chat
- **Impact**: Cleaner code, better maintainability

### Debug Logging System (dm-debug.ts - NEW)
- Added dedicated DM debug logging utilities
- Enable with: `localStorage.setItem('grimoire:debug:dms', 'true')`
- Levels: dmDebug (verbose), dmInfo (important), dmWarn (warnings)
- **Impact**: Better troubleshooting for NIP-17 issues

### Comprehensive Documentation (docs/gift-wrap-architecture.md - NEW)
- 450+ line architecture document
- Component diagrams, data flow, cache strategy
- Security considerations, performance optimizations
- Debugging guide and testing strategy
- **Impact**: Complete reference for gift wrap implementation

## Testing

-  All tests pass (864 tests)
-  Build succeeds with no errors
-  Lint passes (only pre-existing warnings)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 16:44:53 +01:00

57 lines
1.7 KiB
TypeScript

/**
* Debug utility for DM-related services (gift-wrap, NIP-17)
* Enable verbose logging with: localStorage.setItem('grimoire:debug:dms', 'true')
*/
const DM_DEBUG_KEY = "grimoire:debug:dms";
/** Check if DM debug logging is enabled */
function isDMDebugEnabled(): boolean {
try {
return localStorage.getItem(DM_DEBUG_KEY) === "true";
} catch {
return false;
}
}
/** Enable DM debug logging */
export function enableDMDebug() {
localStorage.setItem(DM_DEBUG_KEY, "true");
console.log("[DM Debug] Verbose logging enabled");
}
/** Disable DM debug logging */
export function disableDMDebug() {
localStorage.removeItem(DM_DEBUG_KEY);
console.log("[DM Debug] Verbose logging disabled");
}
/** Log debug message (only if debug enabled) */
export function dmDebug(component: string, message: string, ...args: any[]) {
if (isDMDebugEnabled()) {
console.log(`[${component}] ${message}`, ...args);
}
}
/** Log info message (always shown, but only for important info) */
export function dmInfo(component: string, message: string, ...args: any[]) {
console.info(`[${component}] ${message}`, ...args);
}
/** Log warning message (always shown) */
export function dmWarn(component: string, message: string, ...args: any[]) {
console.warn(`[${component}] ⚠️ ${message}`, ...args);
}
/** Log error message (always shown) */
export function dmError(component: string, message: string, ...args: any[]) {
console.error(`[${component}] ❌ ${message}`, ...args);
}
/** Log success message (only if debug enabled) */
export function dmSuccess(component: string, message: string, ...args: any[]) {
if (isDMDebugEnabled()) {
console.log(`[${component}] ✅ ${message}`, ...args);
}
}