Quickstart with Automatic recovery
Build a functional authentication and wallet sample app using the Openfort React Native SDK.
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 Automatic
method.
These are our wallet recovery methods you can choose from:
- Using Automatic Recovery
- Switch to Password Recovery
- Passkey recovery (coming soon)
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.
Key | Exposure | Description |
---|---|---|
Publishable key | Public (client) | Initialize the SDK (e.g., in OpenfortProvider ). |
Secret key | Secret (server) | Privileged backend actions (e.g., sessions, wallet management). Never bundle in the app or commit to git. |
Shield Keys: Required for non-custodial wallets.
Key | Exposure | Description |
---|---|---|
Encryption part (one-time) | Secret | Server-only key that encrypts/decrypts sensitive wallet data. Store in a key manager; if lost, data can't be recovered. |
Publishable key | Public (client) | Public key the app uses to enable non‑custodial wallet features. Safe to include in client code. |
Secret key | Secret (server) | Server-only key for sensitive wallet operations (e.g., starting encryption or recovery). Never ship in the app; store in a secret manager. |
Get the Project Publishable Key and the Shield Publishable Key and save them for the configuration steps below. Save the secret keys safely for your backend.
Set up the recovery endpoint (only for Automatic recovery)
Create a backend endpoint that issues a Shield encryption session used to recover wallets.
Option 1: One‑click deploy
Use our prebuilt endpoint and deploy in one click on Cloudflare or Vercel as a function.
Option 2: Implement your own backend
Use this option if you have your backend set up and can add an extra endpoint.
Endpoint examples for you to copy
Expose a GET endpoint /api/shield-session
that returns { "session": "<session_id>" }
. Use one of the examples below.
import express, { Request, Response } from 'express';
// Initialize the Openfort client
const openfort = require("@openfort/openfort-node")(process.env.OPENFORT_SECRET_KEY);
// Use your own middleware (JWT, sessions, API key, etc.) to authenticate the user here
export const authenticateUser = (req: Request, res: Response, next: NextFunction) => {
// Example: req.user = { id: 'user_123', email: 'user@example.com' };
return next();
};
const router = express.Router();
router.get('/api/shield-session', authenticateUser, async (req: Request, res: Response) => {
try {
const session = await openfort.registerRecoverySession(
process.env.OPENFORT_SHIELD_PUBLISHABLE_KEY as string,
process.env.OPENFORT_SHIELD_SECRET_KEY as string,
process.env.OPENFORT_SHIELD_ENCRYPTION_SHARE as string
);
res.status(200).json({ session });
} catch (e) {
console.error(e);
res.status(500).json({ error: 'Internal server error' });
}
});
export default router;
After setting up the /api/shield-session
endpoint, save the full endpoint URL for the next step.
Configure environment variables
# .env
# Publishable keys
OPENFORT_PROJECT_PUBLISHABLE_KEY=YOUR_PROJECT_PUBLISHABLE_KEY
OPENFORT_SHIELD_PUBLISHABLE_KEY=YOUR_SHIELD_PUBLISHABLE_KEY
# Automatic recovery endpoint
OPENFORT_SHIELD_RECOVERY_ENDPOINT=https://your-backend.com/api/shield-session
# Gas sponsorship policy
OPENFORT_POLICY_ID=YOUR_POLICY_ID
Create app.config.js
to manage your Openfort keys securely:
// app.config.js
export default {
expo: {
name: "openfort-sample",
slug: "openfort-sample",
version: "1.0.0",
platforms: ["ios", "android"],
extra: {
openfortPublishableKey: process.env.OPENFORT_PROJECT_PUBLISHABLE_KEY || "YOUR_PROJECT_PUBLISHABLE_KEY",
openfortShieldPublishableKey: process.env.OPENFORT_SHIELD_PUBLISHABLE_KEY || "YOUR_SHIELD_PUBLISHABLE_KEY",
openfortShieldRecoveryEndpoint: process.env.OPENFORT_SHIELD_RECOVERY_ENDPOINT || "https://your-backend.com/api/shield-session",
openfortPolicyId: process.env.OPENFORT_POLICY_ID || "YOUR_POLICY_ID",
},
},
};
Replace your Openfort Provider
Replace your basic provider setup with a more comprehensive configuration:
// app/_layout.tsx
import { OpenfortProvider, RecoveryMethod } from "@openfort/react-native";
import Constants from "expo-constants";
import { Stack } from "expo-router";
export default function RootLayout() {
return (
<OpenfortProvider
publishableKey={Constants.expoConfig?.extra?.openfortPublishableKey}
walletConfig={{
debug: false,
recoveryMethod: RecoveryMethod.AUTOMATIC, // or RecoveryMethod.PASSWORD
ethereumProviderPolicyId: Constants.expoConfig?.extra?.openfortPolicyId,
shieldPublishableKey: Constants.expoConfig?.extra?.openfortShieldPublishableKey,
createEncryptedSessionEndpoint: Constants.expoConfig?.extra?.openfortShieldRecoveryEndpoint,
}}
verbose={true}
supportedChains={[
{
id: 84532,
name: 'Base Sepolia',
nativeCurrency: {
name: 'Base Sepolia Ether',
symbol: 'ETH',
decimals: 18
},
rpcUrls: { default: { http: ['https://sepolia.base.org'] } },
},
{
id: 11155111,
name: 'Sepolia',
nativeCurrency: {
name: 'Sepolia Ether',
symbol: 'ETH',
decimals: 18
},
rpcUrls: { default: { http: ['https://ethereum-sepolia-rpc.publicnode.com'] } },
},
]}
>
<Stack>
<Stack.Screen name="index" />
</Stack>
</OpenfortProvider>
);
}
Create the login and user screens
Create the login component that handles multiple authentication methods and the user dashboard component that allows wallet creation and message signing:
// components/LoginScreen.tsx
import { OAuthProvider, useGuestAuth, useOAuth } from "@openfort/react-native";
import { useEffect } from "react";
import { Button, Text, View, StyleSheet } from "react-native";
export default function LoginScreen() {
const { signUpGuest } = useGuestAuth();
const { initOAuth, error: authError } = useOAuth();
const SELECTED_PROVIDERS = [
OAuthProvider.GOOGLE,
OAuthProvider.TWITTER,
OAuthProvider.DISCORD,
OAuthProvider.APPLE,
]
useEffect(() => {
if (authError) {
console.error("[Openfort RN] Error logging in with OAuth:", authError);
}
}, [authError]);
const handleSignUpGuest = () => {
signUpGuest()
.catch((error) => {
console.error("[Openfort RN] Error signing up guest:", error);
});
};
const handleLoginWithOAuth = async (provider: OAuthProvider) => {
initOAuth({ provider });
};
return (
<View style={styles.container}>
<Text style={styles.title}>Openfort Expo Example</Text>
<Button
title="Login as Guest"
onPress={handleSignUpGuest}
/>
<View style={styles.providersContainer}>
{SELECTED_PROVIDERS.map((provider) => (
<View key={provider.toString()}>
<Button
title={`Login with ${provider.toString()}`}
onPress={() => handleLoginWithOAuth(provider)}
/>
</View>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: 10,
marginHorizontal: 10,
},
title: {
fontSize: 20,
fontWeight: "bold",
},
providersContainer: {
display: "flex",
flexDirection: "column",
gap: 5,
margin: 10,
},
});
Create your main app logic
Wire everything together with the main app component:
// app/index.tsx
import LoginScreen from '../components/LoginScreen';
import { UserScreen } from '../components/UserScreen';
import { useOpenfort } from '@openfort/react-native';
export default function Index() {
const { user } = useOpenfort();
if (user === null) {
console.warn('Tried to fetch user from Openfort. The user is not authenticated yet.');
} else {
console.log('Fetched user from Openfort:', user);
}
return !user ? <LoginScreen /> : <UserScreen />;
}
Test your app
Run your app to test authentication, wallet creation, and message signing:
npm run android
# or
npm run ios
The app will show:
- Login Screen: Authentication options (guest, OAuth providers)
- User Dashboard: Simple wallet creation and message signing
Activate logging in with authentication providers
You will now see the option to login with various auth providers, these need to be set up in the Openfort Dashboard in order for them to work.
From the Openfort Dashboard, select your desired app and navigate to Configuration > Providers. Select the account types you'd like users to be able to login with: Email, Discord, Epic Games, Google, Apple and more.
Next steps
- Add gas sponsorship policies for gasless transactions
- Explore advanced wallet features in the React Native documentation
- View our React Native sample app to see the full functionality of the SDK: