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.
This is a paid feature and the minimum pricing plan 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 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)
- Auth0 (SDK-native)
- Custom Google Client ID
Sign the user in with Firebase first, for example with
@react-native-firebase/auth, then pass the Firebase ID token
to connectTo as idToken. The SDK doesn't open a browser for this flow.
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} />
}
For Auth0, the SDK opens Auth0's login page natively, you no longer need react-native-auth0:
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',
},
})
}
/>
)
}
To use your own Google Client ID instead of Web3Auth's default, create a Google connection on the dashboard:
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
authConnectiontoAUTH_CONNECTION.CUSTOMandauthConnectionIdto the dashboard connection that verifies your JWT issuer. - In SDK v10.0.0, the SDK reads the user identifier from the token's
user_idclaim. Firebase ID tokens includeuser_id. Tokens from other issuers must include auser_idclaim that matches the identifier field configured for the connection. extraLoginOptionsdoesn't apply to this flow.- These sessions don't have an Embedded Wallets access token, so
useWeb3Auth().isAuthorizedisfalseanduseAccessTokenreturnsnull. - If the user already enabled MFA for this connection,
connectTofails. Use the browser-based flow (withoutidToken) 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:
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
- Interface
- AUTH_CONNECTION values
| 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. |
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. |
appState? | No | Custom state string returned in userInfo.appState after sign-in. |
dappUrl? | No | Custom redirect URL for the manage MFA flow. |
// 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
}
Import AUTH_CONNECTION from @web3auth/react-native-sdk.
| Constant | Sign-in method |
|---|---|
AUTH_CONNECTION.GOOGLE | |
AUTH_CONNECTION.FACEBOOK | |
AUTH_CONNECTION.APPLE | Sign in with Apple |
AUTH_CONNECTION.DISCORD | Discord |
AUTH_CONNECTION.TWITTER | X (Twitter) |
AUTH_CONNECTION.GITHUB | GitHub |
AUTH_CONNECTION.REDDIT | |
AUTH_CONNECTION.TWITCH | Twitch |
AUTH_CONNECTION.LINE | LINE |
AUTH_CONNECTION.KAKAO | Kakao |
AUTH_CONNECTION.LINKEDIN | |
AUTH_CONNECTION.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. |