import type { Event } from 'nostr-tools' import type { ReviewTip } from '@/types/nostr' import { buildTags } from '../nostrTagSystem' import { PLATFORM_SERVICE } from '../platformConfig' import { generateReviewTipHashId } from '../hashIdGenerator' import { buildObjectId } from '../urlGenerator' import { buildPaymentNoteTemplate, mapPaymentCategory, type PaymentCategoryTag, publishPaymentNoteToRelays } from './shared' export async function publishReviewTipNote(params: { articleId: string reviewId: string authorPubkey: string reviewerPubkey: string payerPubkey: string amount: number paymentHash: string zapReceiptId?: string category?: 'science-fiction' | 'scientific-research' seriesId?: string text?: string payerPrivateKey: string }): Promise { const category = mapPaymentCategory(params.category) const payload = await buildReviewTipNotePayload({ ...params, category }) return publishPaymentNoteToRelays({ payerPrivateKey: params.payerPrivateKey, objectType: 'review_tip', hash: payload.hashId, eventTemplate: payload.eventTemplate, parsed: payload.parsedReviewTip, version: 0, hidden: false, index: 0, }) } async function buildReviewTipNotePayload(params: { articleId: string reviewId: string authorPubkey: string reviewerPubkey: string payerPubkey: string amount: number paymentHash: string zapReceiptId?: string category: PaymentCategoryTag seriesId?: string text?: string }): Promise<{ hashId: string; eventTemplate: import('nostr-tools').EventTemplate; parsedReviewTip: ReviewTip }> { const tipData = { payerPubkey: params.payerPubkey, articleId: params.articleId, reviewId: params.reviewId, reviewerPubkey: params.reviewerPubkey, authorPubkey: params.authorPubkey, amount: params.amount, paymentHash: params.paymentHash, ...(params.seriesId ? { seriesId: params.seriesId } : {}), ...(params.text ? { text: params.text } : {}), } const hashId = await generateReviewTipHashId(tipData) const id = buildObjectId(hashId, 0, 0) const tags = buildReviewTipNoteTags({ ...params, hashId }) tags.push(['json', JSON.stringify({ type: 'review_tip', id, hash: hashId, version: 0, index: 0, ...tipData })]) const parsedReviewTip = buildParsedReviewTip({ ...params, id, hashId }) return { hashId, eventTemplate: buildPaymentNoteTemplate(tags, buildReviewTipNoteContent(params)), parsedReviewTip } } function buildReviewTipNoteTags(params: { articleId: string reviewId: string authorPubkey: string reviewerPubkey: string payerPubkey: string amount: number paymentHash: string zapReceiptId?: string category: PaymentCategoryTag seriesId?: string text?: string hashId: string }): string[][] { return buildTags({ type: 'payment', category: params.category, id: params.hashId, service: PLATFORM_SERVICE, version: 0, hidden: false, payment: true, paymentType: 'review_tip', amount: params.amount, payerPubkey: params.payerPubkey, recipientPubkey: params.reviewerPubkey, paymentHash: params.paymentHash, articleId: params.articleId, reviewId: params.reviewId, ...(params.zapReceiptId ? { zapReceiptId: params.zapReceiptId } : {}), ...(params.seriesId ? { seriesId: params.seriesId } : {}), ...(params.text ? { text: params.text } : {}), }) } function buildReviewTipNoteContent(params: { amount: number; reviewId: string; text?: string }): string { const prefix = `Review tip confirmed: ${params.amount} sats for review ${params.reviewId}` return params.text ? `${prefix}\n\n${params.text}` : prefix } function buildParsedReviewTip(params: { articleId: string reviewId: string authorPubkey: string reviewerPubkey: string payerPubkey: string amount: number paymentHash: string seriesId?: string text?: string id: string hashId: string }): ReviewTip { return { id: params.id, hash: params.hashId, version: 0, index: 0, payerPubkey: params.payerPubkey, articleId: params.articleId, reviewId: params.reviewId, reviewerPubkey: params.reviewerPubkey, authorPubkey: params.authorPubkey, amount: params.amount, paymentHash: params.paymentHash, createdAt: Math.floor(Date.now() / 1000), ...(params.seriesId ? { seriesId: params.seriesId } : {}), ...(params.text ? { text: params.text } : {}), kindType: 'review_tip', } }