Web3Auth PnP React Native Quick Start
This guide is designed to help you quickly integrate a basic instance of Web3Auth Plug and Play in your React Native app.
If you face any problem anytime, you can always find help in the Web3Auth Community.
-
Clone the PnP React Native Quick Start Application
- npm
- Yarn
- pnpm
npx degit Web3Auth/web3auth-pnp-examples/tree/main/react-native/rn-bare-quick-start w3a-quick-start
yarn dlx degit Web3Auth/web3auth-pnp-examples/tree/main/react-native/rn-bare-quick-start w3a-quick-start
pnpm dlx degit Web3Auth/web3auth-pnp-examples/tree/main/react-native/rn-bare-quick-start w3a-quick-start
-
Install & Run
- npm
- Yarn
- pnpm
cd w3a-quick-start
npm install
npm run ios # or npm run androidcd w3a-quick-start
yarn install
yarn ios # or npm run androidcd w3a-quick-start
pnpm install
pnpm run ios # or npm run android
The Web3Auth React Native PnP SDK is not compatible with "Expo Go" app. It is compatible only with Custom Dev Client and EAS builds. Please refer to the troubleshooting section for more on this.
- Android API version
23
or newer is required. compileSdk
should be34
or newer.- Check
android/app/build.gradle
in your React Native project to change it.
- iOS 14+
- Xcode 11.4+ / 12.x
- Swift 4.x / 5.x
platform :ios
needs to be14.0
.- Check
ios/Podfile
in your React Native project to change it.
Install Web3Auth
Install the Web3Auth package in your React Native project.
- npm
- Yarn
- pnpm
npm install --save @web3auth/react-native-sdk @web3auth/base @web3auth/ethereum-provider
yarn add @web3auth/react-native-sdk @web3auth/base @web3auth/ethereum-provider
pnpm add @web3auth/react-native-sdk @web3auth/base @web3auth/ethereum-provider
Fixing Bundler Issues
While using Web3Auth in React Native, you may run into issues building. This issue occurs because some core packages like eccrypto
have certain
dependencies which are not present within the Metro build environment.
To solve this, please have a look at our troubleshooting page:
Get your Client ID from the Web3Auth Dashboard
Visit the Web3Auth Dashboard and create a new project. Use the Client ID of the project to start your integration.
Go to the Developer DashboardWhitelist Package & Bundle ID
To whitelist, you'll need to create a project or use an existing one in the Developer Dashboard.
-
Create or Select a Web3Auth project.
-
To Whitelist URLs section:
- Add
{SCHEME}://{YOUR_APP_PACKAGE_NAME}
forAndroid
, - and,
{bundleId}://auth
foriOS
to
- Add
Initialize Web3Auth
Web3Auth needs to be initialized as soon as your app loads up to enable the user to log in. Preferably done within a constructor, initialization is the step where you can pass on all the configurations for Web3Auth you want.
For initializing Web3Auth React Native SDK, you need to provide your Client ID, the Web3Auth Network of your project and the redirectUrl
for your
application. Make sure to set up Deep Linking so that the Web3Auth SDK can redirect the user back to your application after authentication.
Logging in your User
Use the login
function in the Web3Auth Instance to log in the user. Just create a button that
triggers the login
for the user of the login method of their choice.
After a successful user login, Web3Auth will redirect back to your app, with a payload stored in the state of the Web3Auth Instance.
Making Blockchain Calls
While using the Web3Auth React Native SDK, you get the private key within the user scope. This means that you can use it with any blockchain with their corresponding library within the React Native environment.
Have a look at our Connect Blockchain section of the documentation and choose your blockchain to get started.
In this example, we are using the Ethers library to make calls to the Ethereum blockchain. You can check out our Ethereum in React Native guide of the documentation to get started.
Log the user out
Use the logout
function of the Web3Auth Instance to log the user out.
- App.tsx
- package.json
- metro.config.js
- globals.js
- index.js
- build.gradle
- Podfile
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, View, Button, ScrollView, Dimensions, TextInput } from "react-native";
import "@ethersproject/shims";
import { ethers } from "ethers";
import * as WebBrowser from "@toruslabs/react-native-web-browser";
import EncryptedStorage from "react-native-encrypted-storage";
import Web3Auth, { LOGIN_PROVIDER, OPENLOGIN_NETWORK, ChainNamespace } from "@web3auth/react-native-sdk";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
const scheme = "web3authrnexample"; // Or your desired app redirection scheme
const redirectUrl = `${scheme}://openlogin`;
const clientId = "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ"; // get from https://dashboard.web3auth.io
const chainConfig = {
chainNamespace: ChainNamespace.EIP155,
chainId: "0xaa36a7",
rpcTarget: "https://rpc.ankr.com/eth_sepolia",
// Avoid using public rpcTarget in production.
// Use services like Infura, Quicknode etc
displayName: "Ethereum Sepolia Testnet",
blockExplorerUrl: "https://sepolia.etherscan.io",
ticker: "ETH",
tickerName: "Ethereum",
decimals: 18,
logo: "https://cryptologos.cc/logos/ethereum-eth-logo.png",
};
const ethereumPrivateKeyProvider = new EthereumPrivateKeyProvider({
config: {
chainConfig,
},
});
const web3auth = new Web3Auth(WebBrowser, EncryptedStorage, {
clientId,
redirectUrl,
network: OPENLOGIN_NETWORK.SAPPHIRE_MAINNET, // or other networks
});
export default function App() {
const [loggedIn, setLoggedIn] = useState(false);
const [provider, setProvider] = useState<any>(null);
const [console, setConsole] = useState<string>("");
const [email, setEmail] = useState<string>("");
useEffect(() => {
const init = async () => {
await web3auth.init();
if (web3auth.privKey) {
await ethereumPrivateKeyProvider.setupProvider(web3auth.privKey);
setProvider(ethereumPrivateKeyProvider);
setLoggedIn(true);
}
};
init();
}, []);
const login = async () => {
try {
if (!web3auth.ready) {
setConsole("Web3auth not initialized");
return;
}
if (!email) {
setConsole("Enter email first");
return;
}
setConsole("Logging in");
await web3auth.login({
loginProvider: LOGIN_PROVIDER.EMAIL_PASSWORDLESS,
extraLoginOptions: {
login_hint: email,
},
});
if (web3auth.privKey) {
await ethereumPrivateKeyProvider.setupProvider(web3auth.privKey);
setProvider(ethereumPrivateKeyProvider);
uiConsole("Logged In");
setLoggedIn(true);
}
} catch (e: any) {
setConsole(e.message);
}
};
const logout = async () => {
if (!web3auth.ready) {
setConsole("Web3auth not initialized");
return;
}
setConsole("Logging out");
await web3auth.logout();
if (!web3auth.privKey) {
setProvider(null);
uiConsole("Logged out");
setLoggedIn(false);
}
};
const getAccounts = async () => {
if (!provider) {
uiConsole("provider not set");
return;
}
setConsole("Getting account");
// For ethers v5
// const ethersProvider = new ethers.providers.Web3Provider(this.provider);
const ethersProvider = new ethers.BrowserProvider(provider!);
// For ethers v5
// const signer = ethersProvider.getSigner();
const signer = await ethersProvider.getSigner();
// Get user's Ethereum public address
const address = signer.getAddress();
uiConsole(address);
};
const getBalance = async () => {
if (!provider) {
uiConsole("provider not set");
return;
}
setConsole("Fetching balance");
// For ethers v5
// const ethersProvider = new ethers.providers.Web3Provider(this.provider);
const ethersProvider = new ethers.BrowserProvider(provider!);
// For ethers v5
// const signer = ethersProvider.getSigner();
const signer = await ethersProvider.getSigner();
// Get user's Ethereum public address
const address = signer.getAddress();
// Get user's balance in ether
// For ethers v5
// const balance = ethers.utils.formatEther(
// await ethersProvider.getBalance(address) // Balance is in wei
// );
const balance = ethers.formatEther(
await ethersProvider.getBalance(address) // Balance is in wei
);
uiConsole(balance);
};
const signMessage = async () => {
if (!provider) {
uiConsole("provider not set");
return;
}
setConsole("Signing message");
// For ethers v5
// const ethersProvider = new ethers.providers.Web3Provider(this.provider);
const ethersProvider = new ethers.BrowserProvider(provider!);
// For ethers v5
// const signer = ethersProvider.getSigner();
const signer = await ethersProvider.getSigner();
const originalMessage = "YOUR_MESSAGE";
// Sign the message
const signedMessage = await signer.signMessage(originalMessage);
uiConsole(signedMessage);
};
const launchWalletServices = async () => {
if (!web3auth) {
setConsole("Web3auth not initialized");
return;
}
setConsole("Launch Wallet Services");
await web3auth.launchWalletServices(chainConfig);
};
const uiConsole = (...args: unknown[]) => {
setConsole(JSON.stringify(args || {}, null, 2) + "\n\n\n\n" + console);
};
const loggedInView = (
<View style={styles.buttonArea}>
<Button title="Get User Info" onPress={() => uiConsole(web3auth.userInfo())} />
<Button title="Get Accounts" onPress={() => getAccounts()} />
<Button title="Get Balance" onPress={() => getBalance()} />
<Button title="Sign Message" onPress={() => signMessage()} />
<Button title="Show Wallet UI" onPress={() => launchWalletServices()} />
<Button title="Log Out" onPress={logout} />
</View>
);
const unloggedInView = (
<View style={styles.buttonAreaLogin}>
<TextInput style={styles.inputEmail} placeholder="Enter email" onChangeText={setEmail} />
<Button title="Login with Web3Auth" onPress={login} />
</View>
);
return (
<View style={styles.container}>
{loggedIn ? loggedInView : unloggedInView}
<View style={styles.consoleArea}>
<Text style={styles.consoleText}>Console:</Text>
<ScrollView style={styles.console}>
<Text>{console}</Text>
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
paddingTop: 50,
paddingBottom: 30,
},
consoleArea: {
margin: 20,
alignItems: "center",
justifyContent: "center",
flex: 1,
},
console: {
flex: 1,
backgroundColor: "#CCCCCC",
color: "#ffffff",
padding: 10,
width: Dimensions.get("window").width - 60,
},
consoleText: {
padding: 10,
},
buttonArea: {
flex: 2,
alignItems: "center",
justifyContent: "space-around",
paddingBottom: 30,
},
buttonAreaLogin: {
flex: 2,
alignItems: "center",
justifyContent: "center",
paddingBottom: 30,
},
inputEmail: {
height: 40,
width: 300,
borderColor: "gray",
borderWidth: 1,
padding: 10,
borderRadius: 5,
marginBottom: 20,
},
});