Para supports OAuth authentication with providers like Google, Apple, Discord, X, and Facebook. Use authenticateWithOAuth() to handle the entire OAuth flow in a single call — it manages the redirect, polls for completion, and creates wallets for new users.
Prerequisites
Before implementing OAuth authentication, ensure you have completed the basic Para setup for your React Native or Expo application.
Standard OAuth
Use para.authenticateWithOAuth() to authenticate a user via a third-party OAuth provider. The method manages the OAuth redirect, polls for completion, waits for session establishment, and creates wallets for new signups.
For standard OAuth providers, use the onOAuthUrl callback to open the OAuth URL in an in-app browser.
Installation
Install the In-App Browser package to handle OAuth redirects:npm install react-native-inappbrowser-reborn
# or
yarn add react-native-inappbrowser-reborn
For iOS, add the following to your Info.plist to define your URL scheme:<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>your-app-scheme</string>
</array>
</dict>
</array>
For Android, add your URL scheme to AndroidManifest.xml:<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="your-app-scheme" />
</intent-filter>
</activity>
Implementation
import { para } from "../your-para-client";
import { OAuthMethod } from "@getpara/react-native-wallet";
import { InAppBrowser } from "react-native-inappbrowser-reborn";
const APP_SCHEME = "your-app-scheme";
async function handleOAuthLogin(provider: OAuthMethod) {
try {
const result = await para.authenticateWithOAuth({
method: provider,
appScheme: APP_SCHEME,
redirectCallbacks: {
onOAuthUrl: async (url) => {
await InAppBrowser.openAuth(url, APP_SCHEME, {
ephemeralWebSession: false,
showTitle: false,
enableUrlBarHiding: true,
});
},
},
});
if (result.hasCreatedWallets && result.recoverySecret) {
console.log("Recovery secret:", result.recoverySecret);
}
console.log("Auth info:", result.authInfo);
// Navigate to your authenticated screen
} catch (error) {
console.error("OAuth failed:", error);
}
}
Installation
Install the Expo Web Browser package:npx expo install expo-web-browser
Configure your app.json with the URL scheme:{
"expo": {
"scheme": "your-app-scheme",
"ios": {
"bundleIdentifier": "com.yourcompany.yourappname"
},
"android": {
"package": "com.yourcompany.yourappname"
}
}
}
After updating your app.json, rebuild native files:npx expo prebuild --clean
Implementation
import { para } from "../your-para-client";
import { OAuthMethod } from "@getpara/react-native-wallet";
import { openAuthSessionAsync } from "expo-web-browser";
const APP_SCHEME = "your-app-scheme";
async function handleOAuthLogin(provider: OAuthMethod) {
try {
const result = await para.authenticateWithOAuth({
method: provider,
appScheme: APP_SCHEME,
redirectCallbacks: {
onOAuthUrl: async (url) => {
await openAuthSessionAsync(url, APP_SCHEME, {
preferEphemeralSession: false,
});
},
},
});
if (result.hasCreatedWallets && result.recoverySecret) {
console.log("Recovery secret:", result.recoverySecret);
}
console.log("Auth info:", result.authInfo);
// Navigate to your authenticated screen
} catch (error) {
console.error("OAuth failed:", error);
}
}
Both react-native-inappbrowser-reborn and expo-web-browser use secure browser implementations that leverage the device’s native browser engine rather than a WebView. This provides stronger security protections and support for modern authentication methods.
Telegram & Farcaster
Telegram and Farcaster authentication require a different approach than standard OAuth. These providers authenticate through Para’s hosted portal, which needs to send events back to the SDK when authentication completes. On mobile, this requires opening the portal in a WebView (not an in-app browser) so the portal can communicate via window.ReactNativeWebView.postMessage().
You must forward messages from the WebView to the SDK using para.handleWebViewMessage().
Telegram and Farcaster cannot use InAppBrowser or expo-web-browser because the portal needs a live message channel to send authentication events (TELEGRAM_SUCCESS, FARCASTER_SUCCESS) back to the SDK. Only a WebView provides this channel via onMessage.
import { useState } from "react";
import { Modal } from "react-native";
import { WebView, type WebViewMessageEvent } from "react-native-webview";
import { para } from "../your-para-client";
import type { OAuthMethod } from "@getpara/react-native-wallet";
const APP_SCHEME = "your-app-scheme";
function TelegramOrFarcasterAuth() {
const [portalUrl, setPortalUrl] = useState<string | null>(null);
const handleAuth = async (method: OAuthMethod) => {
try {
const result = await para.authenticateWithOAuth({
method,
appScheme: APP_SCHEME,
redirectCallbacks: {
onOAuthUrl: (url) => {
// Show the portal URL in a WebView instead of an in-app browser
setPortalUrl(url);
},
},
});
setPortalUrl(null);
if (result.hasCreatedWallets && result.recoverySecret) {
console.log("Recovery secret:", result.recoverySecret);
}
console.log("Auth info:", result.authInfo);
// Navigate to your authenticated screen
} catch (error) {
setPortalUrl(null);
console.error("Auth failed:", error);
}
};
const handleWebViewMessage = (event: WebViewMessageEvent) => {
try {
const data = JSON.parse(event.nativeEvent.data);
// Forward portal events (TELEGRAM_SUCCESS, FARCASTER_SUCCESS, etc.) to the SDK
para.handleWebViewMessage(data);
} catch {
// Ignore non-JSON messages
}
};
return (
<>
{/* Your auth buttons */}
<Button title="Continue with Telegram" onPress={() => handleAuth("TELEGRAM")} />
<Button title="Continue with Farcaster" onPress={() => handleAuth("FARCASTER")} />
{/* WebView modal for portal interaction */}
<Modal visible={!!portalUrl} animationType="slide">
<WebView
source={{ uri: portalUrl! }}
onMessage={handleWebViewMessage}
javaScriptEnabled
/>
</Modal>
</>
);
}
Install react-native-webview if you haven’t already:npm install react-native-webview
# or for Expo:
npx expo install react-native-webview
Method Reference
This method must be paired with para.onStatePhaseChange() to handle portal URLs that appear after OAuth completes (e.g. passkey or password setup for returning users). See the guide for your platform for the full state listener pattern.
Cancelling Authentication
Both OAuth polling and session polling accept an isCanceled callback. Return true from isCanceled to stop the polling loop — for example, when the user dismisses the in-app browser or navigates away. The cancellation is clean: no error is thrown, and the optional onCancel callback fires.
const result = await para.authenticateWithOAuth({
method: "GOOGLE",
appScheme: APP_SCHEME,
oAuthPollingCallbacks: {
isCanceled: () => userClickedCancel,
onCancel: () => console.log("OAuth polling canceled"),
},
sessionPollingCallbacks: {
isCanceled: () => userClickedCancel,
onCancel: () => console.log("Session polling canceled"),
},
});
Calling para.logout() also cancels all active polling and resets the state phases back to unauthenticated. This is useful for implementing a “Cancel” button that fully resets the auth flow:
const handleCancel = async () => {
await para.logout();
// All polling stops, state phases reset to unauthenticated
};
Handling Results
authenticateWithOAuth() returns the same AuthenticateResponse as email/phone auth. See the authentication guide for full response type documentation.
Next Steps