/** * Static-address mode disambiguation ("cent dust"): when several invoices share one * receiving address, each gets a unique random suffix in the 4th decimal place region * (0.0001–0.0999) so incoming amounts map to exactly one invoice. */ /** One dust step = 0.0001 in 6-decimal base units. */ export const DUST_STEP = 100n; export const DUST_MAX_STEPS = 999; export function applyCentDust( baseAmount: bigint, isTaken: (candidate: bigint) => boolean, random: () => number = Math.random, ): bigint { for (let attempt = 0; attempt < 500; attempt++) { const steps = 1 + Math.floor(random() * DUST_MAX_STEPS); const candidate = baseAmount + BigInt(steps) * DUST_STEP; if (!isTaken(candidate)) return candidate; } // Random attempts exhausted (pathological collision rate) — sweep deterministically. for (let steps = 1; steps <= DUST_MAX_STEPS; steps++) { const candidate = baseAmount + BigInt(steps) * DUST_STEP; if (!isTaken(candidate)) return candidate; } throw new Error('no unique dust suffix available — too many concurrent invoices at this amount'); }