To authenticate a user via Farcaster (SIWF), use the loginWithFarcaster method
from the useLoginWithFarcaster hook.To authenticate your users with Privy’s out of the box UIs, check out UI components here. loginWithFarcaster(input: {
relyingParty: string;
redirectUrl?: string;
disableSignup?: boolean;
}, config?: {
pollIntervalMs?: number;
pollAttempts?: number;
}): Promise<PrivyUser | null>;
Initializing the login flow
To initialize login, use the loginWithFarcaster function from the useLoginWithFarcaster hook to start the Farcaster login flow.import { useLoginWithFarcaster } from '@privy-io/expo';
const { loginWithFarcaster, state } = useLoginWithFarcaster();
As a parameter to loginWithFarcaster, you should pass an object containing:Your app’s website. Described in SIWF spec as “Origin domain of app frontend.”
A URL path that Farcaster will automatically redirect to after successful authentication. This defaults to a link back to your app root, eg. '/', if not provided.
If true, the flow will only allow existing users to log in, preventing new account creation.
The interval in milliseconds which your app will poll a status endpoint to check if the user has successfully signed in using Farcaster.
The number of polling attempts that will be made to check for successful login.
If you pass in custom polling configuration, make sure to give the user enough time to go through the login process on Farcaster. The default values are pollIntervalMs = 1000 and pollAttempts = 10 giving the user 10 seconds to go through the login process. In our testing, this is usually enough time, but you may want to make it longer.
When this method is invoked, the user will be deeplinked to the Farcaster app on their device if they have it installed, or an installation page for the app. Within the Farcaster app, they can complete the login flow.If loginWithFarcaster succeeds, it will return a PrivyUser object with details about the authenticated user.Reasons loginWithFarcaster might fail include:
- the network request fails
- the login attempt is made after the user is already logged in
- the user cancels the login flow after being linked out to Farcaster
- the user takes too long to login and the polling time expires
Tracking Flow State
Track the state of the Farcaster flow via the state variable returned by the useLoginWithFarcaster hook.state:
| {status: 'initial'}
| {status: 'error'; error: Error | null}
| {status: 'generating-uri'}
| {status: 'awaiting-uri'}
| {status: 'polling-status'}
| {status: 'submitting-token'}
| {status: 'done'};
status
'initial' | 'error' | 'generating-uri' | 'awaiting-uri' | 'polling-status' | 'submitting-token' | 'done'
The current state of the Farcaster flow.
The error that occurred during the Farcaster flow (only present when status is ‘error’).
Usage: Conditional Rendering
import { View, ActivityIndicator, Text } from 'react-native';
import { useLoginWithFarcaster, hasError } from '@privy-io/expo';
export function LoginScreen() {
const { state, loginWithFarcaster } = useLoginWithFarcaster();
return (
<View>
<Button
onPress={() => loginWithFarcaster({ relyingParty: 'https://example.app' })}
title="Login with Farcaster"
disabled={state.status !== 'initial' && state.status !== 'error'}
/>
{state.status === 'polling-status' && (
<View>
<ActivityIndicator />
<Text>Waiting for Farcaster confirmation...</Text>
</View>
)}
{hasError(state) && (
<Text style={{ color: 'red' }}>
Error: {state.error.message}
</Text>
)}
</View>
);
}
Callbacks
You can optionally pass callbacks to the useLoginWithFarcaster hook to run custom logic after a successful login or to handle errors.onSuccess
onSuccess: (user: PrivyUser, isNewUser: boolean) => Promise<void>
Parameters
The user object returned after successful login.
Whether the user is a new user or an existing user.
onError
onError: (error: Error) => Promise<void>
Parameters
The error that occurred during the Farcaster flow.
Usage with Callbacks
import { useLoginWithFarcaster } from '@privy-io/expo';
export function LoginScreen() {
const { loginWithFarcaster } = useLoginWithFarcaster({
onSuccess(user, isNewUser) {
console.log('Login successful', { user, isNewUser });
// Navigate to home screen, show welcome message, etc.
},
onError(error) {
console.error('Login failed', error);
// Show error toast, update UI, etc.
}
});
return (
<Button
onPress={() => loginWithFarcaster({ relyingParty: 'https://example.app' })}
title="Login with Farcaster"
/>
);
}
Resources