import { nostrService } from './nostr' import { PLATFORM_COMMISSIONS } from './platformCommissions' import type { Event } from 'nostr-tools' import { objectCache } from './objectCache' export async function fetchOriginalReviewEvent(reviewId: string): Promise { // Read only from IndexedDB cache const parsed = await objectCache.getById('review', reviewId) if (parsed) { // Get the event from cache const event = await objectCache.getEventById('review', reviewId) if (event) { return event } } // Not found in cache - return null (no network request) return null } export function buildRewardEvent(originalEvent: Event, reviewId: string): { kind: number created_at: number tags: string[][] content: string } { return { kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [ ...originalEvent.tags.filter((tag) => tag[0] !== 'rewarded' && tag[0] !== 'reward_amount'), ['e', reviewId], ['rewarded', 'true'], ['reward_amount', PLATFORM_COMMISSIONS.review.total.toString()], ], content: originalEvent.content, } } export function checkIfAlreadyRewarded(originalEvent: Event, reviewId: string): boolean { const alreadyRewarded = originalEvent.tags.some((tag) => tag[0] === 'rewarded' && tag[1] === 'true') if (alreadyRewarded) { console.warn('Review already marked as rewarded', { reviewId, timestamp: new Date().toISOString(), }) } return alreadyRewarded } export async function publishRewardEvent( updatedEventTemplate: { kind: number created_at: number tags: string[][] content: string }, reviewId: string ): Promise { try { // Get original review to extract hash and parsed data const originalEvent = await fetchOriginalReviewEvent(reviewId) if (!originalEvent) { throw new Error('Original review event not found in cache') } const { parseReviewFromEvent } = await import('./nostrEventParsing') const originalParsed = await parseReviewFromEvent(originalEvent) if (!originalParsed) { throw new Error('Failed to parse original review') } // Increment version for update const newVersion = (originalParsed.version ?? 0) + 1 const {hash} = originalParsed const index = originalParsed.index ?? 0 // Build updated parsed Review object const updatedParsed = { ...originalParsed, version: newVersion, rewarded: true, rewardAmount: PLATFORM_COMMISSIONS.review.total, } // Set private key in orchestrator const privateKey = nostrService.getPrivateKey() if (!privateKey) { throw new Error('Private key required for signing') } const { writeOrchestrator } = await import('./writeOrchestrator') writeOrchestrator.setPrivateKey(privateKey) // Finalize event const { finalizeEvent } = await import('nostr-tools') const { hexToBytes } = await import('nostr-tools/utils') const secretKey = hexToBytes(privateKey) const event = finalizeEvent(updatedEventTemplate, secretKey) // Get active relays const { relaySessionManager } = await import('./relaySessionManager') const activeRelays = await relaySessionManager.getActiveRelays() const { getPrimaryRelay } = await import('./config') const relays = activeRelays.length > 0 ? activeRelays : [await getPrimaryRelay()] // Publish via writeOrchestrator (parallel network + local write) const result = await writeOrchestrator.writeAndPublish( { objectType: 'review', hash, event, parsed: updatedParsed, version: newVersion, hidden: false, index, }, relays ) if (result.success) { console.warn('Review updated with reward tag', { reviewId, updatedEventId: event.id, timestamp: new Date().toISOString(), }) } else { console.error('Failed to publish updated review event', { reviewId, timestamp: new Date().toISOString(), }) } } catch (error) { console.error('Error publishing reward event', { reviewId, error: error instanceof Error ? error.message : 'Unknown error', timestamp: new Date().toISOString(), }) } } export async function updateReviewWithReward(reviewId: string, authorPrivateKey: string): Promise { try { const originalEvent = await fetchOriginalReviewEvent(reviewId) if (!originalEvent) { console.error('Original review event not found', { reviewId, timestamp: new Date().toISOString(), }) return } if (checkIfAlreadyRewarded(originalEvent, reviewId)) { return } nostrService.setPrivateKey(authorPrivateKey) nostrService.setPublicKey(originalEvent.pubkey) const updatedEvent = buildRewardEvent(originalEvent, reviewId) await publishRewardEvent(updatedEvent, reviewId) } catch (error) { console.error('Error updating review with reward', { reviewId, error: error instanceof Error ? error.message : 'Unknown error', timestamp: new Date().toISOString(), }) } }