import { getAlbyService } from './alby' import { calculateArticleSplit, PLATFORM_COMMISSIONS } from './platformCommissions' import { buildTags } from './nostrTagSystem' import type { AlbyInvoice } from '@/types/alby' import type { ArticleDraft } from './articlePublisher' /** * Create Lightning invoice for article with automatic commission split * The invoice is created for the full amount (800 sats) which includes: * - 700 sats for the author * - 100 sats commission for the platform * * The commission is automatically tracked and the split is enforced. * Requires Alby/WebLN to be available and enabled */ export async function createArticleInvoice(draft: ArticleDraft): Promise { // Verify amount matches expected commission structure if (draft.zapAmount !== PLATFORM_COMMISSIONS.article.total) { throw new Error( `Invalid article payment amount: ${draft.zapAmount} sats. Expected ${PLATFORM_COMMISSIONS.article.total} sats (700 to author, 100 commission)` ) } const split = calculateArticleSplit() // Get author's Lightning address from their profile or use platform address as fallback // For now, we'll create the invoice through the platform's wallet // The platform will forward the author's portion after payment const alby = getAlbyService() await alby.enable() const invoice = await alby.createInvoice({ amount: split.total, description: `Article: ${draft.title} (${split.author} sats author, ${split.platform} sats commission)`, expiry: 86400, // 24 hours }) return invoice } /** * Create preview event with invoice tags * If encryptedContent is provided, it will be used instead of preview */ export function createPreviewEvent( draft: ArticleDraft, invoice: AlbyInvoice, authorPresentationId?: string, extraTags: string[][] = [], encryptedContent?: string, encryptedKey?: string ): { kind: 1 created_at: number tags: string[][] content: string } { const tags = buildPreviewTags(draft, invoice, authorPresentationId, extraTags, encryptedKey) return { kind: 1 as const, created_at: Math.floor(Date.now() / 1000), tags, content: encryptedContent ?? draft.preview, } } function buildPreviewTags( draft: ArticleDraft, invoice: AlbyInvoice, _authorPresentationId?: string, extraTags: string[][] = [], encryptedKey?: string ): string[][] { // Map category to new system const category = draft.category === 'science-fiction' ? 'sciencefiction' : draft.category === 'scientific-research' ? 'research' : 'sciencefiction' // Build tags using new system const newTags = buildTags({ type: 'publication', category, id: '', // Will be set to event.id after publication paywall: true, // Publications are paid title: draft.title, preview: draft.preview, zapAmount: draft.zapAmount, invoice: invoice.invoice, paymentHash: invoice.paymentHash, ...(draft.seriesId ? { seriesId: draft.seriesId } : {}), ...(draft.bannerUrl ? { bannerUrl: draft.bannerUrl } : {}), ...(encryptedKey ? { encryptedKey } : {}), }) // Add any extra tags (for backward compatibility) if (extraTags.length > 0) { newTags.push(...extraTags) } return newTags }