diff --git a/ads.js b/ads.js index 966a093..01546ad 100644 Binary files a/ads.js and b/ads.js differ diff --git a/chatbot.js b/chatbot.js index 7aaae8e..05e969a 100644 --- a/chatbot.js +++ b/chatbot.js @@ -38,7 +38,7 @@ const CANNED = [ { re: /((view|watch|see).{0,12}ads?|earn.{0,12}credits?|daily (set|ads|views))/i, a: 'In the Earn credits section of Members, each ad in the daily set opens full screen in its own tab, showing the advertiser\'s real site. A countdown runs while you watch (it pauses if you leave the tab), then you pass a quick click-the-icon check and the view counts. Finish the set, claim your daily credits, and spend them on your own banner or text campaigns. You never see your own ads, and viewer rewards are credits, never cash.' }, { re: /(credit|impression|cpm|what do i get|what am i buying)/i, - a: 'Packages mint ad credits on-chain, and every new member also gets a small batch of welcome credits just for joining. One credit is one cent of ad delivery: banners, text ads, and login ads across the network, managed from the campaign manager in Members. Only your campaigns can spend your credits.' }, + a: 'Packages mint ad credits on-chain, and every new member also gets a small batch of welcome credits just for joining. One credit is one cent of ad delivery: banners, text ads, full-screen login ads, and solo ads across the network, managed from the campaign manager in Members. Only your campaigns can spend your credits.' }, { re: /(price|cost|package|how much is)/i, a: 'Packages run 5 to 250 dollars, priced in dollars and settled in POL at the live rate when you buy. The full ladder with live pricing is on the home page. Packages of $20 or more count toward qualification.' }, { re: /(safe|trust|rug|run away|company disappear)/i, @@ -52,7 +52,7 @@ function systemPrompt() { FACTS: - Free to join with email only (6-digit code sign-in, no passwords). Wallet appears only at purchase or payout activation. Every new member gets a small welcome batch of ad credits at signup (engine-side bonus credits, separate from on-chain purchased credits). - Ad packages: Micro $5/500 credits, Activation $20/2,000, Builder $50/5,500, Growth $100/12,000, Leader $250/32,500. Dollar-priced, settled in POL (Polygon) at the live Chainlink rate. 1 credit = 1 cent of ad delivery. -- Live formats: display banners (per impression), text ads (per impression), login ads (per day). Coming: inbox ads, featured rotation with disclosed rotation size, verified-visit packs. +- Live formats: display banners (per impression), text ads (per impression), full-screen LOGIN ADS (per day: right after a member signs in they land on a sponsor interstitial — they click "Open Ad", the advertiser's page opens in a NEW tab, a countdown runs on the interstitial, and at zero a "Go to dashboard" button appears. Just a CTA link is enough; an optional banner image can be the clickable creative. No framing requirement since it opens in its own tab), and solo ads. Coming: featured rotation with disclosed rotation size, verified-visit packs. - Members EARN credits by attention: in the Earn credits section of Members, each ad in the daily set opens FULL SCREEN in its own tab, showing the advertiser's real website. A countdown runs while you watch (it pauses if you leave the tab), then a quick human check (click the named icon) must be passed before the view counts. Finish the daily set, claim a small daily credit batch. Earned credits spend on banner and text campaigns; attention earns advertising, referrals earn money, and viewer rewards are never cash. Advertisers get real, verified visits to their site. - Onsite SOLO ADS are live: a solo ad is a full message (subject + up to 2000 characters of formatted text + your link) delivered into members' on-site Inbox (Members > Inbox). The composer in Campaigns > Solo ad has a rich-text editor (bold, headings, lists, links), lets you ATTACH one image (PNG/JPG/WebP/GIF, up to 3MB) or one video (MP4/WebM, up to 25MB), and adds a call-to-action button with a custom label that opens the target URL. Cost 5 credits per guaranteed delivery, minimum 10 deliveries (50 credits). Each member receives a given solo at most once, and never the sender's own. Readers earn 2 credits per real read (10-second dwell on the open message, up to 5 rewarded reads/day) — claimed right from the message. Compose one in Campaigns > Solo ad. - Campaign target URLs are checked the moment they are submitted: the page must be reachable and must ALLOW framing (no X-Frame-Options deny/sameorigin, no blocking CSP frame-ancestors), because surf views show the real site full screen. Frame-blocking or dead URLs are rejected with the exact reason; the fix is a landing page that allows framing. Login-ad targets skip the frame check (they are click-through only). diff --git a/public/assets/my.js b/public/assets/my.js index c27d5cc..c902035 100644 --- a/public/assets/my.js +++ b/public/assets/my.js @@ -372,7 +372,7 @@ }); $('cType').addEventListener('change', () => { const t = $('cType').value; - $('cImageRow').hidden = t === 'text' || t === 'solo'; + $('cImageRow').hidden = t !== 'banner'; // only banners carry a creative; login frames its URL $('cTitleRow').hidden = t !== 'text' && t !== 'solo'; $('cBodyRow').hidden = t !== 'text'; $('cSoloRow').hidden = t !== 'solo'; @@ -644,6 +644,7 @@ $('mcVerifyBtn').addEventListener('click', busy($('mcVerifyBtn'), async () => { await api('/api/auth/email/verify', { email: $('mcEmail').value, code: $('mcCode').value }); IAP.status('You are in.', 'ok'); + await showLoginAd(); await render(); })); })(); @@ -656,6 +657,7 @@ $('loginBtn').addEventListener('click', busy($('loginBtn'), async () => { await api('/api/login', { email: $('liEmail').value, password: $('liPass').value }); IAP.status('Logged in.', 'ok'); + await showLoginAd(); await render(); })); $('walletSigninLink').addEventListener('click', async e => { @@ -664,6 +666,7 @@ IAP.status('Check your wallet for the free sign-in signature…'); await IAPWallet.signIn(); IAP.status('Signed in with your wallet.', 'ok'); + await showLoginAd(); await render(); } catch (err) { IAP.status((err && err.message) || String(err), 'bad'); } }); @@ -692,9 +695,55 @@ await render(); }); - // ad surfaces: login ads greet the sign-in screen; members see live + // ── login ad interstitial (ClickBaitPays pattern): after a successful + // sign-in the sponsor card appears; "Open Ad" opens the CTA link in a NEW + // tab (a real, counted click) while the timer counts down on THIS page — + // deliberately not paused, the member is expected to be in the ad tab. + // At zero, "Go to dashboard" appears. + async function showLoginAd() { + try { + const { ad } = await (await fetch('/api/ads/slot?type=login')).json(); + if (!ad || !ad.targetUrl) return; + const gate = $('loginGate'); + const openBtn = $('lgOpen'); + const goBtn = $('lgContinue'); + const timer = $('lgTimer'); + $('lgCreative').innerHTML = ad.imageUrl + ? 'sponsor ad' + : '' + (ad.title ? String(ad.title).replace(/[&<>]/g, '') : 'Visit today\'s sponsor') + ''; + $('lgStatus').textContent = 'Login ad sponsor — click "Open Ad" to begin.'; + timer.hidden = true; + goBtn.hidden = true; + openBtn.disabled = false; + gate.hidden = false; + await new Promise(done => { + openBtn.onclick = () => { + window.open(ad.targetUrl, '_blank'); // the click relay counts it + openBtn.disabled = true; + $('lgStatus').textContent = 'Ad open in a new tab. View it and come back — the timer runs here.'; + let left = ad.dwell || 10; + timer.hidden = false; + timer.textContent = 'Time remaining: ' + left + 's'; + const t = setInterval(() => { + left -= 1; + if (left > 0) { timer.textContent = 'Time remaining: ' + left + 's'; return; } + clearInterval(t); + timer.textContent = 'Time is up'; + timer.classList.add('done'); + $('lgStatus').textContent = 'Thanks for the look. Your dashboard is ready.'; + goBtn.hidden = false; + }, 1000); + goBtn.onclick = () => done(); + }; + }); + gate.hidden = true; + $('lgTimer').classList.remove('done'); + } catch (e) {} + } + + // ad surfaces: a banner greets the sign-in screen; members see live // banner + text placements inside the back office (they ARE the audience) - IAP.adSlot('login', 'adSlotLogin'); + IAP.adSlot('banner', 'adSlotLogin'); IAP.adSlot('banner', 'adSlotOverview'); IAP.adSlot('text', 'adSlotSide'); diff --git a/public/assets/site.css b/public/assets/site.css index 1c1d1d3..4db8298 100644 --- a/public/assets/site.css +++ b/public/assets/site.css @@ -295,6 +295,21 @@ textarea{resize:vertical;font:inherit} .donut-legend{display:flex;flex-direction:column;gap:8px;font-size:13px} .donut-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:8px} .donut-center{font-family:var(--disp);font-weight:800} +/* ── login ad interstitial: sponsor opens in a new tab, timer runs here ── */ +.lgate{position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;background:var(--ground)} +.lgate-bar{display:flex;align-items:center;gap:14px;padding:10px 16px;background:var(--panel-solid); + border-bottom:1px solid var(--line);flex-wrap:wrap} +.lg-brand{font-family:var(--disp);font-weight:800;font-size:15px;white-space:nowrap} +.lg-brand em{color:var(--mint);font-style:normal} +.lgate-note{flex:1;min-width:140px} +.lg-timer{font-weight:700;font-size:14px;border:1px solid var(--line-strong);border-radius:999px; + padding:5px 14px;min-width:150px;text-align:center} +.lg-timer.done{color:var(--mint);border-color:var(--mint)} +.lgate-body{flex:1;display:grid;place-items:center;padding:24px;overflow:auto} +.lgate-card{max-width:560px;text-align:center} +.lgate-card img{max-width:100%;max-height:50vh;border-radius:12px;border:1px solid var(--line-strong)} +#lgCreative .lg-linkcard{display:inline-block;background:var(--panel);border:1px solid var(--line-strong); + border-radius:14px;padding:22px 28px;font-family:var(--disp);font-weight:700;font-size:18px;overflow-wrap:anywhere} /* ── solo composer: toolbar + contenteditable editor ── */ .ed-bar{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px} .ed-bar button{background:var(--panel);color:var(--ink);border:1px solid var(--line-strong);border-radius:8px; diff --git a/public/index.html b/public/index.html index f3d71f3..6597460 100644 --- a/public/index.html +++ b/public/index.html @@ -221,7 +221,9 @@

Login ads live

-

Full attention at sign-in, priced per day. The member is already engaged before they do anything else.

+

The moment a member signs in, your ad is the toll gate: they open your page in a fresh tab + while a countdown holds their dashboard. Just a link is enough — add a banner if you have + one. Priced per day.

diff --git a/public/my.html b/public/my.html index 4802321..3297089 100644 --- a/public/my.html +++ b/public/my.html @@ -4,7 +4,7 @@ Member area | InstantAdPay - + @@ -48,6 +48,25 @@
+ + +

Banner and text targets are shown full screen in the - ad viewer, so the URL must allow framing — we check it the moment you submit.

+ ad viewer, so those URLs must allow framing — we check them the moment you submit. Login and + solo links open in a fresh tab, so any working page is fine.

@@ -379,9 +399,9 @@ - - - - + + + + diff --git a/public/view.html b/public/view.html index dad4ef7..1c66394 100644 --- a/public/view.html +++ b/public/view.html @@ -4,7 +4,7 @@ Viewing ad — InstantAdPay - +