> For the complete documentation index, see [llms.txt](/llms.txt).

# Embedded Wallets SDK for React Native

## Overview[​](#overview "Direct link to 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](/embedded-wallets/migration-guides/react-native/). 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[​](#requirements "Direct link to 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[​](#prerequisites "Direct link to Prerequisites")

Set up your project on the [Embedded Wallets dashboard](https://developer.metamask.io/):

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](/embedded-wallets/dashboard/) for more detail.

## Installation[​](#installation "Direct link to Installation")

### 1. Install the SDK[​](#1-install-the-sdk "Direct link to 1. Install the SDK")

- npm
- Yarn
- pnpm
- Bun

```
npm install @web3auth/react-native-sdk

```

```
yarn add @web3auth/react-native-sdk

```

```
pnpm add @web3auth/react-native-sdk

```

```
bun add @web3auth/react-native-sdk

```

### 2. Install helper modules[​](#2-install-helper-modules "Direct link to 2. Install helper modules")

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

- Bare React Native
- Expo

- npm
- Yarn
- pnpm
- Bun

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

```

```
yarn add @toruslabs/react-native-web-browser react-native-encrypted-storage
yarn add --dev @babel/plugin-transform-export-namespace-from

```

```
pnpm add @toruslabs/react-native-web-browser react-native-encrypted-storage
pnpm add --save-dev @babel/plugin-transform-export-namespace-from

```

```
bun add @toruslabs/react-native-web-browser react-native-encrypted-storage
bun add --dev @babel/plugin-transform-export-namespace-from

```

- npm
- Yarn
- pnpm
- Bun

```
npm install expo-web-browser expo-secure-store
npm install --save-dev @babel/plugin-transform-export-namespace-from

```

```
yarn add expo-web-browser expo-secure-store
yarn add --dev @babel/plugin-transform-export-namespace-from

```

```
pnpm add expo-web-browser expo-secure-store
pnpm add --save-dev @babel/plugin-transform-export-namespace-from

```

```
bun add expo-web-browser expo-secure-store
bun add --dev @babel/plugin-transform-export-namespace-from

```

### 3. Android setup[​](#3-android-setup "Direct link to 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[​](#4-ios-setup "Direct link to 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[​](#5-expo-setup "Direct link to 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[​](#configure-polyfills-and-bundler "Direct link to Configure polyfills and bundler")

### Entry point[​](#entry-point "Direct link to 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.

- Bare React Native
- Expo

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)

```

Create `index.ts` and change `"main"` to `"index.ts"` in `package.json`:

index.ts

```
import '@web3auth/react-native-sdk/setup' // must be first
import { registerRootComponent } from 'expo'
import App from './App'
registerRootComponent(App)

```

### Metro bundler[​](#metro-bundler "Direct link to Metro bundler")

- Bare React Native
- Expo

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)

```

metro.config.js

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

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

```

### Babel config[​](#babel-config "Direct link to Babel config")

- Bare React Native
- Expo

babel.config.js

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

```

babel.config.js

```
module.exports = function (api) {
  api.cache(true)
  return {
    presets: ['babel-preset-expo'],
    plugins: ['@babel/plugin-transform-export-namespace-from'],
  }
}

```

## SDK configuration[​](#sdk-configuration "Direct link to 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.

- Basic (EVM)
- Solana
- With Account Abstraction

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

```

web3authConfig.ts

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

const web3AuthConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_CLIENT_ID',
    redirectUrl: 'web3authrnexample://auth',
    network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    chains: [
      {
        chainNamespace: CHAIN_NAMESPACES.SOLANA,
        chainId: '0x2', // Solana Testnet
        rpcTarget: 'https://api.testnet.solana.com',
        displayName: 'Solana Testnet',
        blockExplorerUrl: 'https://explorer.solana.com',
        ticker: 'SOL',
        tickerName: 'Solana',
      },
    ],
    defaultChainId: '0x2',
  },
}

export default web3AuthConfig

```

web3authConfig.ts

```
import {
  CHAIN_NAMESPACES,
  WEB3AUTH_NETWORK,
  type AccountAbstractionConfig,
  type Web3AuthContextConfig,
} from '@web3auth/react-native-sdk'

const aaConfig: AccountAbstractionConfig = {
  smartAccountType: 'safe',
}

const web3AuthConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_CLIENT_ID',
    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',
    accountAbstractionConfig: aaConfig,
  },
}

export default web3AuthConfig

```

## Set up `Web3AuthProvider`[​](#set-up-web3authprovider "Direct link to set-up-web3authprovider")

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

- Bare React Native
- Expo

```
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>
  )
}

```

```
import * as WebBrowser from 'expo-web-browser'
import * as SecureStore from 'expo-secure-store'
import { Web3AuthProvider } from '@web3auth/react-native-sdk'
import web3AuthConfig from './web3authConfig'

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

```

### Props[​](#props "Direct link to Props")

| Prop       | Type                  | Required | Description                                                                                                                                                   |
| ---------- | --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webBrowser | IWebBrowser           | Yes      | In-app browser implementation. Use @toruslabs/react-native-web-browser for bare React Native and expo-web-browser for Expo.                                   |
| storage    | IStorage              | Yes      | Persistent key-value storage for session data. Use react-native-encrypted-storage for bare React Native and expo-secure-store for Expo.                       |
| config     | Web3AuthContextConfig | Yes      | SDK configuration object containing web3AuthOptions. Typically imported from a dedicated web3authConfig.ts file.                                              |
| key?       | string                | No       | React reconciler key. Change this value to force the provider to remount with a new configuration (for example, when toggling account abstraction on or off). |
| children   | React.ReactNode       | Yes      | Child components that consume the Web3Auth hooks.                                                                                                             |

## Sign users in[​](#sign-users-in "Direct link to 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](/embedded-wallets/sdk/react-native/hooks/) and the [login usage page](/embedded-wallets/sdk/react-native/usage/login/) for the full `connectTo` parameter reference.

## Use the provider for EVM calls[​](#use-the-provider-for-evm-calls "Direct link to 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[​](#use-the-signer-for-solana "Direct link to 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[​](#advanced-configuration "Direct link to Advanced configuration")

- [Account Abstraction (smart accounts)](/embedded-wallets/sdk/react-native/advanced/smart-accounts/)
- [Custom authentication](/embedded-wallets/sdk/react-native/advanced/custom-authentication/)
- [Whitelabeling and UI customization](/embedded-wallets/sdk/react-native/advanced/whitelabel/)
- [Multi-Factor Authentication (MFA)](/embedded-wallets/sdk/react-native/advanced/mfa/)
- [Dapp share](/embedded-wallets/sdk/react-native/advanced/dapp-share/)

## Hooks reference[​](#hooks-reference "Direct link to Hooks reference")

See the [hooks reference](/embedded-wallets/sdk/react-native/hooks/) for full documentation on all available hooks: `useWeb3Auth`, `useWeb3AuthConnect`, `useWeb3AuthDisconnect`, `useWeb3AuthUser`, `useWalletUI`, `useSignatureRequest`, `useIdentityToken`, `useEnableMFA`, `useManageMFA`.

## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting")

If you run into Metro bundler errors, see the [Metro polyfill troubleshooting guide](/embedded-wallets/troubleshooting/metro-issues/).
