Commit Graph

155 Commits

Author SHA1 Message Date
martbost 0c803c07cb Legal pages (Terms, Privacy, Disclaimer) + always-present footer
- New /terms, /privacy, /disclaimer pages in the site style with real content
  tailored to an on-chain ad+referral platform (no income guarantee, crypto
  risk, rehearsal note, privacy of email/wallet/profile, acceptable use).
- renderNav now appends a persistent footer with legal + site links on every
  public page; member-area sidebar gets a Legal link group.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 09:38:08 -05:00
martbost 8e089070dc Recolor achievement badges: Surge purple, Circuit red starburst, Nexus navy
New kie.ai art per Marty's palette — Surge dark neon purple, Circuit bright red
starburst, Nexus navy-blue gradient (Spark stays mint). Full-bleed dark, ornate,
blank ribbon; ribbonY re-tuned per badge; ?v=2 cache-bust on the badge images.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 09:03:45 -05:00
martbost ae580b966c 125x125 sidebar banner (sized ad serving) + shorts report link
- New 125x125 "square button" banner size; ad serve now filters by width/height,
  and the sidebar slot serves a 125x125 banner (empty until such inventory exists).
- Shorts reel gets a "report this short" link (posts to /api/report-ad).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:47:17 -05:00
martbost 31a6560e9e Training center: new members-area pane for videos + materials
New "Training" nav pane lists curated lessons (inline video for mp4/webm, links
for external videos and docs) from /api/training (admin-curated via
data/training.json, with a sensible default).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:41:26 -05:00
martbost 0dbd99f69e Wall page: mint QR, achievement badge, admin-ad backfill, join gated on views
- QR is mint-green (still high-contrast for reliable scanning).
- The wall shows the owner's achievement badge next to their avatar.
- Positions 2 & 3 fill with upline line-banners, then ADMIN ADS when there's no
  upline (configurable via data/admin-wall-ads.json; sensible default) so the
  wall is never sparse.
- "Join free through this wall" is disabled until the visitor has viewed every
  ad on the wall, with a "X/Y viewed" prompt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:35:44 -05:00
martbost a4119d652d Sponsor shown on sign-in + new-member onboarding (username, optional profile)
- Sign-in page shows "You're joining the line of @X" when arriving via a sponsor
  link (/api/sponsor now returns the sponsor name + avatar).
- After a new account verifies (or signs up) with no username yet, an onboarding
  modal prompts for a username and an optional bio (both skippable), before the
  welcome tour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:29:12 -05:00
martbost 4a9e4c789e Daily login bonus (streak) + solo-ad budget default
- Daily login bonus: once/day, base 5 credits + gentle streak (+1/day, cap +5)
  for consecutive days; granted after sign-in, toast + cha-ching. New
  login_day/login_streak on earned_credits; /api/my/login-bonus.
- Solo ad: selecting Solo now defaults Budget to 50 credits (5cr x 10 min
  deliveries) so entering 10 isn't rejected after submit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:19:40 -05:00
martbost a8968041dc Email notifications (welcome + payout + passed-up) and net->network label
- Welcome email on new account: onboarding steps + who their sponsor is.
- On-chain event emails: a payout received (TierPaid/AwardPaid) and a payout
  that passed you by unqualified (PassedUp), wired into the chain event stream.
- Campaign stats: "+N net" relabeled to "+N network" (clearer than "net").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:15:28 -05:00
martbost 19b7770a4d Video once-per-day dedup + featured gold border & spacing
- Video watch-to-earn: a member can no longer re-earn from the same video the
  same day. New video_seen table (dual-mode); serveVideo excludes today's
  already-watched videos; videowatch double-checks before crediting.
- Featured card: equal top/bottom margin (no longer touches the stat cards) and
  a gold border on the card + the rotating link.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 08:13:09 -05:00
martbost 3a6d9d037c Ad-report admin recipient via ADMIN_EMAIL env only (siteConfig is public)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:59:26 -05:00
martbost 4991fe96e8 Ad reporting + featured rotates one link + clear campaign form on submit
- Ad reporting (auto-approved ads need a safety valve): new reports.js store
  (dual-mode) + ad_reports table + POST /api/report-ad; a "⚠ report" control on
  served ad slots opens a reason prompt and notifies the admin by email
  (siteConfig.adminEmail / ADMIN_EMAIL).
- Featured links now show ONE link at a time and cycle (true rotation), instead
  of listing all links at once.
- Campaign form now clears EVERY field on submit (target/creative/title/etc.).
  A leftover target URL was carrying into the next campaign — the same reason a
  video short was saved with the wrong (massifly) CTA target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:57:12 -05:00
martbost 958bd5ac20 Live members-area updates: SSE toasts + cha-ching/pop sounds, no refresh needed
- The members area subscribes to the chain event stream (/api/feed/live) and
  reacts to anything relevant to the member: a payout received (cha-ching + toast
  + auto-refresh), a referral qualifying, a passed-up payout (missed), a settled
  purchase, a new activation in the line. No page refresh required.
- New chat message -> "pop" sound + toast + badge; ping heartbeat (20s) now
  returns chatUnread and pops on an increase.
- Sounds are synthesized via Web Audio (no asset files, CSP-safe).
- Surge badge: nudge the name down (ribbonY .779 -> .805) to center on its ribbon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:36:47 -05:00
martbost 1363bd7b0b Fix: buy links wallet first; achievement milestones use live buyerCount
- Buying now ensures the wallet is LINKED to the account before the purchase
  (one signature if not linked). Without it, a wallet only connected for the
  faucet bought successfully but credits resolved against member id 0 and never
  showed until a manual link. Matches the "buying links your wallet" promise.
- Dashboard computed achievement milestones from buyerCount BEFORE reading it
  from chain (always 0), so Surge/Circuit/Nexus never unlocked even when
  qualification advanced. Moved the milestone block after the chain read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:24:26 -05:00
martbost 204aa6a723 Rehearsal faucet: self-serve test-POL so members can actually buy
Fresh wallets hold 0 POL on the rehearsal chain, so nobody could complete a buy.
- Oracle: the mock POL/USD feed had gone ~49h stale (quoteWei reverted "Stale
  oracle" -> catalog costWei null -> packages showed "paused"). Refreshed it and
  installed a 15-min heartbeat cron so it stays fresh; quotes now return.
- New /api/my/faucet (rehearsal-only, rate-limited) tops a connected wallet up to
  10 test-POL via anvil_setBalance (no key). "Get test POL" card in the Wallet
  pane wires it. Members can now fund, buy, and see payouts move on the ledger.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:02:48 -05:00
martbost 41d3293486 Fix referral attribution (username joins) + broadcast rate-limit regression
- Dashboard "Your line" roster now matches referrals joined under the member's
  USERNAME link (invite link is /join/<username>), not just code + member id —
  username joins were invisible.
- lastBroadcastAt now counts only kind='broadcast'. Chat rides the same table,
  so chatting had been tripping the once-a-day broadcast limit ("try again in
  24h" on the first broadcast).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 06:38:27 -05:00
martbost 5b1a60f653 Fix profile persistence + badge ribbon alignment; 24h sessions
- BUG: /api/me never returned avatarUrl/bio/socials/lineBanner fields, so the
  Profile pane repopulated empty on reload — data WAS saved, just not surfaced.
  Now returned so avatar, bio, and social links persist visibly.
- Achievement badge: member name drops the "@" and sits on a per-badge ribbonY
  (spark .728 / surge .779 / circuit .713 / nexus .709), gold with dark outline.
- Sessions now expire in 24h (was 30d) so members re-login daily and see the
  login ad each day.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 06:13:19 -05:00
martbost a634f83a8e Shorts = portrait-only reel; Watch videos = landscape; badge name in gold
- Videos now carry client-detected pixel dimensions (videoW/videoH) captured at
  campaign create (upload or direct link). serveVideo takes an orientation filter:
  Shorts reel (/shorts) serves portrait (height>width); the Watch videos tab
  serves landscape, including legacy/unknown-dimension videos so nothing is orphaned.
- shorts.js requests the portrait feed and has a client guard that skips any
  landscape video that slips through. Create form shows the detected orientation.
- Achievement badge share image: member name now renders in gold with a dark
  outline (was low-contrast dark ink) and sits centered on the ribbon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 05:41:17 -05:00
martbost ade0a13064 Sponsor Chat: two-way member<->sponsor messaging (presence, availability, mute)
Evolves the one-way broadcast into real support threads, keeping broadcast alongside.
- messages.js: kind='chat' rides sponsor_messages; sendChat/thread/threadList/
  markChatRead/chatUnread; broadcast inbox + login modal scoped to kind='broadcast'
- accounts.js: presence (last_seen), chat availability toggle, per-member mutes;
  sponsorOf() + isDownlineOf() resolvers
- server.js: /api/my/chat/{send,thread,threads,available,mute} + /api/my/ping
  heartbeat; dashboard emits chatUnread/chatAvailable/sponsor; auth = direct
  sponsor up, any downline down, or an existing thread; email only when offline
  and not mid-chat
- my.html/my.js/site.css: slide-in chat drawer (threads list + live thread,
  4s poll), presence dot, Message buttons on direct rows, Message-my-sponsor
  quick action, availability switch in Profile
- db.js: additive migrations (kind, pair index, chat_available, chat_mutes)
- chatbot.js: canned answer + AI fact for Sponsor Chat

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 05:24:23 -05:00
martbost 3c0e94f20f Badge emblems, profile social links, and SEO/OG social previews
- Achievement badge share-image now draws a milestone emblem (⚡🎯⭐🏆) in the medal
- Profile: Facebook/X/YouTube/Instagram/TikTok/Telegram/LinkedIn/Website links, shown on the public bio page
- OG + Twitter Card tags on homepage/ledger/contract (hero banner as share image)
- Per-member OG tags server-injected into /wall/<username> so shared bio links preview with name/bio/avatar
- robots.txt + sitemap.xml; .txt/.xml MIME types

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 12:21:53 -05:00
martbost 2f27038297 DO Spaces enabled: namespace IAP video uploads under iap-uploads/ in the shared media bucket
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:51:43 -05:00
martbost 537e7352d4 DO Spaces adapter (feature-flagged): route video uploads to object storage off the volume
- spaces.js: zero-dep SigV4 PUT to DO Spaces, public-read; inert unless DO_SPACES_* env is set
- /api/my/upload sends video to Spaces when configured, falls back to volume otherwise
- Images stay local; Spaces URLs are https so they pass the video/media validators + CSP

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:24:48 -05:00
martbost cb2542fca5 Verified visits (7th ad format): guaranteed unique human-visit packs
- Buy N verified visits flat up-front; each is a distinct member, dwell + captcha verified
- Verified visits earn sub-tab: open site (new tab), dwell, human-check, earn
- Per-viewer dedup (visit_seen unique), daily cap, completes at N; single-use tokens

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:21:59 -05:00
martbost f30a462ca8 Featured rotation -> day-slot booking: 10 slots/day, pick your start day, live occupancy
- Per-day occupancy shown in composer (Today 1/10, Tomorrow 2/10, …), full days unpickable
- Book a specific start day + duration; every covered day must have an open slot
- Slot cap turns dilution disclosure into a hard ceiling; featured skips frame-check (new-tab)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:16:24 -05:00
martbost c5dd5c685b Paid shorts: full-screen vertical video feed over the video inventory, earn per watched short
- /shorts page: no-seek full-screen player, server-clock watch, credit + swipe to next
- Reuses /api/my/videos + /api/my/videowatch (same fraud model, daily cap, self-exclusion)
- Linked from Earn credits > Watch videos

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:02:29 -05:00
martbost 37a2b97bfd Featured rotation format: duration-priced link rotation with disclosed dilution
- New 'featured' type: headline + link + 1/2/7 day run, flat up-front price (40cr/day)
- Composer discloses dilution (N links share the rotation, yours makes N+1) before buying
- Overview featured strip shows the live rotation; expires automatically

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:58:22 -05:00
martbost b25b4c67fe Buy more views: top up any campaign's budget, reactivates spent/paused ones (+NAS extend)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:53:35 -05:00
martbost 1aab52ca90 Profile build-out (avatar + bio) + shareable bio page with QR
- Profile pane: avatar upload + bio, with a link to your public page
- Wall becomes a bio page: avatar, bio, scannable join QR, line ladder, join CTA
- qrcode npm dep; /api/qr renders SVG QR server-side (CSP-clean img)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:49:20 -05:00
martbost 9e05711f4e Achievement badges + milestone credit bonuses
- Idempotent one-time credit bonus per milestone (payouts/firstBuyer/level2/level3): 10/25/50/100 cr
- Overview badges strip (unlockable medals) with canvas share-to-image (username overlaid)
- Newly-unlocked milestones toast the bonus on next dashboard load

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:43:50 -05:00
martbost 7701a29169 Sponsor to downline messaging: lineage view, daily broadcast (email+inbox), login modal
- Downline resolver (3 levels); email visible for directs only, username+ID deeper
- Broadcast composer (rich editor) to directs or full downline, 1/day cap, sends email + on-site inbox
- Upline messages inbox in My line; unmissable sign-in modal for unread, ack marks read
- messages.js dual-mode store; sponsor_messages table; sanitizeRich reused

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:39:06 -05:00
martbost 57bba0111a NAS syndication adapter (feature-flagged off): push banner/text to Network Ad Space, reconcile delivery into unified credit pool
- nas.js: direct-MySQL writer mirroring CTB's proven payments+sponsorads path (approved:1, pid 1/2, catid 5, remaining counts DOWN)
- Create-time push for banner/text; pause/resume mirrors to NAS deactivate/topUp
- reconcileNas() 5-min loop: reads served, charges delta credits to the shared budget, stops NAS ad when budget dry
- Campaign row shows IAP + '+N net' network views (differentiated stats)
- Inert unless NAS_DB_* env is set; zero prod impact until enabled
- Also: rename Inbox sub-tab to 'Inbox Ads'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:11:32 -05:00
martbost 860aedabf6 Video ads (watch-to-earn): duration-tiered pricing, escape-proof player, per-view charge
- New 'video' campaign type; MP4/WebM upload or direct https link + required-watch tier (10/30/60s → 3/7/12 cr per view; viewer earns 1/2/4)
- Composer: video fields, tier dropdown, live price hint
- Earn credits > Watch videos sub-tab: no-seek player, server-clock watch floor, daily cap, self-exclusion, single-use tokens
- media-src CSP for direct-link/hosted video; video skips frame-check

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:03:01 -05:00
martbost 49508c2a13 Banner ads: required IAB size picker (width/height stored, shown in row, maps to NAS)
Also lands dormant server-side scaffolding for video ads (type, tiers, validation) — not yet exposed in UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 07:51:28 -05:00
martbost 1ee0b5626e Viral welcome tour + line banner + wall, milestone stepper, rich solo editor, CTA-gated reads
- Welcome tour (3 levels x 10s) unlocks welcome credits; line banner in Profile; public /wall/<username>
- 'Your next move' redesigned as a milestone stepper
- Solo composer: BV-style rich editor (H2/H3, inline image+video, undo/redo, raw text)
- Solo read reward now requires clicking through to the advertiser, not just dwelling
- Sanitizer: inline media whitelist + script/style stripped whole

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 07:30:49 -05:00
martbost 718d7f2d0e Built-in transaction viewer: every ledger row verifiable at /tx/<hash>, explorer link when configured
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 05:37:29 -05:00
martbost 1c31679b6c Login ads as post-signin interstitials: Open Ad in new tab, timer here, Go to Dashboard
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 16:28:57 -05:00
martbost 2cc2855488 Rich solo composer: WYSIWYG editor, sanitized HTML bodies, media uploads, CTA labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 15:38:46 -05:00
martbost f6a3befe09 Onsite solo ads: inbox delivery with read rewards, composer, homepage format live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 15:25:00 -05:00
martbost 5c945a1b09 Frame-breaking check at campaign submit: reject XFO/frame-ancestors blockers, SSRF-guarded
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 07:48:55 -05:00
martbost 15b036b940 Earn viewer v2: full-screen URL visits with countdown, human check, explicit return
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 07:23:30 -05:00
martbost e22021c266 Member identity, promo tools, back-office color, seeded inventory
Real people, not numbers: usernames (unique, profile pane to set them),
shown across the ledger, activity, rosters, and the sidebar chip; vanity
invite links (/join/<username>) with late chain binding intact. Promo tools
pane ships Branded Voice share posts and an email swipe personalized with
each member's link. The earn viewer excludes a member's own campaigns, so
nobody earns from their own spend. Back office gains the cyan/violet/amber
accent family over the green base. Three house campaigns seeded so every
surface shows live inventory. Assets v=20260905i.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:28:17 -05:00
martbost 28ed925443 View-fraud protection + real ad placement surfaces
Earning views now run on single-use server-issued tokens: the view only
counts when the full dwell elapses on the server clock; instant, forged,
replayed, and stale posts are all rejected, and the client countdown
pauses whenever the tab loses visibility or focus. New placements: login
ads on the sign-in screen (the per-day format's real home), a banner slot
in the back-office Overview, a text slot in the member sidebar, and a
member-ads banner on the homepage. Assets v=20260905g.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:15:27 -05:00
martbost cdeb59ed7f Earn-and-spend credit economy + private rehearsal chain cutover
Members earn credits by attention (spec 8b): daily 5-ad set with dwell
timing and a too-fast guard, then a claimable daily batch. Earned credits
now FUND campaigns: banner/text budgets draw earned-first (free members can
advertise on welcome credits alone), purchased credits and the on-chain
burn queue only cover the remainder; earned-only campaigns pause when the
pool runs dry. New Earn credits section in the member menu with the viewer.
Explorer links degrade gracefully for the private chain (contract page
points at the audited Amoy verification). Site flipped to the anvil
rehearsal chain at rpc.instantadpay.com: unlimited test POL, no more
faucets. E2E: welcome->views->claim->earned-funded campaign->charged
serving, all green. Assets v=20260905d.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:59:42 -05:00
martbost d5bb74db7a Welcome credits (spec 8b earned pool v1) + official rehearsal rate card
Every account gets welcomeCredits (25, rate-card configurable) via an
idempotent lazy grant on dashboard load, so existing members receive theirs
retroactively. earned_credits table with JSON fallback; Overview stat shows
the purchased/welcome split. Chatbot facts and canned answers synced;
homepage free-membership list mentions the welcome batch. Rate card
promoted from placeholder to decided and persisted in the volume.
Spending integration for the earned pool is the next engine build.
Assets v=20260905b.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:48:42 -05:00
martbost 013a88b7d0 Fix: relay tx receipts through the server (CSP blocked direct RPC polls)
After a wallet sent a transaction, waitTx polled the public RPC straight
from the browser, which connect-src 'self' blocks (Firefox NetworkError,
reported by Marty on Activate; the activation itself landed on-chain).
New /api/tx/<hash> relays eth_getTransactionReceipt via the server's RPC
pool, so the browser only ever talks to us and the mainnet flip needs no
CSP changes. Assets v=20260905a.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:40:56 -05:00
martbost a386c8e3a3 Member dashboard: stat cards, next-move guidance, line roster, share kit
/api/my/dashboard aggregates credits, earned POL (from the chain index),
qualification count, and the referral roster (privacy-masked emails,
joined-free vs wallet-linked status, code+id referrer match). Members area
leads with four stat cards, a next-move card with a qualification progress
bar (2 and 5 buyer marks), the line roster, and a copy-ready share message
beside the invite link. Assets v=20260904j.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 14:47:07 -05:00
martbost 6680e154d0 MySQL data layer: accounts, sessions, campaigns, burns (Marty: real concurrency)
Coolify MySQL (instantadpay-db) via DATABASE_URL; db.js bootstraps schema
and one-time imports the volume JSON. accounts/auth/ads are dual-mode: the
MySQL path uses guarded UPDATEs for the concurrent ad-serving hot path;
without DATABASE_URL the JSON stores remain (local dev). All data functions
async; server boots through db.init. Chain index stays a file: it is a
rebuildable cache of the blockchain, which remains the money truth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 14:13:37 -05:00
martbost f3d2f7db88 24/7 assistant: canned answers + OpenRouter AI, widget on every page
RM Circle pattern: nine canned answers for the questions everyone asks
(pyramid, withdrawals, splits, qualification, joining, credits, safety),
OpenRouter fallback with a facts-loaded system prompt and hard no-income-
promise rules, graceful no-key fallback. Floating mint bubble widget with
linkified replies; 10/min per-IP rate limit. Assets v=20260904i.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 14:00:43 -05:00
martbost dea279eed0 Free members refer from day one: share codes with late chain binding
Every account gets a share code at signup; /join/<code> attributes
first-touch site-side and resolves to the referrer's CURRENT on-chain id at
the referral's buy time, so activating any time before your people buy
locks the line to you. Joining through a code emails the referrer an
activate-payouts nudge. Buy flow re-resolves the sponsor at click time.
Copy updated across home and members; assets bumped to v=20260904g.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 13:54:45 -05:00
martbost 9dc5989aa3 Contract verification page, cache-busted assets, no-withdrawal line
/contract: plain-language security review with the six design laws, honest
operator CAN/CANNOT lists, split walkthrough, oracle bridge and anti-stall
notes, testing summary, live explorer + Sourcify verified-source links
(config-driven so it follows the mainnet flip). Nav gains The contract.
All asset URLs now carry a version query so deploys bust browser caches
(the level-cycler stall). Earn-deeper checklist leads with: no withdrawal
requests, ever.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 13:47:49 -05:00
martbost 08f7a408e3 Passwordless sign-in: 6-digit email codes, feature-flagged on SendGrid key
/api/auth/email/start issues a 15-min code (60s resend guard, 6 tries);
verify creates the account passwordless (sponsor cookie first-touch) and
mints the session. UI swaps the password cards for the code flow when
config.emailAuth is on; dev mode returns the code inline. Password flow
remains until the key lands in the volume (data/sendgrid.key) or
SENDGRID_KEY env.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 13:38:11 -05:00