import type { Article } from '@/types/nostr' import { nostrService } from '../nostr' import { getPublishRelays } from '../relaySelection' import { ensureKeys } from './shared' export async function deleteArticleEvent(articleId: string, authorPubkey: string, authorPrivateKey?: string): Promise { ensureKeys(authorPubkey, authorPrivateKey) const originalEvent = await getOriginalPublicationEventOrThrow(articleId) assertAuthorOwnsEvent({ eventPubkey: originalEvent.pubkey, authorPubkey }) const deleteEventTemplate = await buildDeleteEventTemplateOrThrow({ originalEvent, authorPubkey }) const originalParsed = await parseOriginalArticleOrThrow(originalEvent) const deletePayload = await buildDeletedArticlePayload({ originalParsed, deleteEventTemplate }) const event = await finalizeEventTemplate({ template: deleteEventTemplate, authorPrivateKey }) const relays = await getPublishRelays() await publishDeletion({ event, relays, payload: deletePayload }) } async function getOriginalPublicationEventOrThrow(articleId: string): Promise { const { objectCache } = await import('../objectCache') const originalEvent = await objectCache.getEventById('publication', articleId) if (!originalEvent) { throw new Error('Article not found in cache') } return originalEvent } function assertAuthorOwnsEvent(params: { eventPubkey: string; authorPubkey: string }): void { if (params.eventPubkey !== params.authorPubkey) { throw new Error('Only the author can delete this article') } } async function buildDeleteEventTemplateOrThrow(params: { originalEvent: import('nostr-tools').Event; authorPubkey: string }): Promise { const { buildDeleteEvent } = await import('../objectModification') const template = await buildDeleteEvent(params.originalEvent, params.authorPubkey) if (!template) { throw new Error('Failed to build delete event') } return template } async function parseOriginalArticleOrThrow(originalEvent: import('nostr-tools').Event): Promise
{ const { parseArticleFromEvent } = await import('../nostrEventParsing') const parsed = await parseArticleFromEvent(originalEvent) if (!parsed) { throw new Error('Failed to parse original article') } return parsed } async function buildDeletedArticlePayload(params: { originalParsed: Article; deleteEventTemplate: import('nostr-tools').EventTemplate }): Promise<{ hash: string; index: number; version: number; parsed: Article }> { const { extractTagsFromEvent } = await import('../nostrTagSystem') const tags = extractTagsFromEvent(params.deleteEventTemplate) const version = tags.version ?? params.originalParsed.version + 1 const index = params.originalParsed.index ?? 0 const parsed: Article = { ...params.originalParsed, version } return { hash: params.originalParsed.hash, index, version, parsed } } async function finalizeEventTemplate(params: { template: import('nostr-tools').EventTemplate; authorPrivateKey: string | undefined }): Promise { const privateKey = params.authorPrivateKey ?? nostrService.getPrivateKey() if (!privateKey) { throw new Error('Private key required for signing') } const { writeOrchestrator } = await import('../writeOrchestrator') writeOrchestrator.setPrivateKey(privateKey) const { finalizeEvent } = await import('nostr-tools') const { hexToBytes } = await import('nostr-tools/utils') return finalizeEvent(params.template, hexToBytes(privateKey)) } async function publishDeletion(params: { event: import('nostr-tools').Event relays: string[] payload: { hash: string; index: number; version: number; parsed: Article } }): Promise { const { writeOrchestrator } = await import('../writeOrchestrator') const result = await writeOrchestrator.writeAndPublish( { objectType: 'publication', hash: params.payload.hash, event: params.event, parsed: params.payload.parsed, version: params.payload.version, hidden: true, index: params.payload.index }, params.relays ) if (!result.success) { throw new Error('Failed to publish delete event') } }