Branded Voice copy pass, members activity panels, menu update
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>
This commit is contained in:
@@ -30,14 +30,15 @@ window.IAP = (function () {
|
||||
+ '<a class="logo" href="/">Instant<b>AdPay</b></a>'
|
||||
+ '<span class="links">'
|
||||
+ '<a href="/" data-p="home">How it works</a>'
|
||||
+ '<a href="/#ladder" data-p="pricing">Ad packages</a>'
|
||||
+ '<a href="/ledger" data-p="ledger">Live ledger</a>'
|
||||
+ '<a href="/my" data-p="my">My account</a>'
|
||||
+ '<a href="/my" data-p="my">Members</a>'
|
||||
+ '</span><span id="navWallet" class="muted">…</span></div>';
|
||||
document.body.prepend(nav);
|
||||
if (c.rehearsal) {
|
||||
const b = document.createElement('div');
|
||||
b.className = 'rehearsal';
|
||||
b.innerHTML = '<b>Testnet rehearsal</b> — running on ' + c.chainName + '. Purchases use valueless test POL while we prove every payout in public.';
|
||||
b.innerHTML = '<b>Testnet rehearsal</b>: running on ' + c.chainName + '. Purchases use valueless test POL while we prove every payout in public.';
|
||||
document.body.prepend(b);
|
||||
}
|
||||
const a = nav.querySelector('[data-p="' + active + '"]');
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if (sp.sponsorId) {
|
||||
const el = IAP.$('sponsorLine');
|
||||
el.hidden = false;
|
||||
el.textContent = 'You were invited by member #' + sp.sponsorId + ' — your purchases pay their team, and your own link will do the same for you.';
|
||||
el.textContent = 'You were invited by member #' + sp.sponsorId + '. Your purchases pay their team, and your own link will do the same for you.';
|
||||
}
|
||||
|
||||
async function loadLadder() {
|
||||
@@ -33,8 +33,8 @@
|
||||
btn.disabled = true;
|
||||
IAP.status('Confirm the purchase in your wallet…');
|
||||
const r = await IAPWallet.buy(Number(btn.dataset.id), sp.sponsorId || 0, btn.dataset.cost);
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted — see the explorer.');
|
||||
IAP.status('Purchase settled on-chain — credits are yours, payouts delivered. Watch it on the ledger.', 'ok');
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted. Check the explorer.');
|
||||
IAP.status('Purchase settled on-chain. Credits are yours, payouts delivered. Watch it on the ledger.', 'ok');
|
||||
IAP.refreshNavWallet();
|
||||
} catch (e) {
|
||||
IAP.status('Purchase failed: ' + (e.message || e), 'bad');
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
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>';
|
||||
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 {
|
||||
|
||||
+22
-5
@@ -16,15 +16,16 @@
|
||||
$('creditLine').textContent = (me.credits || 0).toLocaleString();
|
||||
const bc = me.buyerCount || 0;
|
||||
$('qualLine').innerHTML = '<b>' + bc + '</b> qualifying buyer(s) referred<br>'
|
||||
+ (bc >= 5 ? '<span class="badge">Level 3 unlocked — full three-level earnings</span>'
|
||||
+ (bc >= 5 ? '<span class="badge">Level 3 unlocked: full three-level earnings</span>'
|
||||
: bc >= 2 ? '<span class="badge">Level 2 unlocked</span> · ' + (5 - bc) + ' more for level 3'
|
||||
: (2 - bc) + ' more ≥$20 buyer(s) unlock level 2');
|
||||
$('activateCard').hidden = true;
|
||||
$('inviteLine').textContent = location.origin + '/join/' + me.memberId;
|
||||
$('copyInvite').hidden = false;
|
||||
loadActivity();
|
||||
} else {
|
||||
$('posLine').innerHTML = 'Signed in as <span class="mono">' + me.address.slice(0, 8) + '…' + me.address.slice(-6)
|
||||
+ '</span><br>free member — not on-chain yet'
|
||||
+ '</span><br>free member, not on-chain yet'
|
||||
+ (me.sponsorId ? '<br>invited by member #' + me.sponsorId : '');
|
||||
$('creditLine').textContent = '0';
|
||||
$('qualLine').textContent = 'Activate your payout wallet (or buy any package) to start; referrals who buy ≥$20 packages qualify you.';
|
||||
@@ -34,6 +35,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadActivity() {
|
||||
try {
|
||||
const c = await IAP.getConfig();
|
||||
const a = await (await fetch('/api/my/activity')).json();
|
||||
const fill = (id, evs, empty) => {
|
||||
const el = $(id);
|
||||
el.innerHTML = '';
|
||||
if (!evs.length) { el.innerHTML = '<div class="row muted">' + empty + '</div>'; return; }
|
||||
for (const ev of evs) el.appendChild(IAP.feedRow(ev, c));
|
||||
};
|
||||
fill('earnFeed', a.earnings, 'No payouts yet. They appear here the moment one lands.');
|
||||
fill('refFeed', a.referrals, 'No referral activity yet. Share your invite link.');
|
||||
fill('buyFeed', a.purchases, 'No purchases from this wallet yet.');
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
$('signinBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
$('signinBtn').disabled = true;
|
||||
@@ -51,8 +68,8 @@
|
||||
const me = await (await fetch('/api/me')).json();
|
||||
IAP.status('Confirm the free activation in your wallet…');
|
||||
const r = await IAPWallet.activate(me.sponsorId || 0);
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted — see the explorer.');
|
||||
IAP.status('Payout wallet activated — your invite link is live.', 'ok');
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted. Check the explorer.');
|
||||
IAP.status('Payout wallet activated. Your invite link is live.', 'ok');
|
||||
await render();
|
||||
} catch (e) { IAP.status('Activation failed: ' + ((e && e.message) || e), 'bad'); }
|
||||
finally { $('activateBtn').disabled = false; }
|
||||
@@ -60,7 +77,7 @@
|
||||
|
||||
$('copyInvite').addEventListener('click', async () => {
|
||||
try { await navigator.clipboard.writeText($('inviteLine').textContent); IAP.status('Link copied.', 'ok'); }
|
||||
catch (e) { IAP.status('Copy failed — select and copy the link text.', 'bad'); }
|
||||
catch (e) { IAP.status('Copy failed. Select and copy the link text.', 'bad'); }
|
||||
});
|
||||
|
||||
render();
|
||||
|
||||
@@ -13,7 +13,7 @@ a:hover{text-decoration:underline}
|
||||
.wrap{max-width:1020px;margin:0 auto;padding:0 18px}
|
||||
/* nav */
|
||||
nav{border-bottom:1px solid var(--line);background:rgba(13,20,32,.92);position:sticky;top:0;z-index:10}
|
||||
nav .wrap{display:flex;align-items:center;gap:22px;height:58px}
|
||||
nav .wrap{display:flex;align-items:center;gap:22px;min-height:58px;flex-wrap:wrap;padding-top:6px;padding-bottom:6px}
|
||||
.logo{font-weight:800;font-size:19px;color:var(--ink)}
|
||||
.logo b{color:var(--amber)}
|
||||
nav .links{display:flex;gap:18px;font-size:14.5px;flex:1}
|
||||
|
||||
@@ -56,7 +56,7 @@ window.IAPWallet = (function () {
|
||||
if (r.result) return r.result;
|
||||
await new Promise(res => setTimeout(res, 2500));
|
||||
}
|
||||
throw new Error('Timed out waiting for the transaction — check the explorer.');
|
||||
throw new Error('Timed out waiting for the transaction. Check the explorer.');
|
||||
}
|
||||
// buy: quote is read live server-side; pad 2% for oracle drift, contract
|
||||
// refunds every wei of excess in the same transaction.
|
||||
|
||||
+34
-34
@@ -2,17 +2,17 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>InstantAdPay — advertising that pays instantly, on-chain</title>
|
||||
<meta name="description" content="Members-only advertising with immutable on-chain settlement. Every package purchase pays the people who built the audience — in the same transaction, verifiable by anyone.">
|
||||
<title>InstantAdPay: advertise and earn, locked in code</title>
|
||||
<meta name="description" content="Real ad packages with instant on-chain settlement. Every purchase pays the sponsor line in the same transaction, verifiable by anyone on the live ledger.">
|
||||
<link rel="stylesheet" href="/assets/site.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<section class="hero">
|
||||
<h1>Advertising that pays the people who build it — <em>instantly, on-chain</em>.</h1>
|
||||
<p class="lead">Free to join. Real ad inventory. And when anyone buys an ad package,
|
||||
the payment splits to their sponsors <b>in the same blockchain transaction</b> —
|
||||
no balances, no withdrawal requests, no company holding your money. Ever.</p>
|
||||
<h1>Advertise and earn. <em>Locked in code, not promises.</em></h1>
|
||||
<p class="lead">Buy real ad packages from 5 to 250 dollars. Every purchase settles through
|
||||
a smart contract you can read yourself, and your earnings land in
|
||||
<b>your own wallet</b> before the page even refreshes.</p>
|
||||
<p>
|
||||
<a class="btn" href="/my">Join free</a>
|
||||
<a class="btn sec" href="/ledger">Watch payments land live</a>
|
||||
@@ -20,7 +20,7 @@
|
||||
<p class="small muted" id="sponsorLine" hidden></p>
|
||||
</section>
|
||||
|
||||
<h2>Where every dollar goes — enforced by code, not promises</h2>
|
||||
<h2>Where every dollar goes</h2>
|
||||
<div class="card">
|
||||
<div class="split">
|
||||
<div class="s50">50%<br>direct sponsor</div>
|
||||
@@ -28,25 +28,25 @@
|
||||
<div class="s10">10%<br>level 3</div>
|
||||
<div class="sa">20%<br>platform</div>
|
||||
</div>
|
||||
<p class="muted">These percentages are <b>constants in an immutable smart contract</b> — there is no
|
||||
function to change them, pause payouts, or hold funds. The contract's balance is zero after every
|
||||
sale because everything is delivered the moment it arrives. Don't take our word for it:
|
||||
every payment is public on the <a href="/ledger">live ledger</a> with a verify link to the blockchain.</p>
|
||||
<p class="muted">Most referral programs run on a database someone can change after you promote.
|
||||
This one runs on Polygon. The percentages are written into a contract nobody can touch, not even us.
|
||||
Payouts split 50-20-10 across three levels plus a 20 percent platform fee, every single time, on a
|
||||
<a href="/ledger">public ledger</a> where every payment has a verify link you can click.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid c3">
|
||||
<div class="card"><h3>🆓 Join free, earn from day one</h3>
|
||||
<p class="muted small">Membership costs nothing. Share your link and you earn 50% of every ad package
|
||||
your referrals ever buy — not once, every time. Payment arrives in your own wallet within seconds
|
||||
of their purchase.</p></div>
|
||||
<div class="card"><h3>📣 Real advertising, on real audiences</h3>
|
||||
<p class="muted small">Packages buy ad credits delivered across our owned network — banner, text, and
|
||||
login placements seen by active members. Credits are recorded on-chain and only ever spent by
|
||||
your own campaigns.</p></div>
|
||||
<div class="card"><h3>🔎 Qualification by performance</h3>
|
||||
<p class="muted small">Deeper earning levels unlock by referring real buyers — 2 buyers unlock level 2,
|
||||
5 unlock level 3. No buying your way in, no timers, no demotions. When someone in your line isn't
|
||||
qualified, their share passes up to the next person who is.</p></div>
|
||||
<div class="card"><h3>🆓 Join free. Earn from every package your referrals ever buy.</h3>
|
||||
<p class="muted small">Sign up costs nothing. Zero. Every ad package your direct referrals buy for life
|
||||
pays you 50 percent straight to your wallet. Level 2 pays 20 percent. Level 3 pays 10 percent.
|
||||
No balances held, no withdrawal button, no company touching the money.</p></div>
|
||||
<div class="card"><h3>📣 Real ads. Real audience. Credits on-chain.</h3>
|
||||
<p class="muted small">Your ad credits are minted on-chain when you buy. One credit equals one cent of
|
||||
ad delivery across our network of sites. Banner, text, and login ads that only your campaigns
|
||||
can spend.</p></div>
|
||||
<div class="card"><h3>🔎 Qualify by performance. Pass-ups fill the gaps.</h3>
|
||||
<p class="muted small">Level 2 unlocks when you bring 2 buyers who have purchased 20 dollars or more.
|
||||
Level 3 unlocks at 5 qualified buyers. If someone in your line is not qualified, their share passes
|
||||
up to the next qualified person automatically. The contract handles it.</p></div>
|
||||
</div>
|
||||
|
||||
<h2>The ad packages</h2>
|
||||
@@ -64,21 +64,21 @@
|
||||
|
||||
<h2>Why this is different</h2>
|
||||
<div class="grid c2">
|
||||
<div class="card"><h3>No trust required</h3>
|
||||
<p class="muted small">Most affiliate platforms ask you to trust their dashboard number and their
|
||||
payout schedule. Here there is no dashboard number to trust — your earnings arrive as blockchain
|
||||
transactions to your own wallet, and the contract that sends them cannot be modified by anyone,
|
||||
including us.</p></div>
|
||||
<div class="card"><h3>Honest about what it is</h3>
|
||||
<p class="muted small">This is advertising with a referral program, not an investment. Nobody earns
|
||||
without real ad purchases happening, and no income is guaranteed. What we guarantee is the part
|
||||
code can guarantee: if a purchase happens in your line, your share reaches your wallet — instantly,
|
||||
or it visibly passes to someone qualified.</p></div>
|
||||
<div class="card"><h3>No trust required. Your earnings are a transaction to your wallet.</h3>
|
||||
<p class="muted small">Every other platform asks you to trust their ledger. Believe their numbers.
|
||||
Wait for their withdrawal window. InstantAdPay does none of that. The smart contract pays each level
|
||||
at the moment of purchase. Your earnings are a blockchain transaction landing in your own wallet.
|
||||
You can verify every single one on the <a href="/ledger">live ledger</a> with your own eyes.</p></div>
|
||||
<div class="card"><h3>It is an ad service. That is the only thing it is.</h3>
|
||||
<p class="muted small">This is an advertising platform with a referral program. Plain and simple.
|
||||
You buy ad credits. You get ads delivered. You refer other advertisers and earn from what they spend.
|
||||
There is no investment pool, no ROI claim, no income promise. What the code guarantees is what the
|
||||
code does: split the money and pay it out. That is it.</p></div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div>InstantAdPay · every payment verifiable on-chain · <a href="/ledger">live ledger</a> · <a id="contractLink" href="#" target="_blank" rel="noopener">view the contract ↗</a></div>
|
||||
<div class="small">Advertising services with a performance referral program. Not an investment product; no income guarantees. Crypto transactions are irreversible — never spend what you cannot afford.</div>
|
||||
<div class="small">Advertising services with a performance referral program. Not an investment product; no income guarantees. Crypto transactions are irreversible. Never spend what you cannot afford.</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="/assets/common.js"></script>
|
||||
|
||||
+4
-5
@@ -2,17 +2,16 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Live ledger — InstantAdPay</title>
|
||||
<title>Live ledger | InstantAdPay</title>
|
||||
<meta name="description" content="Every purchase, payout, and pass-up on InstantAdPay, streamed straight from the blockchain with a verify link on every line.">
|
||||
<link rel="stylesheet" href="/assets/site.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<section class="hero" style="padding-bottom:20px">
|
||||
<h1>The <em>live ledger</em></h1>
|
||||
<p class="lead">This feed is not our database — it is the blockchain itself, decoded.
|
||||
Every line has a verify link that opens the raw transaction. If it's not here, it didn't happen;
|
||||
if it is here, nobody can undo it.</p>
|
||||
<h1>The ledger <em>does not lie</em>.</h1>
|
||||
<p class="lead">This page streams every payment the contract has ever made. If it is not here,
|
||||
it did not happen. Every line carries a verify link straight to the block explorer. Go click one.</p>
|
||||
<p><span class="badge" id="liveBadge">connecting…</span>
|
||||
<span class="small muted" id="statLine"></span></p>
|
||||
</section>
|
||||
|
||||
+27
-9
@@ -2,21 +2,21 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>My account — InstantAdPay</title>
|
||||
<title>My account | InstantAdPay</title>
|
||||
<link rel="stylesheet" href="/assets/site.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<section class="hero" style="padding-bottom:16px">
|
||||
<h1>My <em>account</em></h1>
|
||||
<p class="lead" id="introLead">One free wallet signature signs you in — it cannot move funds or approve anything.
|
||||
No email, no password.</p>
|
||||
<p class="lead" id="introLead">Sign in with one free wallet signature. No email. No password.
|
||||
No account to create. The signature is free and cannot move funds.</p>
|
||||
</section>
|
||||
|
||||
<div class="card" id="signinCard">
|
||||
<h3>Sign in with your wallet</h3>
|
||||
<p class="muted small">New here? The same button creates your free membership. Your earnings always go
|
||||
straight to this wallet — we never hold them.</p>
|
||||
straight to this wallet. We never hold them.</p>
|
||||
<button class="btn" id="signinBtn">Connect & sign in</button>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</div>
|
||||
|
||||
<div class="card" id="activateCard" hidden>
|
||||
<h3>Activate your payout wallet — free</h3>
|
||||
<h3>Activate your payout wallet, free</h3>
|
||||
<p class="muted small">One free transaction registers this wallet on-chain so commissions can reach it.
|
||||
Buying any package does this automatically, so you can also just start with a package below.</p>
|
||||
<button class="btn sec" id="activateBtn">Activate payout wallet</button>
|
||||
@@ -40,16 +40,34 @@
|
||||
|
||||
<div class="card">
|
||||
<h3>Your invite link</h3>
|
||||
<p class="muted small">Share it anywhere. Everyone who joins through it becomes part of your line —
|
||||
you earn 50% of every ad package they ever buy, level 2 and 3 of their teams' buys as you qualify.</p>
|
||||
<p class="muted small">Share it anywhere. Everyone who joins through it becomes part of your line.
|
||||
You earn 50 percent of every ad package they ever buy, plus levels 2 and 3 of their teams as you qualify.</p>
|
||||
<p class="mono" id="inviteLine">Sign in to get your link.</p>
|
||||
<button class="btn small sec" id="copyInvite" hidden>Copy link</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Buy ad packages</h3>
|
||||
<p class="muted small">The full ladder with live pricing is on the <a href="/">home page</a> —
|
||||
purchases from this wallet automatically credit this account.</p>
|
||||
<p class="muted small">The full ladder with live pricing is on the <a href="/">home page</a>.
|
||||
Purchases from this wallet automatically credit this account.</p>
|
||||
</div>
|
||||
|
||||
<h2>Your activity, straight from the chain</h2>
|
||||
<div class="grid c2">
|
||||
<div class="card">
|
||||
<h3>Earnings</h3>
|
||||
<p class="muted small">Every payout the contract has sent to your wallet. Each line links to the transaction.</p>
|
||||
<div class="feed" id="earnFeed"><div class="row muted">Nothing yet.</div></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Your referrals</h3>
|
||||
<p class="muted small">Activations and qualifying buys in your line.</p>
|
||||
<div class="feed" id="refFeed"><div class="row muted">Nothing yet.</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Your purchases</h3>
|
||||
<div class="feed" id="buyFeed"><div class="row muted">Nothing yet.</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ function siteConfig() {
|
||||
try { saved = JSON.parse(fs.readFileSync(SITE_FILE, 'utf8')); } catch (e) {}
|
||||
return Object.assign({
|
||||
siteName: 'InstantAdPay',
|
||||
tagline: 'Advertising that pays the people who build it — instantly, on-chain.',
|
||||
tagline: 'Advertise and earn. Locked in code, not promises.',
|
||||
rehearsal: true // shows the testnet banner; flipped off at mainnet launch
|
||||
}, saved);
|
||||
}
|
||||
@@ -172,6 +172,20 @@ const server = http.createServer(async (req, res) => {
|
||||
return json(res, 200, out);
|
||||
}
|
||||
|
||||
if (p === '/api/my/activity' && req.method === 'GET') {
|
||||
const s = auth.fromRequest(req);
|
||||
if (!s) return json(res, 401, { error: 'Sign in first.' });
|
||||
const id = s.memberId || await auth.refreshMemberId(s);
|
||||
if (!id) return json(res, 200, { memberId: 0, earnings: [], purchases: [], referrals: [] });
|
||||
const evs = chain.recentEvents(600);
|
||||
return json(res, 200, {
|
||||
memberId: id,
|
||||
earnings: evs.filter(e => (e.type === 'TierPaid' && e.recipientId === id) || (e.type === 'AwardPaid' && e.toId === id)),
|
||||
purchases: evs.filter(e => e.type === 'Purchase' && e.buyerId === id),
|
||||
referrals: evs.filter(e => (e.type === 'MemberActivated' && e.sponsorId === id) || (e.type === 'BuyerCounted' && e.sponsorId === id))
|
||||
});
|
||||
}
|
||||
|
||||
// -- admin (Bearer ADMIN_PASSWORD)
|
||||
if (p === '/api/admin/site' && req.method === 'PATCH') {
|
||||
if (!isAdmin(req)) return json(res, 401, { error: 'auth' });
|
||||
|
||||
Reference in New Issue
Block a user