Skip to content
LogoLogo

Quickstart with Passkey recovery

Build a functional authentication and wallet sample app using the Openfort React Native SDK with biometric passkey recovery. This guide assumes you've completed the Getting Started guide and have your OpenfortProvider configured.

In this guide, we are going to help you set up your wallet recovery method to our Passkey method. These are our wallet recovery methods you can choose from:

Not sure what wallet recovery method you need? Don't miss our guide.

Get your Openfort keys

From this point on, you'll need an Openfort account to handle project keys and settings.

In the Openfort Dashboard, select your desired app and navigate to the API keys. There, you'll get the following keys:

Project keys: Required for any wallet.

KeyExposureDescription
Publishable keyPublic (client)Initialize the SDK (in OpenfortProvider).
Secret keySecret (server)Privileged backend actions (sessions, wallet management). Never bundle in the app or commit to git.

Shield Keys: Required for non-custodial wallets.

KeyExposureDescription
Publishable keyPublic (client)Public key the app uses to enable non‑custodial wallet features. Safe to include in client code.

Get the Project Publishable Key and the Shield Publishable Key and save them for the configuration steps below.

Install passkey dependencies

Install the required passkey library:

npm install react-native-passkeys

Then run prebuild to generate the native code:

npx expo prebuild --clean

Set up domain verification

Passkeys require HTTPS domain verification. For local development, use ngrok or a similar tunneling service.

Start ngrok tunnel

# In a separate terminal
ngrok http 8081

Save the ngrok URL (e.g., abc123.ngrok-free.app) — this will be your Relying Party ID (RP ID).

Configure environment variables

# .env
# Publishable keys
OPENFORT_PROJECT_PUBLISHABLE_KEY=YOUR_PROJECT_PUBLISHABLE_KEY
OPENFORT_SHIELD_PUBLISHABLE_KEY=YOUR_SHIELD_PUBLISHABLE_KEY
 
# Passkey configuration
PASSKEY_RP_ID=abc123.ngrok-free.app
PASSKEY_RP_NAME=Your App Name

Platform setup

Choose your target platform and follow the setup instructions.

Configure OpenfortProvider with passkey

Replace your basic provider setup with passkey configuration:

// app/_layout.tsx
import { OpenfortProvider, RecoveryMethod } from "@openfort/react-native";
import Constants from "expo-constants";
import { Stack } from "expo-router";
 
const {
  openfortPublishableKey,
  openfortShieldPublishableKey,
  passkeyRpId,
  passkeyRpName,
} = Constants.expoConfig?.extra ?? {};
 
export default function RootLayout() {
  return (
    <OpenfortProvider
      publishableKey={openfortPublishableKey}
      walletConfig={{
        debug: false,
        recoveryMethod: RecoveryMethod.PASSKEY,
        shieldPublishableKey: openfortShieldPublishableKey,
        passkeyRpId,
        passkeyRpName,
      }}
      verbose={true}
      supportedChains={[
        {
          id: 84532,
          name: 'Base Sepolia',
          nativeCurrency: {
            name: 'Base Sepolia Ether',
            symbol: 'ETH',
            decimals: 18
          },
          rpcUrls: { default: { http: ['https://sepolia.base.org'] } },
        },
      ]}
    >
      <Stack>
        <Stack.Screen name="index" />
      </Stack>
    </OpenfortProvider>
  );
}

Create the login and user screens

Create components that support passkey wallet creation and recovery:

// components/LoginScreen.tsx
import { OAuthProvider, useGuestAuth, useOAuth, usePasskeySupport } from "@openfort/react-native";
import { useEffect } from "react";
import { Button, Text, View, StyleSheet, ActivityIndicator } from "react-native";
 
export default function LoginScreen() {
  const { signUpGuest } = useGuestAuth();
  const { initOAuth, error: authError } = useOAuth();
  const { isSupported: passkeySupported, isLoading: passkeyLoading } = usePasskeySupport();
 
  useEffect(() => {
    if (authError) {
      console.error("[Openfort RN] Error logging in with OAuth:", authError);
    }
  }, [authError]);
 
  if (passkeyLoading) {
    return (
      <View style={styles.container}>
        <ActivityIndicator size="large" />
        <Text>Checking passkey support...</Text>
      </View>
    );
  }
 
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Openfort Passkey Example</Text>
 
      {passkeySupported ? (
        <Text style={styles.supportText}>Passkeys are supported on this device</Text>
      ) : (
        <Text style={styles.warningText}>Passkeys are not supported on this device</Text>
      )}
 
      <Button title="Login as Guest" onPress={() => signUpGuest()} />
 
      <View style={styles.providersContainer}>
        {[OAuthProvider.Google, OAuthProvider.Apple].map((provider) => (
          <View key={provider.toString()}>
            <Button
              title={`Login with ${provider.toString()}`}
              onPress={() => initOAuth({ provider })}
            />
          </View>
        ))}
      </View>
    </View>
  );
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    gap: 10,
    marginHorizontal: 10,
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
  },
  supportText: {
    color: "green",
    marginBottom: 10,
  },
  warningText: {
    color: "orange",
    marginBottom: 10,
  },
  providersContainer: {
    display: "flex",
    flexDirection: "column",
    gap: 5,
    margin: 10,
  },
});

Create your main app logic

Wire everything together:

// app/index.tsx
import LoginScreen from '../components/LoginScreen';
import { UserScreen } from '../components/UserScreen';
import { useUser } from '@openfort/react-native';
 
export default function Index() {
  const { user } = useUser();
  return !user ? <LoginScreen /> : <UserScreen />;
}

Build and run your app

Build and run on a physical device (passkeys require hardware security):

# Rebuild native code
npx expo prebuild --clean
npm run ios

Next steps

  • Add gas sponsorship policies for gasless transactions
  • Explore advanced wallet features in the React Native documentation
  • View our React Native sample app with passkey support:
View sample
View sample
View sample
React Native Sample
View our React Native sample with passkey recovery. A complete implementation of the Openfort SDK for React Native.