Status
Phantom Connect is disabled in production. NEXT_PUBLIC_PHANTOM_APP_ID has been removed from the Vercel production environment so the "Continue with Phantom" button does not render.
Why it was disabled
The button was live and reaching Phantom, but Phantom rejected every attempt:
Auth2 /login/start request failed (400). Bad Request
The app submission was rejected because the domain-verification TXT record took too long to propagate. The DNS record (_phantom_portal-challenge) now resolves correctly, so the app can be resubmitted — but until Portal approves it, /login/start will keep 400ing and the button is a dead end for learners.
How it is disabled
No code change. The integration was built with an env-var gate:
getPhantomAppId() returns null for unset or whitespace-only (lib/phantom/config.ts)
createPhantomClient() then returns null
- the provider's
enabled stays false — no SDK, no listeners, no traffic (phantom-connect-provider.tsx:70)
- the modal button is behind
{phantomEnabled && …} (auth-modal.tsx:195)
To re-enable
- Confirm the app is approved in Phantom Portal, and that the allowed-domains list contains the production origin and
http://localhost:3000 for dev.
- Set
NEXT_PUBLIC_PHANTOM_APP_ID=d12abb45-9120-4e3c-a5f7-c8e0ad9842c3 in Vercel Production.
- Redeploy with build cache disabled.
NEXT_PUBLIC_* is inlined at build time, so a cache-reusing redeploy silently keeps the old bundle. This bit us when disabling it — the variable was removed and the app id was still present in the served chunk afterwards.
- Verify from outside:
curl -sL https://st.academy/en \
| grep -o '/_next/static/chunks/[^"]*\.js' | sort -u \
| while read c; do curl -sL "https://st.academy$c" \
| grep -q d12abb45 && echo "present in $c"; done
- Do a real sign-in and confirm
/login/start returns 200, not 400.
Blocks / related
Note
The settings graduation card is deliberately not behind this gate — it renders on prefs.walletProvider === "phantom-embedded", so any learner who already received an embedded wallet keeps the "take your wallet with you" instructions. Since sign-in never succeeded in production, that set is expected to be empty.
Status
Phantom Connect is disabled in production.
NEXT_PUBLIC_PHANTOM_APP_IDhas been removed from the Vercel production environment so the "Continue with Phantom" button does not render.Why it was disabled
The button was live and reaching Phantom, but Phantom rejected every attempt:
The app submission was rejected because the domain-verification TXT record took too long to propagate. The DNS record (
_phantom_portal-challenge) now resolves correctly, so the app can be resubmitted — but until Portal approves it,/login/startwill keep 400ing and the button is a dead end for learners.How it is disabled
No code change. The integration was built with an env-var gate:
getPhantomAppId()returns null for unset or whitespace-only (lib/phantom/config.ts)createPhantomClient()then returns nullenabledstaysfalse— no SDK, no listeners, no traffic (phantom-connect-provider.tsx:70){phantomEnabled && …}(auth-modal.tsx:195)To re-enable
http://localhost:3000for dev.NEXT_PUBLIC_PHANTOM_APP_ID=d12abb45-9120-4e3c-a5f7-c8e0ad9842c3in Vercel Production.NEXT_PUBLIC_*is inlined at build time, so a cache-reusing redeploy silently keeps the old bundle. This bit us when disabling it — the variable was removed and the app id was still present in the served chunk afterwards./login/startreturns 200, not 400.Blocks / related
Note
The settings graduation card is deliberately not behind this gate — it renders on
prefs.walletProvider === "phantom-embedded", so any learner who already received an embedded wallet keeps the "take your wallet with you" instructions. Since sign-in never succeeded in production, that set is expected to be empty.