mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-07-25 14:27:50 +02:00
fix: Strip Symbol properties before storing events in Dexie
CRITICAL FIX for "can't serialize event with wrong or missing properties" error. The Problem: - Applesauce attaches Symbol properties to events for caching (SealSymbol, RumorSymbol, etc.) - These Symbols cannot be serialized by Dexie/IndexedDB - Attempting to store events with Symbols causes serialization errors The Solution: - Created serializableEvent() helper that creates plain object copies - Strips all Symbols and non-enumerable properties - Handles rumors (unsigned events without sig field) by using empty string - Applied to all event storage points: * Gift wrap events in envelopes * Seal events in DecryptedRumor * Rumor events in DecryptedRumor * Pending gift wraps stored by loader This ensures Dexie only receives plain, serializable objects while applesauce can still use its Symbol-based caching in memory.
This commit is contained in:
@@ -22,7 +22,11 @@ import pool from "./relay-pool";
|
||||
import eventStore from "./event-store";
|
||||
import { relayListCache } from "./relay-list-cache";
|
||||
import { dmRelayListCache } from "./dm-relay-list-cache";
|
||||
import { processGiftWrap, getPendingGiftWraps } from "./gift-wrap";
|
||||
import {
|
||||
processGiftWrap,
|
||||
getPendingGiftWraps,
|
||||
serializableEvent,
|
||||
} from "./gift-wrap";
|
||||
import db from "./db";
|
||||
|
||||
/**
|
||||
@@ -235,10 +239,11 @@ class GiftWrapLoader {
|
||||
await processGiftWrap(event, state.recipientPubkey, this.currentSigner);
|
||||
} else {
|
||||
// Otherwise, just store the envelope as pending
|
||||
// Use serializableEvent to strip Symbol properties before storing
|
||||
await db.giftWraps.put({
|
||||
id: event.id,
|
||||
recipientPubkey: state.recipientPubkey,
|
||||
event,
|
||||
event: serializableEvent(event),
|
||||
status: "pending",
|
||||
receivedAt: Date.now(),
|
||||
});
|
||||
|
||||
@@ -42,6 +42,26 @@ export class GiftWrapError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plain serializable copy of an event object
|
||||
* Strips Symbols and non-enumerable properties added by applesauce
|
||||
*
|
||||
* CRITICAL: Applesauce attaches Symbol properties to event objects for caching.
|
||||
* These Symbols cannot be serialized by Dexie (IndexedDB). Always use this function
|
||||
* before storing events in the database.
|
||||
*/
|
||||
export function serializableEvent(event: any): NostrEvent {
|
||||
return {
|
||||
id: event.id,
|
||||
pubkey: event.pubkey,
|
||||
created_at: event.created_at,
|
||||
kind: event.kind,
|
||||
tags: event.tags,
|
||||
content: event.content,
|
||||
sig: event.sig || "", // Rumors don't have sig, use empty string
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps a gift wrap and unseals to extract the rumor (full process)
|
||||
* Uses applesauce-common unlockGiftWrap helper
|
||||
@@ -110,11 +130,11 @@ export async function processGiftWrap(
|
||||
// Applesauce caches seal/rumor on the event object via symbols
|
||||
eventStore.add(giftWrap);
|
||||
|
||||
// Store gift wrap envelope
|
||||
// Store gift wrap envelope (use plain object to avoid Symbol serialization issues)
|
||||
const envelope: GiftWrapEnvelope = {
|
||||
id: giftWrap.id,
|
||||
recipientPubkey,
|
||||
event: giftWrap,
|
||||
event: serializableEvent(giftWrap),
|
||||
status: "pending",
|
||||
receivedAt: existing?.receivedAt || Date.now(),
|
||||
processedAt: Date.now(),
|
||||
@@ -124,13 +144,13 @@ export async function processGiftWrap(
|
||||
// Unwrap and unseal
|
||||
const { seal, rumor } = await unwrapAndUnseal(giftWrap, signer);
|
||||
|
||||
// Store decrypted rumor
|
||||
// Store decrypted rumor (use plain objects to avoid Symbol serialization issues)
|
||||
const decryptedRumor: DecryptedRumor = {
|
||||
giftWrapId: giftWrap.id,
|
||||
recipientPubkey,
|
||||
senderPubkey: seal.pubkey,
|
||||
seal,
|
||||
rumor,
|
||||
seal: serializableEvent(seal),
|
||||
rumor: serializableEvent(rumor),
|
||||
rumorCreatedAt: rumor.created_at,
|
||||
rumorKind: rumor.kind,
|
||||
decryptedAt: Date.now(),
|
||||
|
||||
Reference in New Issue
Block a user