// Platform configuration is imported where needed // This file only exports commission-related constants and functions /** * Platform commission configuration * Defines commission rates and split amounts for all payment types */ export const PLATFORM_COMMISSIONS = { /** * Article payment commission * Total: 800 sats * Author: 700 sats * Platform: 100 sats */ article: { total: 800, author: 700, platform: 100, }, /** * Review reward commission * Total: 70 sats * Reviewer: 49 sats * Platform: 21 sats */ review: { total: 70, reviewer: 49, platform: 21, }, /** * Sponsoring commission * Total: 0.046 BTC (4,600,000 sats) * Author: 0.042 BTC (4,200,000 sats) * Platform: 0.004 BTC (400,000 sats) */ sponsoring: { total: 0.046, author: 0.042, platform: 0.004, totalSats: 4_600_000, authorSats: 4_200_000, platformSats: 400_000, }, } as const /** * Platform Lightning address/node for receiving commissions * This should be configured with the platform's Lightning node */ export const PLATFORM_LIGHTNING_ADDRESS = process.env.NEXT_PUBLIC_PLATFORM_LIGHTNING_ADDRESS || '' /** * Calculate commission split for article payment */ export function calculateArticleSplit(totalAmount: number = PLATFORM_COMMISSIONS.article.total): { author: number platform: number total: number } { if (totalAmount !== PLATFORM_COMMISSIONS.article.total) { throw new Error(`Invalid article payment amount: ${totalAmount}. Expected ${PLATFORM_COMMISSIONS.article.total} sats`) } return { author: PLATFORM_COMMISSIONS.article.author, platform: PLATFORM_COMMISSIONS.article.platform, total: PLATFORM_COMMISSIONS.article.total, } } /** * Calculate commission split for review reward */ export function calculateReviewSplit(totalAmount: number = PLATFORM_COMMISSIONS.review.total): { reviewer: number platform: number total: number } { if (totalAmount !== PLATFORM_COMMISSIONS.review.total) { throw new Error(`Invalid review reward amount: ${totalAmount}. Expected ${PLATFORM_COMMISSIONS.review.total} sats`) } return { reviewer: PLATFORM_COMMISSIONS.review.reviewer, platform: PLATFORM_COMMISSIONS.review.platform, total: PLATFORM_COMMISSIONS.review.total, } } /** * Calculate commission split for sponsoring */ export function calculateSponsoringSplit(totalAmount: number = PLATFORM_COMMISSIONS.sponsoring.total): { author: number platform: number total: number authorSats: number platformSats: number totalSats: number } { if (totalAmount !== PLATFORM_COMMISSIONS.sponsoring.total) { throw new Error( `Invalid sponsoring amount: ${totalAmount} BTC. Expected ${PLATFORM_COMMISSIONS.sponsoring.total} BTC` ) } return { author: PLATFORM_COMMISSIONS.sponsoring.author, platform: PLATFORM_COMMISSIONS.sponsoring.platform, total: PLATFORM_COMMISSIONS.sponsoring.total, authorSats: PLATFORM_COMMISSIONS.sponsoring.authorSats, platformSats: PLATFORM_COMMISSIONS.sponsoring.platformSats, totalSats: PLATFORM_COMMISSIONS.sponsoring.totalSats, } } /** * Verify that a payment amount matches expected commission split */ export function verifyPaymentSplit( type: 'article' | 'review' | 'sponsoring', totalAmount: number, authorAmount?: number, platformAmount?: number ): boolean { switch (type) { case 'article': const articleSplit = calculateArticleSplit(totalAmount) return ( articleSplit.author === (authorAmount ?? 0) && articleSplit.platform === (platformAmount ?? 0) ) case 'review': const reviewSplit = calculateReviewSplit(totalAmount) return ( reviewSplit.reviewer === (authorAmount ?? 0) && reviewSplit.platform === (platformAmount ?? 0) ) case 'sponsoring': const sponsoringSplit = calculateSponsoringSplit(totalAmount) return ( sponsoringSplit.authorSats === (authorAmount ?? 0) && sponsoringSplit.platformSats === (platformAmount ?? 0) ) default: return false } }