The Members page loads the newest 500 accounts and built its sponsor name
lookup from that same list. Once the site passed 500 accounts every sponsor who
joined before that window became unfindable, so the page labelled them "dead
link: <name>" with a tooltip saying the member would fall into the holding
tank. It was doing that to 144 of the 500 rows, including cryptoassets 76
times, and not one token on the whole site is genuinely unresolvable.
Sponsorship itself was never affected: assignment at purchase time looks each
token up directly rather than scanning a list.
accounts.identities() returns the identity columns for every account with no
limit, which stays cheap at any size, and the page uses that for the lookup
while still showing 500 rows.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
memberLabel() resolves @username, or the owner's username for a linked
position, else member #id. Subject: '@name just bought a $20 ad package'.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- accounts/db: positions table + JSON store (add/list/owner/remove; main-wallet and cross-account guards)
- auth verify: asPosition links a second wallet without touching the session; position wallets can't mint a session
- /api/my/positions (chain-refreshed member ids, buyer counts, credits) + remove
- credits pooled across main + positions on /api/me, dashboard, campaigns; campaign charged to the best-funded position
- My line: own positions listed on level 1 as 'You · position N'
- Buy pane: Qualified Start card + Add a position flow + Buy-from picker with connected-wallet guard
- Wallet pane: Your positions card; chatbot answer updated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- accounts.wall_offers (JSON, up to 2 offers: label, https link, banner) set from
Profile > Your wall; upload supported; locks show the buyer threshold.
- /api/wall assembles: position 1 = own line banner; positions 2-3 = own offer
when unlocked and set, else upline banners (only uplines with a live banner),
else house ads. Response carries unlocked + buyerCount; wall labels show
"this wall" / "their line" / "InstantAdPay".
- Chatbot canned answer + facts, follow-up email 7 mention the ladder.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- /join/<token>[?v=angle] now serves a capture page (email first, wallet
later) with angle-matched hook copy, sponsor line, worked-example ledger,
how-it-works, live package ladder, and per-angle og tags (og:url keeps ?v=).
The sponsor cookie is set exactly as before; ?v= is remembered and stored
on the account as joined_via (shown in admin Members).
- drip.js: 4-step getting-started sequence (24h/48h/96h/168h) queued when a
free account is created with the pre-checked opt-in; ticker every 10 min;
signed /unsubscribe link in every email; MySQL + JSON storage.
- Admin > Settings: edit the sequence as JSON, reset to defaults, send any
step to the admin inbox; Overview shows follow-ups in flight.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- /admin: email magic-code sign-in allowlisted to ADMIN_EMAIL, 12h admin
session (cookie iap.adm, persisted in the volume). Bearer ADMIN_PASSWORD
API access still works. Member area shows an Admin link for that email.
- House ads: admin places banner/text/login/solo/video/featured/visits
campaigns owned by house@instantadpay.com that cost nothing; budget is
only a delivery cap, spend is never charged or burned.
- Admin APIs: overview, all campaigns (+pause/resume any), members
(+re-point sponsor), reports (+resolve), pending burns, rates/site
config get+patch, creative upload.
- fmtPol rounds to two decimals everywhere (dashboard, toasts, prices).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- 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>
- 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>
- 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>
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>
/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>
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>
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>
/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>
Normal people join with email + password (sponsor attribution via cookie at
signup); the wallet only appears when buying or activating payouts, and gets
linked to the account then. Wallet-only sign-in remains for crypto-native
users. Sessions carry {email, address, memberId}.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Zero-dependency Node server on the RM Circle pattern. Chain config lives in
the volume so the same code runs the Amoy dress rehearsal and mainnet.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>