126 lines
3.3 KiB
TypeScript
126 lines
3.3 KiB
TypeScript
import { nostrService } from './nostr'
|
|
import { PLATFORM_COMMISSIONS } from './platformCommissions'
|
|
import type { Event } from 'nostr-tools'
|
|
|
|
export async function fetchOriginalReviewEvent(reviewId: string): Promise<Event | null> {
|
|
const pool = nostrService.getPool()
|
|
if (!pool) {
|
|
throw new Error('Pool not initialized')
|
|
}
|
|
|
|
const poolWithSub = pool as import('@/types/nostr-tools-extended').SimplePoolWithSub
|
|
const { getPrimaryRelaySync } = await import('./config')
|
|
const relayUrl = getPrimaryRelaySync()
|
|
const filters = [
|
|
{
|
|
kinds: [1],
|
|
ids: [reviewId],
|
|
limit: 1,
|
|
},
|
|
]
|
|
|
|
return new Promise<Event | null>((resolve) => {
|
|
let resolved = false
|
|
const sub = poolWithSub.sub([relayUrl], filters)
|
|
|
|
const finalize = (value: Event | null) => {
|
|
if (resolved) {
|
|
return
|
|
}
|
|
resolved = true
|
|
sub.unsub()
|
|
resolve(value)
|
|
}
|
|
|
|
sub.on('event', (event: Event) => {
|
|
finalize(event)
|
|
})
|
|
|
|
sub.on('eose', () => finalize(null))
|
|
setTimeout(() => finalize(null), 5000)
|
|
})
|
|
}
|
|
|
|
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.log('Review already marked as rewarded', {
|
|
reviewId,
|
|
timestamp: new Date().toISOString(),
|
|
})
|
|
}
|
|
return alreadyRewarded
|
|
}
|
|
|
|
export async function publishRewardEvent(
|
|
updatedEvent: {
|
|
kind: number
|
|
created_at: number
|
|
tags: string[][]
|
|
content: string
|
|
},
|
|
reviewId: string
|
|
): Promise<void> {
|
|
const publishedEvent = await nostrService.publishEvent(updatedEvent)
|
|
if (publishedEvent) {
|
|
console.log('Review updated with reward tag', {
|
|
reviewId,
|
|
updatedEventId: publishedEvent.id,
|
|
timestamp: new Date().toISOString(),
|
|
})
|
|
} else {
|
|
console.error('Failed to publish updated review event', {
|
|
reviewId,
|
|
timestamp: new Date().toISOString(),
|
|
})
|
|
}
|
|
}
|
|
|
|
export async function updateReviewWithReward(reviewId: string, authorPrivateKey: string): Promise<void> {
|
|
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(),
|
|
})
|
|
}
|
|
}
|