diff --git a/public/assets/my.js b/public/assets/my.js index 7d8cb48..56c01fb 100644 --- a/public/assets/my.js +++ b/public/assets/my.js @@ -949,6 +949,8 @@ '
Level ' + L.level + ' · ' + L.members.length + (L.level === 1 ? ' direct' : '') + '
' + L.members.map(m => '
' + esc(m.name) + '' + (m.email ? '' + esc(m.email) + '' : '#' + m.memberId + '') + + '' + + (m.earnedWei && m.earnedWei !== '0' ? '+' + IAP.fmtPol(m.earnedWei) + ' POL' : '0.00 POL') + '' + '' + new Date(m.joined).toLocaleDateString() + '' + (m.email ? '' : '') + '
').join('') diff --git a/public/assets/site.css b/public/assets/site.css index 06de70b..ba06ff8 100644 --- a/public/assets/site.css +++ b/public/assets/site.css @@ -406,7 +406,7 @@ textarea{resize:vertical;font:inherit} .lin-lvl{margin:10px 0} .lin-lvl>.cap{display:inline-block;font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.06em; color:var(--mint);background:var(--mint-soft);border:1px solid var(--line-strong);border-radius:8px;padding:4px 10px;margin-bottom:10px} -.lin-row{display:grid;grid-template-columns:minmax(110px,1.2fr) minmax(0,2fr) auto auto;gap:6px 14px; +.lin-row{display:grid;grid-template-columns:minmax(110px,1.2fr) minmax(0,2fr) auto auto auto;gap:6px 14px; align-items:center;padding:9px 0;border-bottom:1px solid var(--line)} .lin-row .nm{font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .lin-row .em{font-size:12px;color:var(--mint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis} @@ -606,3 +606,6 @@ img{max-width:100%} .obj .lab-say{color:var(--amber)} .obj-truth p{margin:0;font-size:14.5px;color:var(--ink)} .obj-say{margin:0} + +.lin-row .earn{font-family:var(--mono);font-size:12px;color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums} +.lin-row .earn.on{color:var(--mint);font-weight:700} diff --git a/public/assets/wallet.js b/public/assets/wallet.js index c75ad95..bca3dd7 100644 --- a/public/assets/wallet.js +++ b/public/assets/wallet.js @@ -49,7 +49,16 @@ window.IAPWallet = (function () { adapters: [wagmiAdapter], networks: allNets, projectId, defaultNetwork: net, metadata: { name: c.siteName || 'InstantAdPay', description: c.tagline || 'Advertise and earn, paid on-chain.', url: location.origin, icons: [location.origin + '/logo-icon.png'] }, - features: { analytics: false, email: false, socials: [] } + features: { analytics: false, email: false, socials: [] }, + // Picker order: wallets without Trust's balance-proportion block go first. + // Trust Wallet is NOT excluded; it just drops out of the featured row into + // "All wallets" (Marty, 2026-09-09: move Trust to the bottom, not off). + featuredWalletIds: [ + 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96', // MetaMask + 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393', // Phantom + '0b415a746fb9ee99cce155c2ceca0c6f6061b1dbca2d722b3ba16381d0562150', // SafePal + 'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa' // Coinbase Wallet + ] }); return modal; })(); diff --git a/public/index.html b/public/index.html index 867a32c..202583e 100644 --- a/public/index.html +++ b/public/index.html @@ -439,7 +439,7 @@ - + diff --git a/public/my.html b/public/my.html index fd4a30a..d93c4fc 100644 --- a/public/my.html +++ b/public/my.html @@ -5,7 +5,7 @@ Member area | InstantAdPay - + @@ -283,7 +283,7 @@

Your downline, three levels deep

-

Everyone below you across levels 1–3. You see email addresses for your +

Everyone below you across levels 1–3. The POL figure is what each person has paid you so far, straight from the ledger. You see email addresses for your direct referrals only; deeper levels show username and ID. Message your direct referrals right here.

Loading…

@@ -737,9 +737,9 @@
- + - + diff --git a/server.js b/server.js index eda168a..b512e28 100644 --- a/server.js +++ b/server.js @@ -872,11 +872,22 @@ const server = http.createServer(async (req, res) => { const s = await auth.fromRequest(req); if (!s || !s.email) return json(res, 401, { error: 'Sign in first.' }); const levels = await accounts.downline(s.email, 3); + // what each person has paid THIS member so far: sum of TierPaid events where + // this member is the recipient and that person is the buyer (all indexed events) + const myId = await auth.refreshMemberId(s); + const earnedBy = {}; + if (myId) { + for (const ev of chain.recentEvents(1e9)) { + if (ev.type === 'TierPaid' && ev.recipientId === myId && ev.buyerId) + earnedBy[ev.buyerId] = (BigInt(earnedBy[ev.buyerId] || '0') + BigInt(ev.amountWei)).toString(); + } + } const out = levels.map(L => ({ level: L.level, members: L.members.map(m => ({ memberId: m.memberId || 0, name: m.username ? '@' + m.username : m.memberId ? 'member #' + m.memberId : 'member', email: L.level === 1 ? m.email : null, // directs only - joined: m.created })) })); + joined: m.created, + earnedWei: (m.memberId && earnedBy[m.memberId]) || '0' })) })); return json(res, 200, { levels: out, counts: out.map(L => L.members.length) }); } // -- broadcast a message to your downline (1/day), on-site inbox + email