From c7018f6258d6c11fae5dde4cdd814d8a1e91cd97 Mon Sep 17 00:00:00 2001 From: martbost Date: Wed, 9 Sep 2026 07:47:41 -0500 Subject: [PATCH] My line: POL earned from each person; wallet picker features non-Trust wallets first - /api/my/line sums TierPaid events per buyer for the signed-in member; the downline rows show "+X POL" (what that person has paid you so far). - AppKit featuredWalletIds: MetaMask, Phantom, SafePal, Coinbase first; Trust Wallet stays available under All wallets. Co-Authored-By: Claude Fable 5.1 --- public/assets/my.js | 2 ++ public/assets/site.css | 5 ++++- public/assets/wallet.js | 11 ++++++++++- public/index.html | 2 +- public/my.html | 8 ++++---- server.js | 13 ++++++++++++- 6 files changed, 33 insertions(+), 8 deletions(-) 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