Design pass v1: DeFi-flash visual system with real on-chain counters

Aurora ground, glass panels, gradient pill CTAs, Sora display face, live
money ticker, stat band fed by chain totals (tallied in the indexer with
one-time backfill), format showcase, Branded Voice FAQ accordions. CSP
extended for Google Fonts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-04 13:15:14 -05:00
parent bee13ba4b8
commit ca3c9f3063
7 changed files with 200 additions and 53 deletions
+16 -1
View File
@@ -173,6 +173,7 @@ function decodeLog(log) {
function loadState() { function loadState() {
try { state = JSON.parse(fs.readFileSync(STATE_FILE, 'utf8')); } catch (e) { state = null; } try { state = JSON.parse(fs.readFileSync(STATE_FILE, 'utf8')); } catch (e) { state = null; }
if (!state || state.v !== 1) state = { v: 1, lastBlock: getConfig().deployBlock - 1, events: [] }; if (!state || state.v !== 1) state = { v: 1, lastBlock: getConfig().deployBlock - 1, events: [] };
if (!state.totals) { for (const ev of state.events) tally(ev); saveState(); } // one-time backfill
} }
function saveState() { function saveState() {
try { try {
@@ -194,6 +195,7 @@ async function tail() {
const ev = decodeLog(lg); const ev = decodeLog(lg);
if (!ev) continue; if (!ev) continue;
state.events.push(ev); state.events.push(ev);
tally(ev);
if (onEvent) { try { onEvent(ev); } catch (e) { console.error('chain onEvent', e.message); } } if (onEvent) { try { onEvent(ev); } catch (e) { console.error('chain onEvent', e.message); } }
} }
if (state.events.length > KEEP_EVENTS) state.events = state.events.slice(-KEEP_EVENTS); if (state.events.length > KEEP_EVENTS) state.events = state.events.slice(-KEEP_EVENTS);
@@ -205,6 +207,19 @@ async function tail() {
} }
function recentEvents(n) { return state ? state.events.slice(-(n || 100)).reverse() : []; } function recentEvents(n) { return state ? state.events.slice(-(n || 100)).reverse() : []; }
// running totals for the public counters — every number provable on-chain
function tally(ev) {
if (!state.totals) state.totals = { purchases: 0, paidInWei: '0', payouts: 0, payoutWei: '0', activations: 0 };
const t = state.totals;
if (ev.type === 'Purchase') { t.purchases += 1; t.paidInWei = (BigInt(t.paidInWei) + BigInt(ev.paidWei)).toString(); }
if (ev.type === 'TierPaid') { t.payouts += 1; t.payoutWei = (BigInt(t.payoutWei) + BigInt(ev.amountWei)).toString(); }
if (ev.type === 'AwardPaid') { t.payouts += 1; t.payoutWei = (BigInt(t.payoutWei) + BigInt(ev.amountWei)).toString(); }
if (ev.type === 'MemberActivated') t.activations += 1;
}
function totals() {
return state && state.totals ? state.totals : { purchases: 0, paidInWei: '0', payouts: 0, payoutWei: '0', activations: 0 };
}
function init(opts) { function init(opts) {
if (opts && opts.onEvent) onEvent = opts.onEvent; if (opts && opts.onEvent) onEvent = opts.onEvent;
getConfig(); loadState(); getConfig(); loadState();
@@ -213,4 +228,4 @@ function init(opts) {
} }
module.exports = { init, getConfig, reloadConfig, memberIdByAccount, memberCount, member, module.exports = { init, getConfig, reloadConfig, memberIdByAccount, memberCount, member,
product, productCount, quoteWei, creditBalance, catalog, recentEvents, rpc }; product, productCount, quoteWei, creditBalance, catalog, recentEvents, totals, rpc };
+21
View File
@@ -46,5 +46,26 @@
IAP.status('Purchase failed: ' + (e.message || e), 'bad'); IAP.status('Purchase failed: ' + (e.message || e), 'bad');
} finally { btn.disabled = false; } } finally { btn.disabled = false; }
} }
async function loadStats() {
try {
const s = await (await fetch('/api/stats')).json();
IAP.$('stMembers').textContent = (s.onchainMembers || 0).toLocaleString();
IAP.$('stPurchases').textContent = (s.purchases || 0).toLocaleString();
IAP.$('stPaid').textContent = IAP.fmtPol(s.paidInWei || '0');
IAP.$('stPayouts').textContent = (s.payouts || 0).toLocaleString();
} catch (e) {}
}
async function loadTicker() {
try {
const { events } = await (await fetch('/api/feed?n=30')).json();
if (!events.length) return;
const inner = IAP.$('tickerInner');
inner.innerHTML = events.map(ev => '<span>' + IAP.describeEvent(ev, c) + '</span>').join('');
IAP.$('ticker').hidden = false;
} catch (e) {}
}
loadLadder(); loadLadder();
loadStats();
loadTicker();
setInterval(loadStats, 60000);
})(); })();
+97 -48
View File
@@ -1,82 +1,131 @@
/* InstantAdPay — site-wide styles. /* InstantAdPay visual system v2 — "commercial ad-network polish x DeFi flash".
Identity: "wire-transfer receipt meets neon ledger" — dark bank-slate ground, Refs: Adsterra/PropellerAds (dual-audience hero, real-number counters,
electric mint for money-in-motion, warm amber for calls to action. */ format showcase) x DeFi landing patterns (aurora glows, glass cards,
bento grids, ticker heartbeat). Dark luxe ground; mint = money in motion;
amber gradient = action. Display face: Sora. */
:root{ :root{
--ground:#0d1420; --panel:#141d2e; --panel2:#1a2538; --line:#26344d; --ground:#070b16; --panel:rgba(19,28,48,.66); --panel-solid:#131c30;
--ink:#e8eef7; --muted:#8fa1bb; --mint:#3ee6a8; --mint-soft:#10362b; --line:rgba(126,144,186,.16); --line-strong:rgba(126,144,186,.32);
--amber:#f5b83d; --amber-ink:#0d1420; --bad:#ff8f7d; --mono:"Consolas","JetBrains Mono",monospace; --ink:#eef2fb; --muted:#8b9ab5;
--mint:#3de8a8; --mint-dim:#1c5b44; --mint-soft:rgba(61,232,168,.1);
--amber:#ffb238; --amber2:#ff7a45; --amber-ink:#160f04;
--violet:#8b6cf6; --cyan:#5cc8ee; --bad:#ff8f7d;
--mono:"Consolas","JetBrains Mono",monospace;
--disp:"Sora","Segoe UI",system-ui,sans-serif;
--radius:16px;
} }
*{box-sizing:border-box} *{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--ink);font:16px/1.55 "Segoe UI",system-ui,sans-serif} body{margin:0;background:var(--ground);color:var(--ink);font:16px/1.6 "Segoe UI",system-ui,sans-serif;overflow-x:hidden}
/* aurora ground: two blurred glow fields, fixed behind everything */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
background:
radial-gradient(560px 420px at 82% -6%, rgba(139,108,246,.22), transparent 65%),
radial-gradient(640px 460px at -8% 34%, rgba(61,232,168,.13), transparent 65%),
radial-gradient(520px 420px at 58% 108%, rgba(255,122,69,.10), transparent 65%);}
a{color:var(--mint);text-decoration:none} a{color:var(--mint);text-decoration:none}
a:hover{text-decoration:underline} a:hover{text-decoration:underline}
.wrap{max-width:1020px;margin:0 auto;padding:0 18px} .wrap{max-width:1060px;margin:0 auto;padding:0 20px}
h1,h2,h3{font-family:var(--disp);letter-spacing:-.01em}
/* nav */ /* nav */
nav{border-bottom:1px solid var(--line);background:rgba(13,20,32,.92);position:sticky;top:0;z-index:10} nav{border-bottom:1px solid var(--line);background:rgba(7,11,22,.72);backdrop-filter:blur(14px);
nav .wrap{display:flex;align-items:center;gap:22px;min-height:58px;flex-wrap:wrap;padding-top:6px;padding-bottom:6px} -webkit-backdrop-filter:blur(14px);position:sticky;top:0;z-index:10}
.logo{font-weight:800;font-size:19px;color:var(--ink)} nav .wrap{display:flex;align-items:center;gap:22px;min-height:62px;flex-wrap:wrap;padding-top:6px;padding-bottom:6px}
.logo b{color:var(--amber)} .logo{font-family:var(--disp);font-weight:800;font-size:20px;color:var(--ink)}
nav .links{display:flex;gap:18px;font-size:14.5px;flex:1} .logo b{background:linear-gradient(100deg,var(--amber),var(--amber2));-webkit-background-clip:text;background-clip:text;color:transparent}
nav .links{display:flex;gap:20px;font-size:14.5px;flex:1;flex-wrap:wrap}
nav a{color:var(--muted)} nav a{color:var(--muted)}
nav a:hover{color:var(--ink);text-decoration:none} nav a:hover{color:var(--ink);text-decoration:none}
#navWallet{font-size:13.5px} #navWallet{font-size:13.5px}
.rehearsal{background:#3d2a52;color:#c9a9f7;text-align:center;font-size:13px;padding:6px 10px} .rehearsal{background:linear-gradient(90deg,#2c2150,#1c3050);color:#c9b8f7;text-align:center;font-size:13px;padding:7px 12px}
.rehearsal b{color:#e6d5ff} .rehearsal b{color:#eadfff}
/* buttons */ /* buttons */
.btn{display:inline-block;background:var(--amber);color:var(--amber-ink);border:0;border-radius:10px; .btn{display:inline-block;background:linear-gradient(100deg,var(--amber),var(--amber2));color:var(--amber-ink);
padding:12px 22px;font-weight:800;font-size:15.5px;cursor:pointer;font-family:inherit} border:0;border-radius:999px;padding:13px 26px;font-weight:800;font-size:15.5px;cursor:pointer;font-family:var(--disp);
.btn.sec{background:transparent;color:var(--mint);border:2px solid var(--mint);padding:10px 20px} box-shadow:0 6px 24px rgba(255,150,60,.28);transition:transform .15s ease,box-shadow .15s ease}
.btn.small{padding:8px 14px;font-size:13.5px} .btn:hover{transform:translateY(-2px);box-shadow:0 10px 30px rgba(255,150,60,.4);text-decoration:none}
.btn:disabled{opacity:.45;cursor:default} .btn.sec{background:transparent;color:var(--mint);border:1.5px solid var(--mint);box-shadow:none}
/* layout blocks */ .btn.sec:hover{box-shadow:0 6px 22px rgba(61,232,168,.22)}
.hero{padding:64px 0 40px} .btn.small{padding:8px 16px;font-size:13.5px}
.hero h1{font-size:clamp(30px,5.5vw,50px);line-height:1.08;margin:0 0 14px;max-width:640px} .btn:disabled{opacity:.45;cursor:default;transform:none;box-shadow:none}
.hero h1 em{color:var(--mint);font-style:normal} /* hero */
.hero p.lead{color:var(--muted);font-size:18px;max-width:560px;margin:0 0 26px} .hero{padding:76px 0 40px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px;margin:0 0 16px} .eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.22em;text-transform:uppercase;color:var(--mint);margin:0 0 14px}
.hero h1{font-size:clamp(32px,5.6vw,58px);font-weight:800;line-height:1.06;margin:0 0 18px;max-width:720px;text-wrap:balance}
.hero h1 em{font-style:normal;background:linear-gradient(95deg,var(--mint),var(--cyan) 55%,var(--violet));
-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p.lead{color:var(--muted);font-size:19px;max-width:600px;margin:0 0 30px}
.hero p.lead b{color:var(--ink)}
/* live counter band — real chain numbers only */
.stats{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin:38px 0 8px}
@media(min-width:760px){.stats{grid-template-columns:repeat(4,1fr)}}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:18px 20px;
backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.stat .n{font-family:var(--disp);font-size:30px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--mint)}
.stat .l{font-size:12.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
.stat .sub{font-size:11.5px;color:var(--muted)}
/* cards / grids */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:22px;margin:0 0 16px;
backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.card:hover{border-color:var(--line-strong)}
.grid{display:grid;gap:16px} .grid{display:grid;gap:16px}
@media(min-width:760px){.grid.c3{grid-template-columns:1fr 1fr 1fr}.grid.c2{grid-template-columns:1fr 1fr}} @media(min-width:760px){.grid.c3{grid-template-columns:1fr 1fr 1fr}.grid.c2{grid-template-columns:1fr 1fr}}
h2{font-size:24px;margin:36px 0 14px} h2{font-size:clamp(22px,3vw,30px);font-weight:800;margin:52px 0 16px;text-wrap:balance}
h3{font-size:17px;margin:0 0 8px} h3{font-size:17px;margin:0 0 8px;font-weight:700}
.muted{color:var(--muted)} .muted{color:var(--muted)}
.small{font-size:13.5px} .small{font-size:13.5px}
.mono{font-family:var(--mono)} .mono{font-family:var(--mono)}
/* ticker: live money marquee */
.ticker{overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
background:rgba(61,232,168,.05);white-space:nowrap;padding:9px 0;margin:26px 0 0}
.ticker .inner{display:inline-block;font-family:var(--mono);font-size:13px;color:var(--mint);padding-left:100%;
animation:tick 40s linear infinite}
.ticker .inner span{margin-right:44px;color:var(--muted)}
.ticker .inner span b{color:var(--mint);font-weight:600}
@keyframes tick{to{transform:translateX(-100%)}}
@media(prefers-reduced-motion:reduce){.ticker .inner{animation:none;padding-left:0}}
/* ladder table */ /* ladder table */
table{width:100%;border-collapse:collapse;font-size:15px} table{width:100%;border-collapse:collapse;font-size:15px}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:middle} th,td{text-align:left;padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
th{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:1px} th{color:var(--muted);font-size:11.5px;text-transform:uppercase;letter-spacing:.1em;font-family:var(--disp)}
td.num,th.num{font-variant-numeric:tabular-nums} td.num,th.num{font-variant-numeric:tabular-nums}
tr:last-child td{border-bottom:0} tr:last-child td{border-bottom:0}
.tablewrap{overflow-x:auto} .tablewrap{overflow-x:auto}
/* ledger feed */ /* ledger feed */
.feed{font-family:var(--mono);font-size:13.5px;line-height:1.7} .feed{font-family:var(--mono);font-size:13.5px;line-height:1.7}
.feed .row{padding:7px 10px;border-bottom:1px solid var(--line);display:flex;gap:10px;align-items:baseline;flex-wrap:wrap} .feed .row{padding:8px 12px;border-bottom:1px solid var(--line);display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.feed .row:first-child{background:var(--mint-soft)} .feed .row:first-child{background:var(--mint-soft)}
.feed .t-Purchase{color:var(--amber)} .feed .t-Purchase{color:var(--amber)}
.feed .t-TierPaid{color:var(--mint)} .feed .t-TierPaid{color:var(--mint)}
.feed .t-AdminPaid{color:var(--muted)} .feed .t-AdminPaid{color:var(--muted)}
.feed .t-AwardPaid{color:var(--amber)} .feed .t-AwardPaid{color:var(--amber)}
.feed .tx a{color:var(--muted);font-size:12px} .feed .tx a{color:var(--muted);font-size:12px}
.badge{display:inline-block;background:var(--mint-soft);color:var(--mint);border-radius:10px;padding:2px 10px;font-size:12.5px;font-weight:700} .badge{display:inline-block;background:var(--mint-soft);color:var(--mint);border:1px solid rgba(61,232,168,.3);
.badge.amber{background:#3c2f10;color:var(--amber)} border-radius:999px;padding:2px 12px;font-size:12.5px;font-weight:700}
/* split diagram strip */ .badge.amber{background:rgba(255,178,56,.1);border-color:rgba(255,178,56,.35);color:var(--amber)}
.split{display:flex;gap:8px;margin:14px 0} /* split strip */
.split div{border-radius:8px;padding:10px 6px;text-align:center;font-size:12.5px;font-weight:700} .split{display:flex;gap:8px;margin:16px 0}
.split .s50{flex:5;background:var(--mint-soft);color:var(--mint)} .split div{border-radius:10px;padding:13px 6px;text-align:center;font-size:12.5px;font-weight:700;font-family:var(--disp)}
.split .s20{flex:2;background:#173347;color:#6cc4ee} .split .s50{flex:5;background:var(--mint-soft);color:var(--mint);border:1px solid rgba(61,232,168,.3);
.split .s10{flex:1;background:#2c2440;color:#b39df1} box-shadow:0 0 24px rgba(61,232,168,.12)}
.split .sa{flex:2;background:#33290f;color:var(--amber)} .split .s20{flex:2;background:rgba(92,200,238,.09);color:var(--cyan);border:1px solid rgba(92,200,238,.3)}
/* status line + toasts */ .split .s10{flex:1;background:rgba(139,108,246,.1);color:var(--violet);border:1px solid rgba(139,108,246,.3)}
#status{position:fixed;left:50%;transform:translateX(-50%);bottom:22px;background:var(--panel2); .split .sa{flex:2;background:rgba(255,178,56,.08);color:var(--amber);border:1px solid rgba(255,178,56,.28)}
border:1px solid var(--line);border-radius:12px;padding:12px 20px;font-size:14px;max-width:90vw; /* FAQ accordions */
box-shadow:0 8px 30px rgba(0,0,0,.5)} details{border:1px solid var(--line);border-radius:12px;margin:0 0 10px;background:var(--panel)}
summary{cursor:pointer;padding:14px 18px;font-weight:700;font-family:var(--disp);font-size:15px}
details p{margin:0;padding:0 18px 16px;color:var(--muted);font-size:14.5px}
/* status toast */
#status{position:fixed;left:50%;transform:translateX(-50%);bottom:22px;background:var(--panel-solid);
border:1px solid var(--line-strong);border-radius:14px;padding:13px 22px;font-size:14px;max-width:90vw;z-index:30;
box-shadow:0 12px 40px rgba(0,0,0,.55)}
#status.ok{border-color:var(--mint)} #status.ok{border-color:var(--mint)}
#status.bad{border-color:var(--bad)} #status.bad{border-color:var(--bad)}
footer{border-top:1px solid var(--line);margin-top:60px;padding:26px 0;color:var(--muted);font-size:13.5px} footer{border-top:1px solid var(--line);margin-top:70px;padding:30px 0;color:var(--muted);font-size:13.5px}
input,select{background:var(--ground);border:1px solid var(--line);color:var(--ink);border-radius:8px; input,select{background:rgba(7,11,22,.6);border:1px solid var(--line-strong);color:var(--ink);border-radius:10px;
padding:10px 12px;font-size:14.5px;font-family:inherit} padding:11px 14px;font-size:14.5px;font-family:inherit}
input:focus,select:focus{border-color:var(--mint)}
:focus-visible{outline:2px solid var(--mint);outline-offset:2px} :focus-visible{outline:2px solid var(--mint);outline-offset:2px}
@media(prefers-reduced-motion:no-preference){ @media(prefers-reduced-motion:no-preference){
.feed .row:first-child{animation:landed .9s ease} .feed .row:first-child{animation:landed .9s ease}
@keyframes landed{from{background:#1d5c44}to{background:var(--mint-soft)}} @keyframes landed{from{background:rgba(61,232,168,.28)}to{background:var(--mint-soft)}}
} }
+62 -2
View File
@@ -4,11 +4,13 @@
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>InstantAdPay: advertise and earn, locked in code</title> <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."> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css"> <link rel="stylesheet" href="/assets/site.css">
</head> </head>
<body> <body>
<div class="wrap"> <div class="wrap">
<section class="hero"> <section class="hero">
<p class="eyebrow">Advertising · settled on-chain · instantly</p>
<h1>Advertise and earn. <em>Locked in code, not promises.</em></h1> <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 <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 a smart contract you can read yourself, and your earnings land in
@@ -18,8 +20,21 @@
<a class="btn sec" href="/ledger">Watch payments land live</a> <a class="btn sec" href="/ledger">Watch payments land live</a>
</p> </p>
<p class="small muted" id="sponsorLine" hidden></p> <p class="small muted" id="sponsorLine" hidden></p>
</section>
<div class="stats">
<div class="stat"><div class="n" id="stMembers">–</div><div class="l">On-chain members</div></div>
<div class="stat"><div class="n" id="stPurchases">–</div><div class="l">Packages bought</div></div>
<div class="stat"><div class="n" id="stPaid">–</div><div class="l">POL settled through</div></div>
<div class="stat"><div class="n" id="stPayouts">–</div><div class="l">Instant payouts delivered</div></div>
</div>
<p class="small muted">Every number above comes from the blockchain, not a marketing database.
Click any line on the <a href="/ledger">live ledger</a> to verify it yourself.</p>
</section>
</div>
<div class="ticker" hidden id="ticker"><div class="inner" id="tickerInner"></div></div>
<div class="wrap">
<h2>Where every dollar goes</h2> <h2>Where every dollar goes</h2>
<div class="card"> <div class="card">
<div class="split"> <div class="split">
@@ -49,7 +64,7 @@
up to the next qualified person automatically. The contract handles it.</p></div> up to the next qualified person automatically. The contract handles it.</p></div>
</div> </div>
<h2>The ad packages</h2> <h2 id="ladder-h">The ad packages</h2>
<div class="card"> <div class="card">
<div class="tablewrap"> <div class="tablewrap">
<table id="ladder"> <table id="ladder">
@@ -62,6 +77,16 @@
Packages of $20 or more count toward your sponsor's qualification.</p> Packages of $20 or more count toward your sponsor's qualification.</p>
</div> </div>
<h2>What your credits buy</h2>
<div class="grid c3">
<div class="card"><h3>Display banners</h3><p class="muted small">All standard sizes, served across the network. Per impression.</p><span class="badge">live</span></div>
<div class="card"><h3>Text ads</h3><p class="muted small">Headline plus one line, placed where members actually look. Per impression.</p><span class="badge">live</span></div>
<div class="card"><h3>Login ads</h3><p class="muted small">Full attention at sign-in, priced per day.</p><span class="badge">live</span></div>
<div class="card"><h3>Inbox ads</h3><p class="muted small">Delivered on-site, and viewers earn credits for reading.</p><span class="badge amber">shipping soon</span></div>
<div class="card"><h3>Featured rotation</h3><p class="muted small">Your link in the featured rotation for 1, 2, or 7 days. We show you exactly how many links share it before you buy.</p><span class="badge amber">shipping soon</span></div>
<div class="card"><h3>Verified visits</h3><p class="muted small">Buy a guaranteed count of verified unique visits. No bots, no recycled clicks.</p><span class="badge amber">shipping soon</span></div>
</div>
<h2>Why this is different</h2> <h2>Why this is different</h2>
<div class="grid c2"> <div class="grid c2">
<div class="card"><h3>No trust required. Your earnings are a transaction to your wallet.</h3> <div class="card"><h3>No trust required. Your earnings are a transaction to your wallet.</h3>
@@ -76,6 +101,41 @@
code does: split the money and pay it out. That is it.</p></div> code does: split the money and pay it out. That is it.</p></div>
</div> </div>
<h2>Questions people actually ask</h2>
<div id="faq">
<details><summary>Is this a pyramid or ponzi scheme?</summary>
<p>No, and here is the plain version of why. A pyramid scheme pays you just for recruiting, with no
real product behind it. Here every payment is for ad delivery, and the payouts only come from real
buyers who buy real ad packages. You earn from people actually advertising, not from building a chain
of signups. The whole thing runs on a public ledger you can verify yourself, so nothing stays hidden.</p></details>
<details><summary>What happens if the company disappears?</summary>
<p>The important part is that there is no company holding the money. Every sale is split by the smart
contract itself, on the blockchain, in the same transaction. Nobody can pause it, change it, or run
off with the funds, because the code does the paying automatically. If the site vanished tomorrow,
the contract would keep paying exactly what it is set to pay.</p></details>
<details><summary>Do I need crypto experience or a wallet to join?</summary>
<p>No. You can start with a free email signup and use the platform the same way you would use any ad
site. If you want payouts to a wallet, setting one up takes a few minutes and the platform walks you
through it. But you do not need to know anything about crypto to get in and get moving.</p></details>
<details><summary>How fast do I really get paid?</summary>
<p>Payouts happen inside the very transaction that pays for the package. There is no approval step
and nobody holding funds. Your share lands in your own wallet the moment your referral's purchase
confirms. The public ledger lets you watch each one go through.</p></details>
<details><summary>What am I actually buying?</summary>
<p>You are buying ad delivery. Credits are one cent of delivery each, recorded on-chain when you buy.
The 5 dollar package mints 500 credits, and the bigger packages mint bonus credits on top, up to
32,500 on the 250 dollar package. That is the product, plain and simple. Your earnings come from
referring people who also buy real ad delivery, and the contract splits every purchase automatically.</p></details>
</div>
<div class="card" style="text-align:center;padding:40px 22px">
<h2 style="margin:0 0 10px">See a payment land before you decide.</h2>
<p class="muted" style="max-width:520px;margin:0 auto 22px">The ledger is open to everyone.
Watch real purchases split and settle, then join free when you have seen enough.</p>
<a class="btn" href="/my">Join free</a>
<a class="btn sec" href="/ledger">Open the live ledger</a>
</div>
<footer> <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>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>
+1
View File
@@ -4,6 +4,7 @@
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <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."> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css"> <link rel="stylesheet" href="/assets/site.css">
</head> </head>
<body> <body>
+1
View File
@@ -3,6 +3,7 @@
<head> <head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css"> <link rel="stylesheet" href="/assets/site.css">
</head> </head>
<body> <body>
+2 -2
View File
@@ -43,7 +43,7 @@ function siteConfig() {
const MIME = { '.html': 'text/html; charset=utf-8', '.css': 'text/css', '.js': 'text/javascript', const MIME = { '.html': 'text/html; charset=utf-8', '.css': 'text/css', '.js': 'text/javascript',
'.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml', '.webp': 'image/webp', '.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml', '.webp': 'image/webp',
'.ico': 'image/x-icon', '.json': 'application/json', '.mp4': 'video/mp4', '.woff2': 'font/woff2' }; '.ico': 'image/x-icon', '.json': 'application/json', '.mp4': 'video/mp4', '.woff2': 'font/woff2' };
const CSP = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self' data:; form-action 'self'"; const CSP = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; connect-src 'self'; font-src 'self' data: https://fonts.gstatic.com; form-action 'self'";
function baseHeaders(extra) { function baseHeaders(extra) {
return Object.assign({ 'Content-Security-Policy': CSP, 'X-Content-Type-Options': 'nosniff', return Object.assign({ 'Content-Security-Policy': CSP, 'X-Content-Type-Options': 'nosniff',
'Referrer-Policy': 'strict-origin-when-cross-origin' }, extra || {}); 'Referrer-Policy': 'strict-origin-when-cross-origin' }, extra || {});
@@ -135,7 +135,7 @@ const server = http.createServer(async (req, res) => {
} }
if (p === '/api/stats' && req.method === 'GET') { if (p === '/api/stats' && req.method === 'GET') {
let members = 0; try { members = await chain.memberCount(); } catch (e) {} let members = 0; try { members = await chain.memberCount(); } catch (e) {}
return json(res, 200, { onchainMembers: members, siteAccounts: accounts.count() }); return json(res, 200, Object.assign({ onchainMembers: members, siteAccounts: accounts.count() }, chain.totals()));
} }
// -- accounts: email + password is the normal join path (wallet comes // -- accounts: email + password is the normal join path (wallet comes