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

# Custom authentication in React Native SDK

Custom authentication lets you integrate your own identity provider, Google with your own Client ID, Firebase, Auth0, AWS Cognito, or any custom JWT issuer, so that the resulting wallet is tied to your user identity rather than to Web3Auth's default verifiers.

note

This is a paid feature and the minimum [pricing plan](https://web3auth.io/pricing.html) to use this SDK in a production environment is the **Growth Plan**. You can use this feature in Web3Auth Sapphire Devnet network for free.

## Prerequisites

Create a **Connection** in the [Authentication tab](https://developer.metamask.io) of your project on the Embedded Wallets dashboard. The dashboard will give you an **Auth Connection ID** which you pass to `connectTo` at sign-in time.

You don't need to change `web3AuthOptions` for custom authentication. Pass the connection ID to `connectTo` at sign-in time.

## Single connection

Use `AUTH_CONNECTION.CUSTOM` with `authConnectionId` to target a specific connection registered on the dashboard.

**Firebase (JWT)**

Sign the user in with Firebase first, for example with [@react-native-firebase/auth](https://rnfirebase.io/auth/usage), then pass the Firebase ID token to `connectTo` as `idToken`. The SDK doesn't open a browser for this flow.

```tsx
import auth from '@react-native-firebase/auth'
import { AUTH_CONNECTION, useWeb3AuthConnect } from '@web3auth/react-native-sdk'
import { Button } from 'react-native'

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

  const login = async () => {
    // Sign in with any Firebase method, then read the ID token
    const { user } = await auth().signInAnonymously()
    const idToken = await user.getIdToken(true)

    await connectTo({
      authConnection: AUTH_CONNECTION.CUSTOM,
      authConnectionId: 'w3a-firebase-demo', // Dashboard Connection ID
      idToken,
    })
  }

  return <Button title="Sign in with Firebase" disabled={loading} onPress={login} />
}

```

**Auth0 (SDK-native)**

For Auth0, the SDK opens Auth0's login page natively, you no longer need `react-native-auth0`:

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

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

  return (
    <Button
      title="Sign in with Auth0"
      disabled={loading}
      onPress={() =>
        connectTo({
          authConnection: AUTH_CONNECTION.CUSTOM,
          authConnectionId: 'w3a-auth0-demo', // Dashboard Connection ID
          extraLoginOptions: {
            domain: 'https://web3auth.au.auth0.com', // Your Auth0 domain
            verifierIdField: 'sub',
          },
        })
      }
    />
  )
}

```

**Custom Google Client ID**

To use your own Google Client ID instead of Web3Auth's default, create a Google connection on the dashboard:

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

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

  return (
    <Button
      title="Sign in with Google"
      disabled={loading}
      onPress={() =>
        connectTo({
          authConnection: AUTH_CONNECTION.GOOGLE,
          authConnectionId: 'my-google-connection', // Your dashboard Connection ID
        })
      }
    />
  )
}

```

## Bring your own JWT (`idToken`)

When you pass `idToken` to `connectTo`, the SDK verifies the token with the Embedded Wallets network and derives the wallet directly, without an in-app browser. Keep the following in mind:

- Set `authConnection` to `AUTH_CONNECTION.CUSTOM` and `authConnectionId` to the dashboard connection that verifies your JWT issuer.
- In SDK v10.0.0, the SDK reads the user identifier from the token's `user_id` claim. Firebase ID tokens include `user_id`. Tokens from other issuers must include a `user_id` claim that matches the identifier field configured for the connection.
- `extraLoginOptions` doesn't apply to this flow.
- These sessions don't have an Embedded Wallets access token, so `useWeb3Auth().isAuthorized` is `false` and [useAccessToken](/embedded-wallets/sdk/react-native/hooks/useAccessToken/) returns `null`.
- If the user already enabled MFA for this connection, `connectTo` fails. Use the browser-based flow (without `idToken`) for users with MFA.

## Grouped connections (aggregate verifiers)

Grouped connections allow users to sign in through different providers and always receive the same wallet address, as long as the underlying email or user identifier matches. This is useful for "Sign in with Google" and "Sign in with email" mapping to the same wallet.

Configure a **Grouped Connection** on the dashboard, then pass the group ID as `groupedAuthConnectionId` alongside each individual connection's `authConnectionId`:

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

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

  const loginWithGoogle = () =>
    connectTo({
      authConnection: AUTH_CONNECTION.GOOGLE,
      authConnectionId: 'w3a-google', // individual connection
      groupedAuthConnectionId: 'aggregate-sapphire', // grouped connection
    })

  const loginWithEmail = () =>
    connectTo({
      authConnection: AUTH_CONNECTION.CUSTOM,
      authConnectionId: 'w3a-a0-email-passwordless',
      groupedAuthConnectionId: 'aggregate-sapphire', // same group, same wallet
    })

  return (
    <View>
      <Button title="Sign in with Google" disabled={loading} onPress={loginWithGoogle} />
      <Button title="Sign in with Email" disabled={loading} onPress={loginWithEmail} />
    </View>
  )
}

```

Both buttons produce the same wallet address for users whose email matches across providers.

## `connectTo` parameter reference

**Parameters**

| Parameter                  | Required | Description                                                                                                                                                                                                                                                                          |
| -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `authConnection`           | Yes      | Authentication method. Pass an `AUTH_CONNECTION.*` constant.                                                                                                                                                                                                                         |
| `authConnectionId?`        | No       | Connection ID from the dashboard. Required for `AUTH_CONNECTION.CUSTOM` and for grouped connections. Also use it to target a specific connection when you have several of the same type.                                                                                             |
| `groupedAuthConnectionId?` | No       | Grouped connection ID from the dashboard. Connections in the same group produce the same wallet for the same user.                                                                                                                                                                   |
| `idToken?`                 | No       | JWT from your own auth provider. When set, the SDK skips the in-app browser and derives the wallet from the token directly. Requires `authConnectionId`. See [Custom authentication](/embedded-wallets/sdk/react-native/advanced/custom-authentication/#bring-your-own-jwt-idtoken). |
| `extraLoginOptions?`       | No       | Extra OAuth parameters for browser-based sign-in, for example `login_hint` (email or phone number for passwordless), `domain` (Auth0 domain), and `verifierIdField` (JWT claim used as the user ID).                                                                                 |
| `mfaLevel?`                | No       | When to show the MFA setup screen: `'optional'`, `'mandatory'`, or `'none'` (`MFA_LEVELS.OPTIONAL`, `MFA_LEVELS.MANDATORY`, `MFA_LEVELS.NONE`).                                                                                                                                      |
| `curve?`                   | No       | Key curve: `SUPPORTED_KEY_CURVES.SECP256K1` or `SUPPORTED_KEY_CURVES.ED25519`.                                                                                                                                                                                                       |
| `dappShare?`               | No       | Dapp share for MFA-enabled custom connections. The SDK stores and reuses the dapp share automatically; see [Dapp share](/embedded-wallets/sdk/react-native/advanced/dapp-share/).                                                                                                    |
| `appState?`                | No       | Custom state string returned in `userInfo.appState` after sign-in.                                                                                                                                                                                                                   |
| `dappUrl?`                 | No       | Custom redirect URL for the manage MFA flow.                                                                                                                                                                                                                                         |

**Interface**

```typescript
// SdkLoginParams = LoginParams from @web3auth/auth (without getWalletKey) & { idToken?: string }
type SdkLoginParams = {
  authConnection: AUTH_CONNECTION_TYPE | CUSTOM_AUTH_CONNECTION_TYPE
  authConnectionId?: string
  groupedAuthConnectionId?: string
  idToken?: string
  extraLoginOptions?: ExtraLoginOptions
  mfaLevel?: MfaLevelType
  curve?: SUPPORTED_KEY_CURVES_TYPE
  dappShare?: string
  appState?: string
  dappUrl?: string
  recordId?: string
  loginSource?: string
}

```

**AUTH_CONNECTION values**

Import `AUTH_CONNECTION` from `@web3auth/react-native-sdk`.

| Constant                             | Sign-in method                                      |
| ------------------------------------ | --------------------------------------------------- |
| `AUTH_CONNECTION.GOOGLE`             | Google                                              |
| `AUTH_CONNECTION.FACEBOOK`           | Facebook                                            |
| `AUTH_CONNECTION.APPLE`              | Sign in with Apple                                  |
| `AUTH_CONNECTION.DISCORD`            | Discord                                             |
| `AUTH_CONNECTION.TWITTER`            | X (Twitter)                                         |
| `AUTH_CONNECTION.GITHUB`             | GitHub                                              |
| `AUTH_CONNECTION.REDDIT`             | Reddit                                              |
| `AUTH_CONNECTION.TWITCH`             | Twitch                                              |
| `AUTH_CONNECTION.LINE`               | LINE                                                |
| `AUTH_CONNECTION.KAKAO`              | Kakao                                               |
| `AUTH_CONNECTION.LINKEDIN`           | LinkedIn                                            |
| `AUTH_CONNECTION.WECHAT`             | WeChat                                              |
| `AUTH_CONNECTION.TELEGRAM`           | Telegram                                            |
| `AUTH_CONNECTION.FARCASTER`          | Farcaster                                           |
| `AUTH_CONNECTION.EMAIL_PASSWORDLESS` | One-time code sent to an email address              |
| `AUTH_CONNECTION.SMS_PASSWORDLESS`   | One-time code sent to a phone number                |
| `AUTH_CONNECTION.PASSKEYS`           | Passkey                                             |
| `AUTH_CONNECTION.AUTHENTICATOR`      | Authenticator app                                   |
| `AUTH_CONNECTION.CUSTOM`             | Custom connection (Auth0, Firebase, any JWT issuer) |

## `extraLoginOptions` field reference

| Field                        | Type      | Description                                                                                                                   |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `domain?`                    | `string`  | Your identity provider domain (for example, `https://example.auth0.com`).                                                     |
| `login_hint?`                | `string`  | Pre-filled email address for email passwordless flows.                                                                        |
| `verifierIdField?`           | `string`  | The JWT claim to use as the user identifier (typically `sub` or `email`). Must match the setting in the dashboard connection. |
| `isVerifierIdCaseSensitive?` | `boolean` | Whether the verifier ID field comparison is case-sensitive. Default is `true`.                                                |
| `client_id?`                 | `string`  | Client ID of the OAuth application (if different from `clientId` in `web3AuthOptions`).                                       |
| `leeway?`                    | `string`  | Clock skew tolerance in seconds for JWT expiry checks. Maximum `120`.                                                         |
| `scope?`                     | `string`  | Space-separated list of OAuth scopes to request.                                                                              |
| `id_token_hint?`             | `string`  | A previously issued ID token to pass as a hint.                                                                               |
| `redirect_uri?`              | `string`  | Override the redirect URI for the OAuth flow.                                                                                 |
