For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at the same URL with .md appended (or via Accept: text/markdown).
Skip to main content

Embedded Wallets SDK for React Native

Overview​

The MetaMask Embedded Wallets SDK for React Native lets you add social login and embedded wallet functionality to your iOS and Android apps. Version 9 is a hooks-first API: you wrap your app in a Web3AuthProvider and access all functionality through React hooks, no class instance, no useEffect-based initialisation.

Migration from v8 or earlier

Use the React Native migration guide. It includes an LLM agent prompt, a full legacy-to-v9 API map, and step-by-step file targets for any prior @web3auth/react-native-sdk version.

Requirements​

  • React Native 0.71 or later (bare workflow)
  • Expo SDK 48 or later (managed workflow)
  • iOS 14 or later
  • Android API level 31 or later (target SDK)

Prerequisites​

Set up your project on the Embedded Wallets dashboard:

  1. Create a new project and copy the Client ID.
  2. Go to Allowed Origins and add your app's deep link scheme (for example, web3authrnexample://auth).

See the dashboard setup guide for more detail.

Installation​

1. Install the SDK​

npm install @web3auth/react-native-sdk

2. Install helper modules​

The SDK requires a WebBrowser and a persistent Storage implementation. The correct packages differ between bare React Native and Expo:

npm install @toruslabs/react-native-web-browser react-native-encrypted-storage
npm install --save-dev @babel/plugin-transform-export-namespace-from

3. Android setup​

In your android/app/build.gradle, ensure the compile SDK version is 31 or higher:

android/app/build.gradle
compileSdkVersion = 31
targetSdkVersion = 31

Add the intent filter with your custom scheme to AndroidManifest.xml:

AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- replace with your own scheme -->
<data android:scheme="web3authrnexample" />
</intent-filter>

Also set android:exported="true" on your main activity:

AndroidManifest.xml
<activity
android:name=".MainActivity"
android:exported="true"
...>

4. iOS setup​

In your Podfile, set the minimum platform to iOS 14:

Podfile
platform :ios, '14'

Then install Pods:

cd ios && pod install

Register your redirect URL (for example, web3authrnexample://auth) in the Allowed Origins section of the dashboard. No additional Info.plist entry is required.

5. Expo setup​

Add your scheme to app.json:

app.json
{
"expo": {
"scheme": "web3authexpoexample"
}
}
note

The SDK does not work with the Expo Go app. Use a custom dev client or an EAS build. Run npx expo prebuild before building.

Configure polyfills and bundler​

Entry point​

Add import "@web3auth/react-native-sdk/setup" as the first line of your app's entry file. This single import replaces the globals.js / react-native-get-random-values pattern used in v8.

index.js
import '@web3auth/react-native-sdk/setup' // must be first
import { AppRegistry } from 'react-native'
import App from './App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App)

Metro bundler​

metro.config.js
const { getDefaultConfig } = require('@react-native/metro-config')
const { withWeb3Auth } = require('@web3auth/react-native-sdk/metro-config')

const config = getDefaultConfig(__dirname)
module.exports = withWeb3Auth(config)

Babel config​

babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['@babel/plugin-transform-export-namespace-from'],
}

SDK configuration​

Create a dedicated web3authConfig.ts file. This is the only file you need to edit to change SDK settings, chains, or optional features.

web3authConfig.ts
import {
CHAIN_NAMESPACES,
WEB3AUTH_NETWORK,
type Web3AuthContextConfig,
} from '@web3auth/react-native-sdk'

const web3AuthConfig: Web3AuthContextConfig = {
web3AuthOptions: {
clientId: 'YOUR_CLIENT_ID', // from developer.metamask.io
redirectUrl: 'web3authrnexample://auth',
network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
chains: [
{
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: '0xaa36a7',
rpcTarget: 'https://rpc.ankr.com/eth_sepolia',
displayName: 'Ethereum Sepolia Testnet',
blockExplorerUrl: 'https://sepolia.etherscan.io',
ticker: 'ETH',
tickerName: 'Ethereum',
},
],
defaultChainId: '0xaa36a7',
},
}

export default web3AuthConfig

Set up Web3AuthProvider​

Web3AuthProvider is the React context provider that initialises the SDK and makes all hooks available to the component tree.

import * as WebBrowser from '@toruslabs/react-native-web-browser'
import EncryptedStorage from 'react-native-encrypted-storage'
import { Web3AuthProvider } from '@web3auth/react-native-sdk'
import web3AuthConfig from './web3authConfig'

export default function App() {
return (
<Web3AuthProvider webBrowser={WebBrowser} storage={EncryptedStorage} config={web3AuthConfig}>
<Screen />
</Web3AuthProvider>
)
}

Props​

PropTypeRequiredDescription
webBrowserIWebBrowserYesIn-app browser implementation. Use @toruslabs/react-native-web-browser for bare React Native and expo-web-browser for Expo.
storageIStorageYesPersistent key-value storage for session data. Use react-native-encrypted-storage for bare React Native and expo-secure-store for Expo.
configWeb3AuthContextConfigYesSDK configuration object containing web3AuthOptions. Typically imported from a dedicated web3authConfig.ts file.
key?stringNoReact reconciler key. Change this value to force the provider to remount with a new configuration (for example, when toggling account abstraction on or off).
childrenReact.ReactNodeYesChild components that consume the Web3Auth hooks.

Sign users in​

Call connectTo from the useWeb3AuthConnect hook. The SDK opens the authentication provider in an in-app browser and returns control to your app after the redirect.

import { AUTH_CONNECTION, useWeb3AuthConnect } from '@web3auth/react-native-sdk'

function LoginView() {
const { connectTo, loading } = useWeb3AuthConnect()

return (
<View>
<Button
title={loading ? 'Signing in…' : 'Sign in with Google'}
disabled={loading}
onPress={() => connectTo({ authConnection: AUTH_CONNECTION.GOOGLE })}
/>
<Button
title="Sign in with Email"
onPress={() =>
connectTo({
authConnection: AUTH_CONNECTION.EMAIL_PASSWORDLESS,
extraLoginOptions: { login_hint: 'user@example.com' },
})
}
/>
</View>
)
}

See the hooks reference and the login usage page for the full connectTo parameter reference.

Use the provider for EVM calls​

After the user connects, use useWeb3Auth().provider with ethers or viem. No additional provider setup is needed.

import { useWeb3Auth } from '@web3auth/react-native-sdk'
import { ethers } from 'ethers'

function HomeView() {
const { provider } = useWeb3Auth()

const getAddress = async () => {
const ep = new ethers.BrowserProvider(provider!)
const signer = await ep.getSigner()
return await signer.getAddress()
}

const signMessage = async (message: string) => {
const ep = new ethers.BrowserProvider(provider!)
const signer = await ep.getSigner()
return await signer.signMessage(message)
}
}

Use the signer for Solana​

import { useWeb3Auth } from '@web3auth/react-native-sdk'
import type { TransactionSigner } from '@solana/signers'
import { Connection, PublicKey } from '@solana/web3.js'

function SolanaView() {
const { web3Auth } = useWeb3Auth()
const signer = web3Auth?.signer as TransactionSigner | null

const getAddress = () => String(signer?.address)

const getBalance = async () => {
const connection = new Connection('https://api.testnet.solana.com', 'confirmed')
return connection.getBalance(new PublicKey(getAddress()))
}
}

Advanced configuration​

Hooks reference​

See the hooks reference for full documentation on all available hooks: useWeb3Auth, useWeb3AuthConnect, useWeb3AuthDisconnect, useWeb3AuthUser, useWalletUI, useSignatureRequest, useIdentityToken, useEnableMFA, useManageMFA.

Troubleshooting​

If you run into Metro bundler errors, see the Metro polyfill troubleshooting guide.