- React
- React Native
- Swift
- Android
- Flutter
Implementation
To integrate JWT-based authentication with Privy in your React application, you’ll need to use theuseSubscribeToJwtAuthWithFlag hook to subscribe the Privy SDK to your auth provider’s
state.Getting the state from your auth provider
To get the state from your auth provider, import the provider’s hook.Report incorrect code
Copy
Ask AI
// Import your auth provider's hook or state management
import { useAuth } from 'your-auth-provider';
// Get auth details from your provider
const { getToken, isLoading, isAuthenticated } = useAuth();
Subscribing to the auth provider’s state
In a component that lives below bothPrivyProvider, and your custom auth provider, call the
useSubscribeToJwtAuthWithFlag hook to subscribe the Privy SDK to your auth provider’s state.Report incorrect code
Copy
Ask AI
import { useAuth } from 'your-auth-provider';
import { useSubscribeToJwtAuthWithFlag } from '@privy-io/react-auth';
const MyStateSyncComponent = () => {
const { getToken, isLoading, isAuthenticated } = useAuth();
useSubscribeToJwtAuthWithFlag({
isAuthenticated,
isLoading,
getExternalJwt: async () => {
if (isAuthenticated) {
const token = await getToken();
return token;
}
}
})
return null;
}
MyStateSyncComponent component) should be mounted throughout the
lifetime of your app to ensure state is kept in sync.Integrate the provider with your app
Make sure to nest your custom provider inside your auth provider in your app structure:App.tsx
Report incorrect code
Copy
Ask AI
import { AuthProvider } from 'your-auth-provider';
import PrivyAuthProvider from './PrivyAuthProvider';
function App() {
return (
<AuthProvider>
<PrivyAuthProvider>
{/* Invocation of `useSubscribeToJwtAuthWithFlag` must be below both providers */}
<MyStateSyncComponent />
<MainContent />
</PrivyAuthProvider>
</AuthProvider>
);
}
export default App;
Disabling the external auth provider
If you want to disable the external auth provider, you can set theenabled flag to false in
the hook configuration.Report incorrect code
Copy
Ask AI
useSubscribeToJwtAuthWithFlag({
enabled: false,
isAuthenticated,
// ...
});
enabled flag to false will disable the external auth provider and will stop
Privy from attempting to synchronize its state with the external auth provider regardless of the
value of the isAuthenticated flag, until enabled is set to true again.Advanced Usage
This approach is not recommended for most use cases, as it increases the complexity of setup significantly and
can result in state synchronization issues if used incorrectly.Always prefer the flag-based approach when possible if your auth provider offers an
isAuthenticated flag.isAuthenticated flag, you can use the useSyncJwtBasedAuthState hook to subscribe to
the auth provider’s state via state listeners.Let’s say the library for your auth provider exports an authStore object that holds state.Report incorrect code
Copy
Ask AI
import { authStore } from 'your-auth-provider';
subscribe method that takes a callback, and invokes it every time the
auth state changes, most importantly when the user either logs in or out.Report incorrect code
Copy
Ask AI
authStore.subscribe(() => {
console.log('Auth state changed');
});
getState method that returns the current state, which we can use to
get the current JWT token whenever necessary.Report incorrect code
Copy
Ask AI
const authState = authStore.getState();
console.log('Is authenticated:', authState.isAuthenticated);
console.log('JWT token:', authState.token);
useSyncJwtBasedAuthState hook, we can link Privy to the auth provider’s state store
by using those two methods.Report incorrect code
Copy
Ask AI
import { useSyncJwtBasedAuthState } from '@privy-io/react-auth';
import { authStore } from 'your-auth-provider';
useSyncJwtBasedAuthState({
subscribe: (onAuthStateChange) => {
const unsubscribe = authStore.subscribe((state) => {
onAuthStateChange(); // Notify Privy of the auth state change.
});
return unsubscribe; // Return the `unsubscribe` to avoid memory leaks.
},
getExternalJwt: () => {
const authState = authStore.getState();
if (authState.isAuthenticated) {
return authState.token;
}
}
})
Accessing User Authentication Status
Once configured, you can access the user’s authentication status through the Privy SDK:Report incorrect code
Copy
Ask AI
import { usePrivy } from '@privy-io/react-auth';
function MainContent() {
const { user, ready, authenticated } = usePrivy();
if (!ready) {
return <div>Loading...</div>;
}
if (!authenticated) {
return <div>Please log in through your authentication provider</div>;
}
return (
<div>
<p>Welcome, authenticated user!</p>
<p>User ID: {user.id}</p>
</div>
);
}
When using a custom authentication provider, you should not use the Privy
login method (from useLogin or usePrivy). Instead, call the login method of your custom provider, and the Privy SDK will automatically synchronize its state.Implementation
To integrate JWT-based authentication with Privy in your React Native application, you’ll need to create a customPrivyProvider wrapper that supplies your auth token to Privy.Create a custom PrivyProvider wrapper
Create a component that wraps the PrivyProvider with your custom auth configuration:PrivyAuthProvider.tsx
Report incorrect code
Copy
Ask AI
import { useCallback, PropsWithChildren } from 'react';
import { PrivyProvider } from '@privy-io/expo';
// Import your auth provider's hook or state management
import { useAuth0 } from 'react-native-auth0';
const PrivyAuthProvider: React.FC<PropsWithChildren> = ({ children }) => {
// Get auth details from your auth provider
const { user: auth0User, isLoading, getCredentials } = useAuth0();
// Create a callback to get the token
const getCustomToken = useCallback(async () => {
// Your logic to retrieve the JWT token from your auth provider
try {
const creds = await getCredentials();
return creds?.idToken;
} catch (error) {
// If there's an error, the user is likely not authenticated
return undefined;
}
}, [isLoading, auth0User, getCredentials]); // Re-create when auth state changes
return (
<PrivyProvider
appId='your-privy-app-id'
config={{
customAuth: {
enabled: true,
// Indicates if your auth provider is currently updating auth state
isLoading: isLoading,
// Callback to get the user's JWT token
getCustomAccessToken: getCustomToken,
}
}}
>
{children}
</PrivyProvider>
);
};
export default PrivyAuthProvider;
Integrate the provider with your app
Make sure to nest your custom provider inside your auth provider in your app structure:App.tsx
Report incorrect code
Copy
Ask AI
import { Auth0Provider } from 'react-native-auth0';
import PrivyAuthProvider from './PrivyAuthProvider';
function App() {
return (
<Auth0Provider
domain="your-domain.auth0.com"
clientId="your-client-id"
>
{/* Our custom wrapper must be nested inside your AuthProvider */}
<PrivyAuthProvider>
{/* Your app content */}
<MainContent />
</PrivyAuthProvider>
</Auth0Provider>
);
}
export default App;
Accessing User Authentication Status
Once configured, you can access the user’s authentication status through the Privy SDK:Report incorrect code
Copy
Ask AI
import { usePrivy } from '@privy-io/expo';
import { View, Text } from 'react-native';
function MainContent() {
const { user, ready } = usePrivy();
if (!ready) {
return <Text>Loading...</Text>;
}
if (!user) {
return <Text>Please log in through your authentication provider</Text>;
}
return (
<View>
<Text>Welcome, authenticated user!</Text>
<Text>User ID: {user.id}</Text>
</View>
);
}
When using a custom authentication provider in React Native, you should let your auth provider handle the authentication flow. Privy will automatically synchronize its state based on the token provided by your
getCustomAccessToken callback.Implementation
To integrate JWT-based authentication with Privy in your Swift application, you’ll need to initialize the Privy SDK with a token provider callback and handle authentication.Initialize Privy with a token provider callback
First, initialize the Privy SDK with atokenProvider callback that will provide the JWT from your custom auth provider:Privy initialization with custom auth
Report incorrect code
Copy
Ask AI
let privy = PrivyConfig(
appId: "YOUR_APP_ID",
appClientId: "YOUR_APP_CLIENT_ID",
customAuthConfig: PrivyLoginWithCustomAuthConfig {
// Client logic to provide the JWT
// This might involve network requests or accessing secure storage
return await fetchAccessTokenFromAuthProvider()
}
)
Example token provider implementation
Report incorrect code
Copy
Ask AI
private func fetchAccessTokenFromAuthProvider() async throws -> String? {
// Your custom logic to retrieve the JWT token
// This might be from shared preferences, secure storage, or an API call
try await yourAuthManager.getAccessToken()
}
tokenProvider callback should:- Return the current user’s access token as a
Stringwhen authenticated - Return
nilwhen the user is not authenticated
Authenticate your user
Once you have defined atokenProvider callback, authenticate your user with Privy using the loginWithCustomAccessToken method:Authenticating with Privy
Report incorrect code
Copy
Ask AI
do {
try await privy.customJwt.loginWithCustomAccessToken()
// User is now authenticated with Privy
} catch {
// Handle authentication errors
print("Failed to authenticate with Privy: \(error)")
}
Example with Auth0
Here’s an example using Auth0’s Swift SDK for authentication:Auth0 Integration Example
Report incorrect code
Copy
Ask AI
// Store the Auth0 token
var auth0Token: String? = nil
// Set up the token provider to return the stored token
let config = PrivyConfig(
appId: "YOUR_APP_ID",
appClientId: "YOUR_APP_CLIENT_ID",
customAuthConfig: PrivyLoginWithCustomAuthConfig {
return auth0Token
}
)
// Handle Auth0 authentication
Auth0.webAuth().start { result in
if case .success(let credentials) = result {
auth0Token = credentials.accessToken
Task {
do {
// Authenticate with Privy using the token
try await privy.customJwt.loginWithCustomAccessToken()
// Now the user is authenticated with Privy
// You can access their wallet and other features
} catch {
print("Privy authentication failed: \(error)")
}
}
} else {
print("Auth0 authentication failed")
}
}
Authentication Flow
When using custom authentication with the Swift SDK:- When the Privy SDK is first initialized, it attempts to restore any prior session
- If a prior session exists, Privy automatically tries to reauthenticate using your
tokenProvider - You can manually trigger authentication by calling
loginWithCustomAccessToken - After successful authentication, you have access to the
PrivyUserobject and wallet functionality
When your app starts up, as soon as you determine your user is authenticated via your custom auth provider, you should call Privy’s
loginWithCustomAccessToken method to synchronize the authentication state.Accessing User Data
Once authenticated, you can access the user’s data and embedded wallets:Report incorrect code
Copy
Ask AI
// Check if user is authenticated
if let user = privy.user {
// Access user information
let userId = user.id
// Access embedded wallets
if let wallet = user.embeddedEthereumWallets.first {
let walletAddress = wallet.address
print("User has Ethereum wallet with address: \(walletAddress)")
}
}
sub claim of their access token). You can view all users in the Users section of the Privy Developer Dashboard.Implementation
To integrate JWT-based authentication with Privy in your Android application, you’ll need to initialize the Privy SDK with a token provider callback and handle authentication.Initialize Privy with a token provider callback
First, initialize the Privy SDK with atokenProvider callback that will provide the JWT from your custom auth provider:Privy initialization with custom auth
Report incorrect code
Copy
Ask AI
private val privy: Privy = Privy.init(
context = applicationContext, // Be sure to only pass in Application context
config = PrivyConfig(
appId = "YOUR_APP_ID",
appClientId = "YOUR_APP_CLIENT_ID",
logLevel = PrivyLogLevel.NONE,
customAuthConfig = LoginWithCustomAuthConfig(
tokenProvider = {
// Return the user's access token if they're authenticated
// Or return null if they're not authenticated
fetchTokenFromAuthProvider()
}
)
)
)
// Example token provider implementation
private suspend fun fetchTokenFromAuthProvider(): String? {
return try {
// Your custom logic to retrieve the JWT token
// This might be from shared preferences, secure storage, or an API call
yourAuthManager.getAccessToken()
} catch (e: Exception) {
// If there's an error, the user is likely not authenticated
null
}
}
tokenProvider callback should:- Return the current user’s access token as a
Stringwhen authenticated - Return
nullwhen the user is not authenticated - Be implemented as a suspending function that can perform asynchronous operations
Authenticate your user
Once you’ve initialized Privy with atokenProvider callback, authenticate your user with Privy using the loginWithCustomAccessToken method:Authenticating with Privy
Report incorrect code
Copy
Ask AI
// Make sure to call this in a coroutine scope
val privyLoginResult = privy.customAuth.loginWithCustomAccessToken()
privyLoginResult.fold(
onSuccess = { user ->
Log.d("Privy", "Privy login success! User: ${user}")
// Now you can access user information and wallet functionality
},
onFailure = { error ->
Log.d("Privy", "Privy login failure! $error")
// Handle authentication error
}
)
Result.success with the PrivyUser object. If the token is invalid, it will return a Result.failure.Example integration with Auth0
Here’s an example of integrating with Auth0 for Android:Auth0 Integration Example
Report incorrect code
Copy
Ask AI
private val auth0 = Auth0(
clientId = "YOUR_AUTH0_CLIENT_ID",
domain = "YOUR_AUTH0_DOMAIN"
)
// Store the Auth0 token
private var auth0Token: String? = null
// Initialize Privy with token provider that returns the Auth0 token
private val privy = Privy.init(
context = applicationContext,
config = PrivyConfig(
appId = "YOUR_PRIVY_APP_ID",
appClientId = "YOUR_PRIVY_APP_CLIENT_ID",
customAuthConfig = LoginWithCustomAuthConfig(
tokenProvider = { auth0Token }
)
)
)
// Authenticate with Auth0, then with Privy
private fun authenticateUser() {
val callback = object : Callback<Credentials, AuthenticationException> {
override fun onSuccess(credentials: Credentials) {
// Store the token
auth0Token = credentials.accessToken
// Authenticate with Privy
lifecycleScope.launch {
val privyResult = privy.customAuth.loginWithCustomAccessToken()
privyResult.fold(
onSuccess = { user ->
Log.d("Auth", "Successfully authenticated with Privy")
// Proceed with authenticated user
},
onFailure = { error ->
Log.e("Auth", "Failed to authenticate with Privy", error)
}
)
}
}
override fun onFailure(error: AuthenticationException) {
Log.e("Auth", "Auth0 authentication failed", error)
}
}
// Start Auth0 authentication
WebAuthProvider.login(auth0)
.withScheme("demo")
.start(this, callback)
}
Authentication flow
When using custom authentication with the Android SDK:- When the Privy SDK is first initialized, it attempts to restore any prior session
- If a prior session exists, Privy automatically tries to reauthenticate using your
tokenProvider - You can manually trigger authentication by calling
loginWithCustomAccessToken - After successful authentication, you have access to the
PrivyUserobject and wallet functionality
It’s important to await the
privy.awaitReady() call before triggering any other Privy flows to ensure the SDK has completed initialization and attempted session restoration.Accessing user data and wallets
Once authenticated, you can access the user’s data and embedded wallets:Report incorrect code
Copy
Ask AI
// Check if user is authenticated
val user = privy.user
if (user != null) {
// Access user information
val userId = user.id
// Access embedded Ethereum wallets
val ethereumWallets = user.embeddedEthereumWallets
if (ethereumWallets.isNotEmpty()) {
val walletAddress = ethereumWallets.first().address
Log.d("Wallet", "User has Ethereum wallet with address: $walletAddress")
}
}
sub claim of their access token). You can view all users in the Users section of the Privy Developer Dashboard.Implementation
To integrate JWT-based authentication with Privy in your Flutter application, you’ll need to initialize the Privy SDK with a token provider callback and handle authentication.Initialize Privy with a token provider callback
First, initialize the Privy SDK with atokenProvider callback that will provide the JWT from your custom auth provider:Privy initialization with custom auth
Report incorrect code
Copy
Ask AI
// Define a function to retrieve the token from your auth provider
Future<String?> _retrieveCustomAuthAccessToken() async {
// Implement logic to fetch the access token from your auth provider
// Return the token if the user is authenticated, or null if not
try {
// Your custom logic to retrieve the JWT token
// This might be from secure storage or an API call
final token = await yourAuthService.getAccessToken();
return token;
} catch (e) {
// If there's an error, the user is likely not authenticated
return null;
}
}
// Initialize Privy with the token provider
final privyConfig = PrivyConfig(
appId: "YOUR_APP_ID",
appClientId: "YOUR_APP_CLIENT_ID",
logLevel: PrivyLogLevel.NONE,
customAuthConfig: LoginWithCustomAuthConfig(
tokenProvider: _retrieveCustomAuthAccessToken,
),
);
final privy = Privy(config: privyConfig);
tokenProvider callback should:- Return the current user’s access token as a
Stringwhen authenticated - Return
nullwhen the user is not authenticated - Be implemented as an async function that can perform asynchronous operations
Await SDK readiness
Before performing any operations with the SDK, make sure to await its readiness:Awaiting SDK readiness
Report incorrect code
Copy
Ask AI
// Wait for the SDK to be ready before proceeding
await privy.awaitReady();
Authenticate your user
Once you’ve initialized Privy with atokenProvider callback, authenticate your user with Privy using the loginWithCustomAccessToken method:Authenticating with Privy
Report incorrect code
Copy
Ask AI
// Authenticate with Privy
final result = await privy.customAuth.loginWithCustomAccessToken();
result.fold(
onSuccess: (user) {
print("Privy login success! User: ${user}");
// Now you can access user information and wallet functionality
},
onFailure: (error) {
print("Privy login failure! ${error.message}");
// Handle authentication error
},
);
Success() with an encapsulated PrivyUser. If the token is invalid, it will return a Failure() with a PrivyException.Example integration with Firebase Auth
Here’s an example of integrating with Firebase Authentication:Firebase Auth Integration Example
Report incorrect code
Copy
Ask AI
import 'package:firebase_auth/firebase_auth.dart';
import 'package:privy_flutter/privy_flutter.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
late final Privy _privy;
// Initialize Privy with Firebase token provider
Future<void> initPrivy() async {
final privyConfig = PrivyConfig(
appId: "YOUR_PRIVY_APP_ID",
appClientId: "YOUR_PRIVY_APP_CLIENT_ID",
logLevel: PrivyLogLevel.NONE,
customAuthConfig: LoginWithCustomAuthConfig(
tokenProvider: _getFirebaseIdToken,
),
);
_privy = Privy(config: privyConfig);
// Wait for Privy to be ready
await _privy.awaitReady();
}
// Firebase token provider function
Future<String?> _getFirebaseIdToken() async {
try {
final user = _auth.currentUser;
if (user == null) return null;
// Get the ID token
return await user.getIdToken();
} catch (e) {
print("Error getting Firebase ID token: $e");
return null;
}
}
// Sign in with Firebase, then with Privy
Future<Result<PrivyUser>> signInWithEmailAndPassword(String email, String password) async {
try {
// Sign in with Firebase
await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
// After Firebase auth succeeds, authenticate with Privy
return await _privy.customAuth.loginWithCustomAccessToken();
} catch (e) {
return Result.failure(AuthError("Firebase authentication failed: $e"));
}
}
}
Authentication flow
When using custom authentication with the Flutter SDK:- When the Privy SDK is first initialized, it attempts to restore any prior session
- If a prior session exists, Privy automatically tries to reauthenticate using your
tokenProvider - You can manually trigger authentication by calling
loginWithCustomAccessToken - After successful authentication, you have access to the
PrivyUserobject and wallet functionality
It’s important to
await privy.awaitReady() before triggering any other Privy flows to ensure the SDK has completed initialization and attempted session restoration.Accessing user data and wallets
Once authenticated, you can access the user’s data and embedded wallets:Report incorrect code
Copy
Ask AI
// Check if user is authenticated
final user = privy.user;
if (user != null) {
// Access user information
final userId = user.id;
// Access embedded Ethereum wallets
final ethereumWallets = user.embeddedEthereumWallets;
if (ethereumWallets.isNotEmpty) {
final walletAddress = ethereumWallets.first.address;
print("User has Ethereum wallet with address: $walletAddress");
}
}
sub claim of their access token). You can view all users in the Users section of the Privy Developer Dashboard.
