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 single Migrate to v9 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 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!)
return (await ep.getSigner()).getAddress()
}

const signMessage = async (message: string) => {
const ep = new ethers.BrowserProvider(provider!)
return (await ep.getSigner()).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.