import type { VerifiedEvent } from "nostr-tools" import { Session } from "./Session" import type { Rumor, SessionState } from "./types" import { deepCopyState, deserializeSessionState } from "./utils" export interface SessionPreviewCandidate { state: SessionState | string chatId?: string context?: TContext } export interface SessionEventPreview { outerEvent: VerifiedEvent rumor: Rumor candidate: SessionPreviewCandidate candidateIndex: number chatId?: string context?: TContext } function copyCandidateState(candidate: SessionPreviewCandidate): SessionState { return typeof candidate.state === "string" ? deserializeSessionState(candidate.state) : deepCopyState(candidate.state) } export function decryptSessionEventPreview( outerEvent: VerifiedEvent, candidates: Iterable>, ): SessionEventPreview | null { let candidateIndex = 0 for (const candidate of candidates) { try { const session = new Session(copyCandidateState(candidate)) const rumor = session.receiveEvent(outerEvent) if (rumor) { return { outerEvent, rumor, candidate, candidateIndex, chatId: candidate.chatId, context: candidate.context, } } } catch { // Keep scanning; service workers often have stale inactive sessions. } candidateIndex += 1 } return null }