Files
martbost 0d2621defd missed: list each tier's skips in walk order
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 13:16:03 -05:00

54 lines
3.1 KiB
JavaScript

// The missed-payout notice, whole chain in one message (Marty, 2026-09-19).
//
// A purchase pays three tiers up the sponsor line. When a tier's rightful recipient is not
// qualified, the contract passes that share up until it finds someone who is, or hands it to
// the company. Every hop is an on-chain event: PassedUp (who was skipped, and why) and TierPaid
// (who finally got it, and how many hops up). Until now the Telegram notice reported one tier
// per message; this composes ONE message per purchase that shows every tier's walk, every
// person passed, and what it added up to. The point is that the people passed over see, in
// numbers, exactly what qualifying would have paid them.
//
// Pure: takes the events of one transaction plus a name resolver; returns the text or null.
'use strict';
const SHARE = { 1: 0.5, 2: 0.2, 3: 0.1 }; // tier shares of the purchase, for a tier nobody caught
const NEED = { 2: 2, 3: 5 }; // qualifying buyers a tier requires
function fmtPol(wei) {
try { return (Number(BigInt(String(wei)) / 10n ** 14n) / 1e4).toFixed(4); } catch (e) { return '0'; }
}
// txEvents: every indexed event sharing the tx. who(id) -> '#id @name'. had(id, tier) -> qualifying
// buyers that member had at the time (a number) or null when unknown.
function composeMissed(txEvents, who, had, site) {
const buy = txEvents.find(e => e.type === 'Purchase');
const skips = txEvents.filter(e => e.type === 'PassedUp');
if (!buy || !skips.length) return null;
const price = '$' + Math.round((buy.priceCents || 0) / 100);
const lines = ['\u{1F62C} <b>Missed payouts</b> on ' + who(buy.buyerId) + "'s " + price + ' purchase:'];
const passed = new Set(); let walked = 0;
for (const tier of [2, 3]) {
const sk = skips.filter(s => Number(s.tier) === tier).sort((x, y) => Number(x.li || 0) - Number(y.li || 0)); // walk order: nearest first
if (!sk.length) continue;
const paid = txEvents.find(e => e.type === 'TierPaid' && Number(e.tier) === tier);
const pol = paid ? Number(fmtPol(paid.amountWei)) : Number(fmtPol(BigInt(String(buy.paidWei || 0)) * BigInt(Math.round(SHARE[tier] * 100)) / 100n));
walked += pol;
const hops = sk.map(s => {
passed.add(s.skippedId);
let why;
if (s.reason === 'unqualified') { const n = had(s.skippedId, tier); why = (n == null ? 'not qualified' : n + ' of ' + NEED[tier] + ' qualifying buyers'); }
else if (s.reason === 'send-failed') why = 'wallet refused the payment';
else why = String(s.reason || 'passed');
return who(s.skippedId) + ' (' + why + ')';
});
const end = paid ? 'paid to ' + who(paid.recipientId) : 'nobody above was qualified, so the company kept it';
lines.push('Level ' + tier + ' · <b>' + pol.toFixed(4) + ' POL</b>: ' + hops.join(' → ') + ' → ' + end);
}
const n = passed.size;
lines.push('<b>' + walked.toFixed(4) + ' POL walked past ' + n + ' ' + (n === 1 ? 'person' : 'people') + ' on one ' + price + ' sale.</b>');
lines.push('Qualify before the next one: <a href="' + site + '">' + site.replace(/^https:\/\//, '') + '</a>');
return lines.join('\n');
}
module.exports = { composeMissed, fmtPol };