Solana
solana.com ↗Solana runs no OAuth provider for third-party apps — you borrow OAuth from Phantom's embedded wallet (Google/Apple, needs a Phantom Portal App ID that may be paused) and public distribution then costs Solana dApp Store KYC/KYB plus ~3–4 business days of app review.
01Pick your path
02Time & effort
- DEVDecide the identity layer10–30 minutesinferred[S5][S6]Solana L1 issues no tokens for third-party apps; the sources only show wallet connection, wallet-SDK OAuth delegation, and API-key models.
- DEVCreate Phantom app + App ID, allowlist redirect URI15–45 minutessourced[S4][S6]Your login and wallet — the agent cannot do this. Portal registration may be paused (see blockers).
- DEVScaffold and configure the starter30–60 minutesinferred[S6]Agent can run the CLI, fill .env, and wire the callback route.
- DEVNative dev build + sign-in test on device1–3 hourssourced[S6]Expo Go is not supported; needs prebuild and simulator/device. Rebuild after any scheme change.
- PRODPublisher account, KYC/KYB approval, mint App NFTwait 1–5 daysinferred[S3]KYC/KYB turnaround is not documented in the source; duration is my estimate.
- PRODApp review for first releasewait 3–4 dayssourced[S3][S11]Results emailed from publishersupport@dappstore.solanamobile.com; escalate in #dev-answers after 5 business days. Updates are faster (1–2 business days).
03Steps
Get a working connection
Nothing in the fetched Solana sources describes a Solana-run OAuth authorization or token endpoint for third-party apps. What exists: wallet connect + wallet SDKs that delegate sign-in to Google/Apple (Phantom), and API-key models that mint wallets for users (Crossmint). Pick one of these before writing any OAuth code.
Sign in at Phantom Portal, create an app, copy the App ID (not Organization ID), and add the redirect URI phantomwallet://phantom-auth-callback. If registration is paused, follow the portal's access instructions or contact Phantom support — this is an external prerequisite.
“Copy your App ID (not Organization ID)” — [S4] verified verbatim
↗ phantom.app/Run the template generator, then fill .env. Keep EXPO_PUBLIC_APP_SCHEME identical to expo.scheme in app.json, and replace the com.example.phantomwallet bundle/package identifiers with your own reverse-domain IDs.
“Keep EXPO_PUBLIC_APP_SCHEME equal to expo.scheme in app.json.” — [S6] verified verbatim
↗ solana.com/developers/templates/phantom-embedded-react-native-starterCopy .env.example to .env and set the three variables. The SDK reads EXPO_PUBLIC_APP_SCHEME; EXPO_PUBLIC_REDIRECT_URL is ignored and causes "Invalid redirect URL".
◆ prepared by agent · Env + redirect URI checklistEXPO_PUBLIC_PHANTOM_APP_ID=<your-app-id> EXPO_PUBLIC_APP_SCHEME=phantomwallet EXPO_PUBLIC_SOLANA_RPC_URL=https://api.mainnet-beta.solana.com # redirect URI to allowlist in Phantom Portal: # phantomwallet://phantom-auth-callback # app.json must contain: { "expo": { "scheme": "phantomwallet" } }The template routes the OAuth callback through app/+native-intent.tsx and initializes Web Crypto (lib/crypto.native.ts) before the Phantom SDK loads; the crypto import must be first in app/_layout.tsx. The random-values polyfill alone does not provide crypto.subtle.
Run expo prebuild and run:ios / run:android. Expo Go will not work. Verify sign-in completes, the deep link returns to the app, and session restoration lands on the dashboard.
Alternative to Phantom: generate a Crossmint client API key with only the scopes you need, set app type Mobile with your iOS bundle ID and Android package name, and configure Google OAuth client IDs (Web + iOS + Android with SHA-1). For an agent that must act without per-action popups, add delegated signers.
“Add delegated signers to allow third parties to sign transactions on behalf of your wallet” — [S5] verified verbatim
◆ prepared by agent · Scope justification draft (Crossmint)Crossmint client API key — requested scopes (least privilege, v1): users.create - create the Crossmint user on first Google login users.read - map session -> user wallets.read - list the user's wallets wallets.balance.read- display SOL/SPL balances NOT requested in v1: wallets.create, wallets:transactions.create, wallets:transactions.sign, wallets.fund (value-moving; add only behind a separate server-side key) App type: Mobile (iOS bundle ID + Android package name from app.json), domain allowlisted.
Make it production-ready
Sign up at the Publisher Portal, create the publisher profile, complete KYC/KYB (required before adding a dApp), connect the publisher wallet with SOL, mint the App NFT, then upload the signed APK under Releases > New Version and approve each wallet transaction. Review typically returns in 3–4 business days; updates in 1–2.
↗ publish.solanamobile.com/
04Requirements, scopes & nuances
You'll need
- ▸Phantom Portal access and a real App ID (a placeholder cannot authenticate). sourced ❝[S6]
- ▸Node.js ^22.13.0, ^24.3.0, or >=26.0.0 (23 and 25 unsupported); Android Studio for Android; macOS + Xcode for iOS. sourced ❝[S6]
- ▸For dApp Store listing: public HTTPS terms of service and privacy policy pages, a public website about your app/company, 512×512 icon, 1200×600 banner, 4–8 screenshots. sourced ❝[S3]
- ▸A Solana wallet browser extension with a small amount of SOL — use a dedicated publisher wallet; losing it blocks future submissions. sourced ❝[S3]
- ▸Release APK (not AAB) signed with a signing key separate from your Google Play key, supporting arm64-v8a, ≤2 GB. sourced ❝[S9]
- ▸Identity verification: KYC as an individual, KYB as a company, before any dApp can be added. sourced ❝[S3]
Gotchas
- !The probe URL is GitHub's endpoint (github.com/login/oauth/authorize), not a Solana endpoint — it proves GitHub redirects an unknown client_id to its login page and says nothing about Solana OAuth. inferred
- !Expo Go will not work. The Phantom React Native SDK needs native modules; you must create a development build (expo prebuild + run:ios/run:android). sourced ❝[S6]
- !The OAuth callback URI must match exactly and be allowlisted in Phantom Portal: {scheme}://phantom-auth-callback (default phantomwallet://phantom-auth-callback). Changing the scheme requires editing both .env and app.json AND the portal entry, then a native rebuild. inferred[S6]
- !The app reads EXPO_PUBLIC_APP_SCHEME, not EXPO_PUBLIC_REDIRECT_URL — a common cause of "Invalid redirect URL". sourced ❝[S6]
- !dApp Store Package Name must exactly match the APK application ID, is case-sensitive, and cannot be changed later. sourced ❝[S3]
- !Never put private keys or service secrets in EXPO_PUBLIC_* variables — the SDK ships the App ID to the client. sourced ❝[S6]
- !Two fetched sources (Solsynth "Stargate" OAuth-apps docs and Solar Network / Suki "OAuth Authentication") are different projects that merely collide on naming. Do not use their endpoints (/api/oauth-apps, api.solian.app/padlock/...) for Solana apps. inferred[S7][S10]
| Scope / permission | Tier | Note | Evidence |
|---|---|---|---|
| openid profile email (Google/Apple sign-in inside the wallet SDK) | basic | The starter ships Google and Apple auth providers; the exact OIDC scopes it requests are not listed in the fetched source — request only openid + email unless you need a display name. | inferred[S6] |
| users.create, users.read (Crossmint client API key) | basic | Minimum for Crossmint Auth to create/read the user tied to the Google login. | inferred[S5] |
| wallets.read, wallets.balance.read | sensitive | Read-only wallet and balance access; safe default for a reporting agent. | inferred[S5] |
| wallets.create | sensitive | Only needed if your flow provisions a wallet per user. | inferred[S5] |
| wallets:transactions.create, wallets:transactions.sign | restricted | Moves value. Treat as the highest-risk grant on the key; keep it out of any key shipped to a client. | inferred[S5] |
| wallets.fund | restricted | Funds a wallet — spending authority, not just signing. | inferred[S5] |
| In-wallet transaction/message approval (no scope exists) | gated | With a connected browser wallet the user must approve each signature; the agent cannot self-approve. Delegated signers (Crossmint) are the escape hatch. | inferred[S5][S6] |
05If you get blocked
→ Treat Solana as a wallet layer, not an IdP: use a wallet SDK for sign-in (Phantom embedded/Connect) and your own session, or use Crossmint Auth (Google OAuth) as the identity provider.
→ Get access through Phantom before building auth; local setup cannot remove the restriction. Do not substitute the Phantom MCP server — it does not supply an App ID for the mobile template.
→ Complete KYC (individual) or KYB (company) first; if stuck, get the Developer role in #developer on Discord and open a KYC / KYB Verification Issue in #dev-answers.
→ Use macOS + Xcode for iOS, or ship Android-only / EAS cloud builds from another OS.
→ Generate a separate dappstore.keystore and use product flavors / EAS local credentials for the dApp Store build.
06Evidence: what was tested, sourced, and still uncertain
Sources read
- [S1] Authorizing OAuth apps - GitHub Docs official
- [S2] Solana Labs third-party
- [S3] Submit a New App - Solana Mobile Docs official
- [S4] GitHub - Th3Ya0vi/phantom-embedded-react-native-starter third-party
- [S5] GitHub - Crossmint/solana-wallets-expo-ncs-google-quickstart third-party
- [S6] Phantom Embedded React Native Starter - Solana Template official
- [S7] OAuth apps third-party
- [S8] dApp Publishing CLI - Solana Mobile Docs official
- [S9] Publishing from Google Play to the dApp Store - Solana Mobile Docs official
- [S10] OAuth Authentication - Suki official
- [S11] Submit an Update - Solana Mobile Docs official
- [composio] Composio — Managed OAuth apps directory official
- [probe] Live HTTP probes run by the agent (dummy client_id, no credentials) probe
Still uncertain
- ? Solana's own developer docs were not fetched — no source here documents a general Solana authentication page, so the "no first-party OAuth" conclusion rests on absence of evidence in S1–S11 plus the wallet-SDK shape of S5/S6. Verify at solana.com/developers before committing.
- ? The probe targeted github.com and is not evidence about Solana; the planner's "unclear" is justified — re-run a probe against the endpoint you actually intend to use.
- ? KYC/KYB turnaround for the Solana dApp Store is not stated anywhere in S3; the 1–5 day estimate is mine.
- ? Whether Phantom Portal app creation is currently open is unknown; S6 flags that it can be paused.
- ? Exact OIDC scopes requested by the Phantom SDK (Google/Apple) are not listed in S6 — the scope tiers for openid/profile/email are my judgement.
- ? S7 (Solsynth Stargate) and S10 (Solar Network / Suki) are unrelated projects with name collisions; they were excluded from the Solana guidance entirely.
- ? If the user actually wants "Sign in with Solana" (a signed-message wallet login, not OAuth), none of the sources cover it — this guide would need a different shape.
- ? Generated automatically; no app was registered and no review was submitted.