← library
Wallet-gated, indirect
Blockchain / wallet identity (no first-party OAuth IdP)·agent-generated · deepseek-v4.1-flash·checked 2026-10-28
difficulty
3/5

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.

First working connection
~1–3 hours
Production / approved
~1–2 weeks (KYC/KYB + 3–4 business-day first-app review)
Composio managed OAuth
Bring your own app
Not in Composio's managed-OAuth list — you'll need your own OAuth app (or it isn't a Composio toolkit yet).
who does itagent 4you 4provider 0
evidencetested 1sourced 20inferred 19
◆ agent run11 pages read17/29 quotes verified verbatim39s$0.025deepseek-v4.1-flash

01Pick your path

Phantom embedded wallet (Google/Apple OAuth handled by Phantom)
when You want consumer sign-in inside a mobile/Expo app and are willing to depend on Phantom Portal access.
→ No browser extension; user signs in with Google or Apple and gets a Solana (and Ethereum) address. Requires a Phantom Portal App ID and allowlisted redirect URI.
Crossmint wallets + Google OAuth
when You need an agent/backend to hold delegated signing rights rather than prompt the wallet on every action.
→ Crossmint client API key with explicit scopes creates wallets and adds delegated signers so a third party can sign for the user; Google Cloud OAuth client IDs supply the login.
Browser wallet connect (no OAuth at all)
when Web dApp, fastest prototype, and you accept manual approval on each transaction.
→ User connects Phantom/Solflare extension; every signature is a wallet popup the agent cannot automate.
Solana dApp Store distribution
when You want the app listed on the Solana dApp Store, not just running locally.
→ Publishing needs a Publisher account, KYC/KYB, a publisher wallet with SOL, signed APK on a unique key, then app review (typically 3–4 business days for a new app).

02Time & effort

Hands-on work
1.9 h – 5.3 h
Waiting on others
4 days – 9 days
You're actually working
2% of elapsed time
Phases
6
start↑ first working connection, then production pathproduction
  1. 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.
  2. 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).
  3. DEVScaffold and configure the starter30–60 minutesinferred[S6]Agent can run the CLI, fill .env, and wire the callback route.
  4. 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.
  5. 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.
  6. 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).
agent can do it you waiting on providerbar widths ∝ √time, so short tasks stay visible

03Steps

0/8 done

Get a working connection

  1. Accept that Solana is not an OAuth provideryouinferred[S5][S6]

    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.

  2. Get a Phantom App ID and allowlist the redirect URIyousourced ❝[S4][S6]

    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/
  3. Scaffold the embedded-wallet starteragentsourced ❝[S6]

    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-starter
  4. Write the env/config pairagentinferred[S6]

    Copy .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 checklist
    EXPO_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" } }
  5. Wire the callback route and crypto initagentinferred[S6]

    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.

  6. Build natively and test sign-in on a deviceyouinferred[S6]

    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.

  7. Optional: delegation path via Crossmintagentsourced ❝[S5]

    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

  1. Ship to the Solana dApp Storeyouinferred[S3][S11]

    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 / permissionTierNoteEvidence
openid profile email (Google/Apple sign-in inside the wallet SDK)basicThe 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)basicMinimum for Crossmint Auth to create/read the user tied to the Google login.inferred[S5]
wallets.read, wallets.balance.readsensitiveRead-only wallet and balance access; safe default for a reporting agent.inferred[S5]
wallets.createsensitiveOnly needed if your flow provisions a wallet per user.inferred[S5]
wallets:transactions.create, wallets:transactions.signrestrictedMoves value. Treat as the highest-risk grant on the key; keep it out of any key shipped to a client.inferred[S5]
wallets.fundrestrictedFunds a wallet — spending authority, not just signing.inferred[S5]
In-wallet transaction/message approval (no scope exists)gatedWith 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

✕There is no Solana-run OAuth authorization/token endpoint to register against. Nothing in the fetched sources shows a Solana-branded OAuth provider with client registration; what exists is wallet-based connection plus third-party wallet SDKs and API keys.inferred[S5][S6]

→ 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.

✕Phantom Portal signup or app creation can be unavailable/paused, and a placeholder App ID cannot authenticate.sourced ❝[S6]

→ 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.

✕You cannot add a dApp to the Solana dApp Store until KYC/KYB is approved.sourced ❝[S3]

→ 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.

✕iOS native build requires macOS; Windows cannot run expo run:ios locally.sourced ❝[S6]

→ Use macOS + Xcode for iOS, or ship Android-only / EAS cloud builds from another OS.

✕Reusing your Google Play signing key for the dApp Store is explicitly disallowed.sourced ❝[S9]

→ 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

$ probes: live GETs with a dummy client_id, no credentials
✓ Authorize endpoint with a fake client_id → 302
https://github.com/login/oauth/authorize?client_id=probe_invalid_client&response_type=code&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
redirect → https://github.com/login?client_id=probe_invalid_client&return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dprobe_invalid_client%26redirect_uri%3Dhttps%253A%25
∴ This is GitHub's authorize endpoint, not a Solana one. The 302 to github.com/login shows GitHub handles an unrecognized client_id by sending the user to log in rather than erroring — it is evidence about GitHub [S1] and exactly zero evidence about Solana. Re-probe the actual identity endpoint you plan to use (e.g. the wallet SDK's authorize URL or Phantom Portal redirect validation).

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.