a87a63d75d
Site copy regenerated through the bv-tester1 engine; em dashes scrubbed from all user-visible strings. /api/my/activity serves per-member earnings, referrals, and purchases from the chain index. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
29 lines
1.1 KiB
JavaScript
29 lines
1.1 KiB
JavaScript
// Live ledger: recent history + SSE stream of new chain events.
|
|
(async function () {
|
|
await IAP.renderNav('ledger');
|
|
const c = await IAP.getConfig();
|
|
IAP.$('contractLink').href = c.explorer + '/address/' + c.contract;
|
|
const feed = IAP.$('feed');
|
|
|
|
const { events } = await (await fetch('/api/feed?n=150')).json();
|
|
feed.innerHTML = '';
|
|
if (!events.length) feed.innerHTML = '<div class="row muted">No activity yet. The first purchase will appear here the moment it lands.</div>';
|
|
for (const ev of events) feed.appendChild(IAP.feedRow(ev, c));
|
|
|
|
try {
|
|
const stats = await (await fetch('/api/stats')).json();
|
|
IAP.$('statLine').textContent = stats.onchainMembers + ' on-chain member(s)';
|
|
} catch (e) {}
|
|
|
|
const es = new EventSource('/api/feed/live');
|
|
es.onopen = () => { const b = IAP.$('liveBadge'); b.textContent = '● live'; };
|
|
es.onerror = () => { const b = IAP.$('liveBadge'); b.textContent = 'reconnecting…'; };
|
|
es.onmessage = m => {
|
|
try {
|
|
const ev = JSON.parse(m.data);
|
|
feed.prepend(IAP.feedRow(ev, c));
|
|
while (feed.children.length > 200) feed.removeChild(feed.lastChild);
|
|
} catch (e) {}
|
|
};
|
|
})();
|