30 lines
1.6 KiB
TypeScript
Executable File
30 lines
1.6 KiB
TypeScript
Executable File
import { ADDITIONAL_MARKET_FEE } from './market.ts';
|
|
import { assertXmrAmount, xmrCommission } from './xmr-amount.ts';
|
|
|
|
/** Allocation only, not proof of payment or an instruction to send/retain funds. */
|
|
export function allocateXmrSale(gross: bigint, hostingBps: number) {
|
|
assertXmrAmount(gross);
|
|
if (gross === 0n) throw new Error('Sale price must be positive; use a free transfer for gifts');
|
|
if (!Number.isSafeInteger(hostingBps) || hostingBps < 0 || hostingBps > 5000) {
|
|
throw new Error('Hosting commission must be between 0 and 5000 basis points');
|
|
}
|
|
const hosting = xmrCommission(gross, hostingBps);
|
|
const author = xmrCommission(gross, ADDITIONAL_MARKET_FEE.bps);
|
|
return { gross, hosting, author, sellerBeforeNetworkCosts: gross - hosting - author };
|
|
}
|
|
|
|
/**
|
|
* Evaluate an explicitly supplied total seller-funded network-cost budget, including
|
|
* every applicable leg. Does not choose who funds an author leg or approve a quote.
|
|
* The budget is a maximum, not revenue; actual costs/unused budget need accounting.
|
|
*/
|
|
export function assessXmrSaleBudget(gross: bigint, hostingBps: number, sellerNetworkBudget: bigint) {
|
|
const allocation = allocateXmrSale(gross, hostingBps);
|
|
assertXmrAmount(sellerNetworkBudget);
|
|
const available = allocation.sellerBeforeNetworkCosts;
|
|
const viable = sellerNetworkBudget < available;
|
|
return { ...allocation, sellerNetworkBudget, viable,
|
|
sellerMinimumNet: viable ? available - sellerNetworkBudget : 0n,
|
|
// Additional gross-independent funding required to retain at least one atomic unit.
|
|
fundingShortfall: viable ? 0n : sellerNetworkBudget - available + 1n };
|
|
} |