Follow the guide below to integrate your authentication provider with Privy.

Implementation

To integrate JWT-based authentication with Privy in your React application, you’ll need to use the useSubscribeToJwtAuthWithFlag 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.
// 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 both PrivyProvider, and your custom auth provider, call the useSubscribeToJwtAuthWithFlag hook to subscribe the Privy SDK to your auth provider’s state.
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;
}
This hook will observe state from your auth provider and update the Privy SDK’s authentication state accordingly. The hook itself (and the 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
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 the enabled flag to false in the hook configuration.
useSubscribeToJwtAuthWithFlag({
    enabled: false,
    isAuthenticated,
    // ...
});
Setting the 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.
For more advanced usage, or in cases where your auth provider lives outside React or otherwise offers no 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.
import { authStore } from 'your-auth-provider';
This object has a 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.
authStore.subscribe(() => {
    console.log('Auth state changed');
});
The store object also has a getState method that returns the current state, which we can use to get the current JWT token whenever necessary.
const authState = authStore.getState();
console.log('Is authenticated:', authState.isAuthenticated);
console.log('JWT token:', authState.token);
By using the useSyncJwtBasedAuthState hook, we can link Privy to the auth provider’s state store by using those two methods.
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:
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.