mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-08-03 11:00:24 +02:00
feat: Show decryption errors in inbox UI and remove debug logs
- Added error display section in InboxViewer showing failed gift wraps with error messages - Query and display up to 10 failed gift wraps with their failureReason - Show total error count in red card - Removed all debug console.log statements from gift-wrap.ts and gift-wrap-loader.ts - Kept console.error and console.warn for actual error reporting - Cleaner logs for production use This helps users diagnose decryption issues by showing actual error messages from the applesauce unlockGiftWrap helper.
This commit is contained in:
@@ -68,15 +68,20 @@ export function InboxViewer() {
|
||||
.count();
|
||||
}, [activeAccount?.pubkey]);
|
||||
|
||||
// Get failed gift wraps with error messages
|
||||
const failedGiftWraps = useLiveQuery(async () => {
|
||||
if (!activeAccount?.pubkey) return [];
|
||||
return db.giftWraps
|
||||
.where("[recipientPubkey+status]")
|
||||
.equals([activeAccount.pubkey, "failed"])
|
||||
.limit(10)
|
||||
.toArray();
|
||||
}, [activeAccount?.pubkey]);
|
||||
|
||||
// Get conversations (from decrypted rumors)
|
||||
const conversations = useLiveQuery(async () => {
|
||||
if (!activeAccount?.pubkey) return [];
|
||||
const convos = await getConversations(activeAccount.pubkey);
|
||||
console.log(
|
||||
`[InboxViewer] Found ${convos.length} conversations for ${activeAccount.pubkey.slice(0, 8)}`,
|
||||
convos,
|
||||
);
|
||||
return convos;
|
||||
return await getConversations(activeAccount.pubkey);
|
||||
}, [activeAccount?.pubkey]);
|
||||
|
||||
// Get loader state for relay info
|
||||
@@ -443,6 +448,44 @@ export function InboxViewer() {
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Decryption Errors */}
|
||||
{privateMessagesEnabled &&
|
||||
failedGiftWraps &&
|
||||
failedGiftWraps.length > 0 && (
|
||||
<Card>
|
||||
<CardHeader className="p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<XCircle className="h-4 w-4 text-red-600" />
|
||||
<CardTitle className="text-base text-red-600">
|
||||
Decryption Errors ({failedCount ?? 0})
|
||||
</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="p-4 pt-0">
|
||||
<div className="space-y-2">
|
||||
{failedGiftWraps.map((gw) => (
|
||||
<div
|
||||
key={gw.id}
|
||||
className="p-2 rounded bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900"
|
||||
>
|
||||
<div className="text-xs font-mono text-red-900 dark:text-red-300 mb-1">
|
||||
{gw.id.slice(0, 16)}...
|
||||
</div>
|
||||
<div className="text-sm text-red-700 dark:text-red-400">
|
||||
{gw.failureReason || "Unknown error"}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{(failedCount ?? 0) > 10 && (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Showing first 10 of {failedCount} errors
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Help Text */}
|
||||
{!privateMessagesEnabled && (
|
||||
<div className="text-sm text-muted-foreground space-y-2">
|
||||
|
||||
@@ -92,16 +92,6 @@ class GiftWrapLoader {
|
||||
recipientPubkey,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`[GiftWrapLoader] Enabled for ${recipientPubkey.slice(0, 8)} (autoDecrypt: ${autoDecrypt})`,
|
||||
);
|
||||
console.log(
|
||||
`[GiftWrapLoader] Signer type: ${signer.constructor?.name || "unknown"}`,
|
||||
);
|
||||
console.log(
|
||||
`[GiftWrapLoader] Signer has nip44: ${!!signer.nip44}, has decrypt: ${!!signer.nip44?.decrypt}`,
|
||||
);
|
||||
|
||||
// Start loading
|
||||
await this.sync();
|
||||
}
|
||||
@@ -124,8 +114,6 @@ class GiftWrapLoader {
|
||||
loading: false,
|
||||
recipientPubkey: undefined,
|
||||
});
|
||||
|
||||
console.log("[GiftWrapLoader] Disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,12 +123,10 @@ class GiftWrapLoader {
|
||||
const state = this.state$.value;
|
||||
|
||||
if (!state.enabled || !state.recipientPubkey || !this.currentSigner) {
|
||||
console.warn("[GiftWrapLoader] Cannot sync: not enabled or no signer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.loading) {
|
||||
console.log("[GiftWrapLoader] Already syncing, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -158,11 +144,6 @@ class GiftWrapLoader {
|
||||
// so this might not work well
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[GiftWrapLoader] Syncing from ${inboxRelays.length} inbox relays:`,
|
||||
inboxRelays,
|
||||
);
|
||||
|
||||
// Update state with relays being used
|
||||
this.state$.next({
|
||||
...this.state$.value,
|
||||
@@ -177,10 +158,6 @@ class GiftWrapLoader {
|
||||
// since: state.lastSync ? Math.floor(state.lastSync / 1000) : undefined,
|
||||
};
|
||||
|
||||
console.log(
|
||||
`[GiftWrapLoader] Subscribing to kind 1059 events on ${inboxRelays.length} relays`,
|
||||
);
|
||||
|
||||
// Use pool.subscription to connect to relays and fetch events
|
||||
const obs = pool.subscription(inboxRelays, [filter], { eventStore });
|
||||
|
||||
@@ -192,15 +169,9 @@ class GiftWrapLoader {
|
||||
if (typeof response === "string") {
|
||||
// EOSE received from a relay
|
||||
eoseCount++;
|
||||
console.log(
|
||||
`[GiftWrapLoader] EOSE ${eoseCount}/${inboxRelays.length} from relay`,
|
||||
);
|
||||
|
||||
// When we've received EOSE from all relays, we're done loading
|
||||
if (eoseCount >= inboxRelays.length) {
|
||||
console.log(
|
||||
`[GiftWrapLoader] All relays sent EOSE, received ${eventCount} gift wraps`,
|
||||
);
|
||||
this.state$.next({
|
||||
...this.state$.value,
|
||||
loading: false,
|
||||
@@ -214,9 +185,6 @@ class GiftWrapLoader {
|
||||
// Event received from relay
|
||||
const event = response as NostrEvent;
|
||||
eventCount++;
|
||||
console.log(
|
||||
`[GiftWrapLoader] Received gift wrap ${event.id.slice(0, 8)} (${eventCount} total)`,
|
||||
);
|
||||
|
||||
// Process the gift wrap immediately
|
||||
void this.handleGiftWrap(event);
|
||||
@@ -231,7 +199,6 @@ class GiftWrapLoader {
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
console.log("[GiftWrapLoader] Subscription completed");
|
||||
this.state$.next({
|
||||
...this.state$.value,
|
||||
loading: false,
|
||||
@@ -266,9 +233,6 @@ class GiftWrapLoader {
|
||||
// If auto-decrypt is enabled, process immediately
|
||||
if (state.autoDecrypt) {
|
||||
await processGiftWrap(event, state.recipientPubkey, this.currentSigner);
|
||||
console.log(
|
||||
`[GiftWrapLoader] Auto-decrypted gift wrap ${event.id.slice(0, 8)}`,
|
||||
);
|
||||
} else {
|
||||
// Otherwise, just store the envelope as pending
|
||||
await db.giftWraps.put({
|
||||
@@ -278,9 +242,6 @@ class GiftWrapLoader {
|
||||
status: "pending",
|
||||
receivedAt: Date.now(),
|
||||
});
|
||||
console.log(
|
||||
`[GiftWrapLoader] Stored gift wrap ${event.id.slice(0, 8)} for manual decryption`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
@@ -309,10 +270,6 @@ class GiftWrapLoader {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[GiftWrapLoader] Auto-processing ${pending.length} pending gift wraps`,
|
||||
);
|
||||
|
||||
for (const envelope of pending) {
|
||||
try {
|
||||
await processGiftWrap(
|
||||
@@ -341,7 +298,6 @@ class GiftWrapLoader {
|
||||
const state = this.state$.value;
|
||||
|
||||
if (!state.recipientPubkey || !this.currentSigner) {
|
||||
console.warn("[GiftWrapLoader] Cannot decrypt: not enabled or no signer");
|
||||
return { success: 0, failed: 0, total: 0 };
|
||||
}
|
||||
|
||||
@@ -351,10 +307,6 @@ class GiftWrapLoader {
|
||||
return { success: 0, failed: 0, total: 0 };
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[GiftWrapLoader] Manually decrypting ${pending.length} pending gift wraps`,
|
||||
);
|
||||
|
||||
let success = 0;
|
||||
let failed = 0;
|
||||
|
||||
@@ -397,9 +349,6 @@ class GiftWrapLoader {
|
||||
const dmRelays = await dmRelayListCache.get(pubkey);
|
||||
|
||||
if (dmRelays && dmRelays.length > 0) {
|
||||
console.log(
|
||||
`[GiftWrapLoader] Using ${dmRelays.length} DM relays from kind 10050`,
|
||||
);
|
||||
return dmRelays;
|
||||
}
|
||||
|
||||
@@ -407,9 +356,6 @@ class GiftWrapLoader {
|
||||
const inboxRelays = await relayListCache.getInboxRelays(pubkey);
|
||||
|
||||
if (inboxRelays && inboxRelays.length > 0) {
|
||||
console.log(
|
||||
`[GiftWrapLoader] Fallback to ${inboxRelays.length} inbox relays from kind 10002`,
|
||||
);
|
||||
return inboxRelays;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,10 +52,6 @@ export async function unwrapAndUnseal(
|
||||
giftWrap: NostrEvent,
|
||||
signer: ISigner,
|
||||
): Promise<{ seal: NostrEvent; rumor: NostrEvent }> {
|
||||
console.log(
|
||||
`[GiftWrap] Using applesauce unlockGiftWrap for ${giftWrap.id.slice(0, 8)}`,
|
||||
);
|
||||
|
||||
// Use applesauce helper to unlock the gift wrap
|
||||
const rumor = await unlockGiftWrap(giftWrap, signer);
|
||||
|
||||
@@ -69,10 +65,6 @@ export async function unwrapAndUnseal(
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[GiftWrap] Successfully unlocked - sender: ${seal.pubkey.slice(0, 8)}, rumor kind: ${rumor.kind}`,
|
||||
);
|
||||
|
||||
// Convert rumor to NostrEvent (rumor has id but no sig)
|
||||
const rumorEvent = rumor as NostrEvent;
|
||||
|
||||
@@ -92,28 +84,15 @@ export async function processGiftWrap(
|
||||
recipientPubkey: string,
|
||||
signer: ISigner,
|
||||
): Promise<DecryptedRumor | null> {
|
||||
console.log(
|
||||
`[GiftWrap] Processing gift wrap ${giftWrap.id.slice(0, 8)} for recipient ${recipientPubkey.slice(0, 8)}`,
|
||||
);
|
||||
console.log(
|
||||
`[GiftWrap] Signer has nip44: ${!!signer.nip44}, has decrypt: ${!!signer.nip44?.decrypt}`,
|
||||
);
|
||||
|
||||
// Check if already processed
|
||||
const existing = await db.giftWraps.get(giftWrap.id);
|
||||
if (existing) {
|
||||
// Already processed
|
||||
if (existing.status === "decrypted") {
|
||||
console.log(
|
||||
`[GiftWrap] Already decrypted ${giftWrap.id.slice(0, 8)}, skipping`,
|
||||
);
|
||||
return (await db.decryptedRumors.get(giftWrap.id)) || null;
|
||||
}
|
||||
if (existing.status === "failed") {
|
||||
// Already tried and failed, don't retry
|
||||
console.log(
|
||||
`[GiftWrap] Previously failed ${giftWrap.id.slice(0, 8)}, skipping`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +141,6 @@ export async function processGiftWrap(
|
||||
error instanceof Error ? error.message : String(error);
|
||||
await db.giftWraps.put(envelope);
|
||||
|
||||
console.error(`[GiftWrap] Failed to process ${giftWrap.id}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -195,10 +173,6 @@ async function updateConversationMetadata(
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
await db.conversations.put(conversation);
|
||||
console.log(
|
||||
`[GiftWrap] Created new conversation ${conversationId}`,
|
||||
conversation,
|
||||
);
|
||||
} else {
|
||||
// Update existing conversation if this is newer
|
||||
if (rumor.rumorCreatedAt > existing.lastMessageCreatedAt) {
|
||||
|
||||
Reference in New Issue
Block a user