Show which generation caught each pass-up + finish domain go-forward

Feature (Marty): live payment proof + notifications now show the
generation for upgrade pass-ups (matrix hop distance payer→recipient),
removing the "why did they get it" question. chain.genBetween() adds a
`gen` field to payout events + /api/public/payouts; rendered as a gold
"Gen N" badge in the feed, "Gen N pass-up" in toasts, and "Gen N …" in
Telegram team alerts.

Domain: rmcircle.team is now live (added to Coolify alongside
rmcircle.saasy.top, SSL issued, both serve, no redirect). Switched the
auto-tweet CTA to https://rmcircle.team.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-16 05:22:47 -05:00
parent 663948595c
commit d0b1eddda2
5 changed files with 19 additions and 6 deletions
+14 -2
View File
@@ -200,6 +200,18 @@ function passedOver(fromId, toId) {
return [];
}
// Which generation caught a pass-up: matrix hops from the payer up to the
// recipient (1 = direct parent, 2 = grandparent, …). null if not on the chain.
function genBetween(fromId, toId) {
if (!state || !fromId || !toId) return null;
let cur = state.members[fromId] && state.members[fromId].uplineId;
for (let hops = 1; cur && hops <= 40; hops++) {
if (cur === toId) return hops;
cur = state.members[cur] && state.members[cur].uplineId;
}
return null;
}
async function processRange(fromBlock, toBlock) {
const logs = await rpc('eth_getLogs', [{
address: CONTRACT, fromBlock: '0x' + fromBlock.toString(16), toBlock: '0x' + toBlock.toString(16),
@@ -258,7 +270,7 @@ async function processRange(fromBlock, toBlock) {
state.payouts.push(p); state.totals.count++; state.totals.pol = +(state.totals.pol + p.pol).toFixed(6);
const rcpt = state.members[p.toId];
if (rcpt) rcpt.earnedPol = +((rcpt.earnedPol || 0) + p.pol).toFixed(6);
emit({ type: 'payout', kind: p.kind, toId: p.toId, fromId: p.fromId, pol: p.pol, levelName: levelName(p.level), upgrade: p.upgrade, tx, ts });
emit({ type: 'payout', kind: p.kind, toId: p.toId, fromId: p.fromId, pol: p.pol, levelName: levelName(p.level), upgrade: p.upgrade, gen: p.kind === 'upline' ? genBetween(p.fromId, p.toId) : undefined, tx, ts });
}
}
}
@@ -344,7 +356,7 @@ function getPayoutsPublic(offset = 0, limit = 40) {
limit: lim,
hasMore: off + lim < reversed.length,
payouts: page.map(p => ({
key: p.key, kind: p.kind, toId: p.toId, fromId: p.fromId,
key: p.key, kind: p.kind, toId: p.toId, fromId: p.fromId, gen: p.kind === 'upline' ? genBetween(p.fromId, p.toId) : undefined,
level: p.level, levelName: levelName(p.level), pol: p.pol, tx: p.tx, ts: p.ts, desc: p.desc,
toAccount: state.members[p.toId] ? state.members[p.toId].account : undefined,
upgrade: p.upgrade ? { id: p.upgrade.id, newLevel: p.upgrade.newLevel, levelName: levelName(p.upgrade.newLevel), tier: tierName(p.upgrade.tier) } : undefined,