547bff0d05c333c93c3829de17ba77de206f83f8
refreshNavWallet assumed every signed-in session has a wallet address and threw on null for email-only members; the catch returned null and render() treated the member as signed out even though the session and cookie were valid. Nav now shows the email (or member badge) when no wallet is linked. Verified with a full browser cycle: session landing, logout, fresh code sign-in. Assets v=20260904k. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
InstantAdPay — site
Membership advertising with immutable on-chain settlement. Zero-dependency Node server (RM Circle pattern): static pages + JSON API + SSE ledger.
Architecture
server.js— http server: pages,/api/*,/join/<id>sponsor links, SSE feedchain.js— contract reader + persistent event indexer (free public RPCs)auth.js— SIWE wallet sign-in (EIP-4361), sessions in the volumeaccounts.js— site-side records only (free members, first-touch sponsor attribution, handles). The CHAIN is the source of truth for money/credits.public/— landing, live ledger, member area; no client libraries
Chain flip (rehearsal → mainnet)
Everything chain-specific lives in data/config.json (volume):
{contract, chainId, chainName, explorer, rpcs, deployBlock}.
Defaults point at the Amoy rehearsal deployment. Launch = deploy the
mainnet contract, wipe accounts.json/sessions.json/chain-index.json,
PATCH /api/admin/chain with the mainnet values, set rehearsal:false via
/api/admin/site. Same code, different config.
Run
PORT=3100 node server.js # DATA_DIR defaults to ./data
Admin API auth: Authorization: Bearer $ADMIN_PASSWORD.
Spec: ../CONTRACT-SPEC.md (v1.0.3-frozen). Contracts: ../contracts/.
Description
Languages
JavaScript
78.6%
HTML
17.1%
CSS
4.2%
Shell
0.1%