35 lines
2.2 KiB
TypeScript
Executable File
35 lines
2.2 KiB
TypeScript
Executable File
import { ADDITIONAL_MARKET_FEE } from '../../shared/market.ts';
|
|
import { formatXmr, parseAtomicXmr, XMR_ATOMIC_UNITS } from '../../shared/xmr-amount.ts';
|
|
import { allocateXmrSale } from '../../shared/xmr-pricing.ts';
|
|
|
|
/** No live payment adapter is reachable in this release. Never return a payable mock address. */
|
|
export function paymentMode(env: NodeJS.ProcessEnv = process.env): 'mock' {
|
|
const mode = env.WIKIDECK_PAYMENT_MODE ?? 'mock';
|
|
if (mode !== 'mock') throw new Error('Real payments are launch-gated. Only WIKIDECK_PAYMENT_MODE=mock is supported until production settlement review.');
|
|
return mode;
|
|
}
|
|
export function xmrString(atomic: bigint): string {
|
|
return formatXmr(atomic);
|
|
}
|
|
/** Deterministic simulation ONLY. Round gross up and both independent seller fees down. */
|
|
export function mockQuote(priceCents: number, feeBps: number, usdCentsPerXmr: number) {
|
|
const rate = BigInt(usdCentsPerXmr);
|
|
const gross = (BigInt(priceCents) * XMR_ATOMIC_UNITS + rate - 1n) / rate;
|
|
const { hosting: fee, author: additionalFee, sellerBeforeNetworkCosts } = allocateXmrSale(gross, feeBps);
|
|
return { invoice: { provider: 'mock' as const, amountXmr: xmrString(gross), address: null,
|
|
label: 'SIMULATION ONLY — no Monero payment address. Never send real XMR.' },
|
|
feeXmr: xmrString(fee), sellerNetXmr: xmrString(sellerBeforeNetworkCosts),
|
|
additionalFee: { ...ADDITIONAL_MARKET_FEE, amountXmr: xmrString(additionalFee), payout: 'not-started' as const } };
|
|
}
|
|
|
|
/** Native-XMR sandbox quote: exact listed gross, with no exchange-rate conversion. */
|
|
export function mockXmrQuote(priceAtomicXmr: string, feeBps: number) {
|
|
const gross = parseAtomicXmr(priceAtomicXmr);
|
|
if (gross === 0n) throw new Error('Sale price must be positive');
|
|
const { hosting: fee, author: additionalFee, sellerBeforeNetworkCosts } = allocateXmrSale(gross, feeBps);
|
|
return { invoice: { provider: 'mock' as const, amountXmr: formatXmr(gross), address: null,
|
|
label: 'SIMULATION ONLY — no Monero payment address. Never send real XMR.' },
|
|
feeXmr: formatXmr(fee), sellerNetXmr: formatXmr(sellerBeforeNetworkCosts),
|
|
additionalFee: { ...ADDITIONAL_MARKET_FEE, amountXmr: formatXmr(additionalFee), payout: 'not-started' as const } };
|
|
}
|