Phantom exposes its EVM provider at window.phantom.ethereum and does not always
fire EIP-6963, so the picker never saw it. probeInjected() now folds in Phantom
and any window.ethereum.providers[] entries (deduped by identity + name) for
both pick() and list(). Phantom added to the mobile in-app-browser hint and the
dashboard no-wallet message.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New shared wallet-notice.js on join-now, my, training: if config.walletNotice
is set, shows an admin-authored heads-up right above every connect/unlock
button; empty string hides it everywhere (one PATCH, no deploy). Placed at the
friction point only, not a sitewide banner, so unaffected wallets/Mini App
users are not told about a warning they will never see.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mobile users on SafePal/Coinbase/Rabby had no route in — the deep-link help
only offered MetaMask + Trust. Added a wallet-agnostic instruction (open your
wallet app -> Browser/DApp tab -> type the join URL) that works via the
injected provider our EIP-6963 picker already resolves; join-now fills the
sponsor path into the hint. Dashboard no-wallet message made wallet-agnostic
and names SafePal. No guessed SafePal deep-link scheme (unverified).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- /app decodes startapp=<sponsorId>[_<angle>] -> unlinked visitors land on the
sponsor squeeze page /join/<ref>?src=miniapp (linked members still go to
their dashboard); no-invite prospects get a gold Join button -> /join-now
- tg-app.js: sync __rmcInTg flag; external links route out of the webview via
openLink/openTelegramLink (wallet deep links reach the wallet app reliably)
- join-now.js in the webview leads with the MetaMask/Trust deep links (no
injected wallet can exist there); ref + src survive into the wallet browser
- tgbot: links command + weekly digest include the t.me/<bot>/<short>?startapp
Telegram-native invite once config.miniAppShortName is set (new PATCH key)
- Synced chat.js canned answer + AI prompt (prospects can join from the app)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Floating translate button (bottom-left) on every member-facing page
lazy-loads the Google Translate element; language choice persists
across pages via the googtrans cookie. CSP extended for Google's
translate hosts only. Chatbot now replies in the member's language
and a canned answer points at the button.
- GET /api/public/moonpay-url: returns a MoonPay checkout link for POL on
Polygon (pol_polygon). With partner keys in config (moonpayPublicKey/
moonpaySecretKey, now PATCHable), the URL is HMAC-signed and prefilled
with the member's own wallet address + shortfall amount; without keys it
falls back to MoonPay's generic buy page. MoonPay is merchant of record -
the site never touches funds.
- Join page: when the connected wallet can't cover the Premium entry, a
funding box appears with the exact shortfall, a buy button (new tab), and
a refresh-balance button.
- Training page: "buy POL with a card" callout after the funding video with
the three things to get right (POL, Polygon network, own address).
- Start page: one-line card-buy pointer under the sponsor card.
- Chatbot canned answer + AI system prompt updated (funding guidance).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Self-enroll pageviews now tracked as the "joinnow" event (track.js loaded
on the page; server whitelist + admin tiles/columns extended)
- A confirmed on-chain registration in the wallet-connect flow now auto-posts
to the submit-id API, so every self-enroll join records a submission with
source + clickid attribution and fires the purchase event and BeMob postback
with no manual ID entry
- Optional name/handle field on the join page feeds the submission and the
team Telegram alert
- Admin Traffic panel: Join-now views tile, Join-now -> Confirmed conversion,
and a per-source Confirmed column for campaign-level ROI reading
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both /join-now and /direct-join now discover every injected wallet (Brave,
MetaMask, SafePal, Trust, Coinbase…) via EIP-6963 and, when more than one is
present, show a 'Choose your wallet' picker on connect — instead of blindly
grabbing window.ethereum (which silently hangs when e.g. Brave's built-in wallet
wins the slot). Shared public/rmc-wallet.js; provider resolved on connect and
wallet events bound once after. Falls back to window.ethereum for legacy
single-provider wallets. CSP-safe (6963 icons are data URIs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
/join-now: public self-enroll page gated behind config.dappFallbackPublic
(default off -> redirects to /start, invisible until needed). Auto-assigns the
current rotation sponsor via /api/public/current-sponsor, registers the user's
own wallet, then redirects to /my/<newId> so new members land on their live
position instead of guessing their ID. HTML lives in private/, served only via
the flagged route. Reuses the proven contract engine. Admin /direct-join now
also shows a 'View position ->' link to /my/<newId> after a successful join.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>