When asking for help in this category, please make sure to provide the following details:
I’m trying to build and integrate a very basic web3auth flow for my react native expo app that I’m running in an android emulator. I’m familiar with web3auth on web but new to mobile and react native expo.
I’ve the below packages and piece of code. And the error I’m running into.
I’ve also added polyfills so as to avoid any compatibility issues.
Any help would be highly appreciated.
Let me know if any more information is needed from my end.
Package.json -
{
“name”: “fortify”,
“main”: “expo-router/entry”,
“version”: “1.0.0”,
“scripts”: {
“start”: “expo start”,
“reset-project”: “node ./scripts/reset-project.js”,
“android”: “expo run:android”,
“ios”: “expo run:ios”,
“web”: “expo start --web”,
“lint”: “expo lint”
},
“dependencies”: {
“@expo/vector-icons”: “^15.0.2”,
“@react-navigation/bottom-tabs”: “^7.4.0”,
“@react-navigation/elements”: “^2.6.3”,
“@react-navigation/native”: “^7.1.8”,
“@web3auth/react-native-sdk”: “^8.1.0”,
“@web3auth/solana-provider”: “^9.7.0”,
“buffer”: “^6.0.3”,
“expo”: “54.0.13”,
“expo-camera”: “~17.0.8”,
“expo-constants”: “~18.0.9”,
“expo-font”: “~14.0.9”,
“expo-haptics”: “~15.0.7”,
“expo-image”: “~3.0.9”,
“expo-linear-gradient”: “^15.0.7”,
“expo-linking”: “~8.0.8”,
“expo-router”: “~6.0.12”,
“expo-secure-store”: “~15.0.7”,
“expo-splash-screen”: “~31.0.10”,
“expo-status-bar”: “~3.0.8”,
“expo-symbols”: “~1.0.7”,
“expo-system-ui”: “~6.0.7”,
“expo-web-browser”: “~15.0.8”,
“react”: “19.1.0”,
“react-dom”: “19.1.0”,
“react-native”: “0.81.4”,
“react-native-gesture-handler”: “~2.28.0”,
“react-native-qrcode-svg”: “^6.3.15”,
“react-native-quick-crypto”: “^0.7.17”,
“react-native-reanimated”: “~4.1.1”,
“react-native-safe-area-context”: “~5.6.0”,
“react-native-screens”: “~4.16.0”,
“react-native-svg”: “15.12.1”,
“react-native-web”: “~0.21.0”,
“react-native-worklets”: “0.5.1”
},
“devDependencies”: {
“@types/react”: “~19.1.0”,
“eslint”: “^9.25.0”,
“eslint-config-expo”: “~10.0.0”,
“typescript”: “~5.9.2”
},
“private”: true
}
App.tsx -
import { CHAIN_NAMESPACES } from “@web3auth/base”;
import Web3Auth, { WEB3AUTH_NETWORK } from “@web3auth/react-native-sdk”;
import { SolanaPrivateKeyProvider } from “@web3auth/solana-provider”;
import * as Linking from “expo-linking”;
import * as SecureStore from “expo-secure-store”;
import * as WebBrowser from “expo-web-browser”;
import { useEffect, useRef } from “react”;
import { Platform, StyleSheet, Text, View } from “react-native”;
import { Button } from “…/components/ui”;
import “…/globals”;
const clientId = process.end.clientId;
export default function Index() {
const web3authRef = useRef<Web3Auth | null>(null);
useEffect(() => {
let disposed = false;
const initWeb3Auth = async () => {
if (!clientId) {
console.warn("Missing EXPO_PUBLIC_WEB3AUTH_CLIENT_ID for Web3Auth initialization.");
return;
}
// Configure Web3Auth to target Solana on the devnet cluster.
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.SOLANA,
chainId: "0x3",
rpcTarget: "https://api.devnet.solana.com",
displayName: "Solana Devnet",
blockExplorerUrl: "https://explorer.solana.com",
ticker: "SOL",
tickerName: "Solana",
decimals: 9,
} as const;
const privateKeyProvider = new SolanaPrivateKeyProvider({
config: { chainConfig },
});
const redirectUrl = Linking.createURL("auth", { scheme: "fortify" });
try {
const web3auth = new Web3Auth(WebBrowser, SecureStore, {
clientId,
network: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
redirectUrl: Platform.select({ default: redirectUrl }) ?? redirectUrl,
privateKeyProvider,
});
await web3auth.init();
if (!disposed) {
web3authRef.current = web3auth;
}
} catch (error) {
console.error("Failed to initialize Web3Auth", error);
}
};
initWeb3Auth();
return () => {
disposed = true;
web3authRef.current = null;
};
}, []);
const navigateToAuth = () => {
console.log(“Navigating to auth…”);
};
return (
Fortify
Asset Growth Platform
<View style={styles.buttonContainer}>
<Button
title="Get Started"
onPress={navigateToAuth}
style={styles.button}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: “center”,
alignItems: “center”,
padding: 24,
backgroundColor: “#1E293B”,
},
title: {
fontSize: 48,
fontWeight: “bold”,
color: “#FFFFFF”,
marginBottom: 8,
},
subtitle: {
fontSize: 18,
color: “rgba(255, 255, 255, 0.7)”,
marginBottom: 48,
textAlign: “center”,
},
buttonContainer: {
width: “100%”,
gap: 16,
},
button: {
width: “100%”,
},
});
Globals.js -
global.Buffer = require(“buffer”).Buffer;
// eslint-disable-next-line import/first
import { install } from “react-native-quick-crypto”;
install();
// Needed so that ‘stream-http’ chooses the right default protocol.
global.location = {
protocol: “file:”,
};
global.process.version = “v16.0.0”;
if (!global.process.version) {
global.process = require(“process”);
console.log({ process: global.process });
}
process.browser = true;
metro.config.js -
// Learn more Metro bundler - Expo Documentation
const { getDefaultConfig } = require(“expo/metro-config”);
/** @type {import(‘expo/metro-config’).MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.extraNodeModules = {
buffer: require.resolve(“buffer”)
};
config.transformer.getTransformOptions = () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true
}
});
module.exports = config;
Error faced -
All im seeing is a black screen on the emulator.