> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native authentication

> Authenticate with an OIDC ID token, email OTP, or an OIDC redirect and activate a wallet.

Authentication establishes an access credential. Wallet selection then activates a wallet and completes the wallet session. Reuse the single `omsWallet` instance created in the [quickstart](/wallets/sdk/react-native/quickstart) throughout every flow.

## OIDC ID token

When your host app's provider integration returns an OIDC ID token, pass that token directly to OMS Wallet. The OMS Wallet SDK validates the token and establishes the wallet credential; it does not acquire the provider token.

```typescript theme={null}
const result = await omsWallet.wallet.signInWithOidcIdToken({
  idToken,
  issuer: 'https://accounts.google.com',
  audience: 'YOUR_WEB_CLIENT_ID',
  provider: 'google',
  providerLabel: 'Google',
})

if (result.type === 'walletSelected') {
  console.log('Active wallet:', result.walletAddress)
}
```

`idToken` above is the value returned by your app's native provider code. Configure that provider to issue the token for the same client ID passed as `audience`. The requested credential lifetime defaults to one week. Set `sessionLifetimeSeconds` to an integer from 1 through 2,592,000 seconds when you need another lifetime.

## Authenticate with email OTP

Email authentication has a request and completion step:

```typescript theme={null}
await omsWallet.wallet.startEmailAuth({
  email: 'user@example.com',
  sessionLifetimeSeconds: 604800,
})

const result = await omsWallet.wallet.completeEmailAuth({
  code: '123456',
})

if (result.type === 'walletSelected') {
  console.log('Active wallet:', result.walletAddress)
}
```

The requested session lifetime belongs on `startEmailAuth`, not `completeEmailAuth`.

## Authenticate with an OIDC redirect

Use redirect authentication when the provider integration does not supply an ID token. Fixed OMS relay configurations are available for Google and Apple:

```typescript theme={null}
import { OmsRelayOidcProviders } from '@polygonlabs/oms-wallet-react-native'

const callbackUri = 'com.example.app://auth/callback'

const started = await omsWallet.wallet.startOidcRedirectAuth({
  provider: OmsRelayOidcProviders.google,
  omsRelayReturnUri: callbackUri,
})
```

The start call also accepts `loginHint`, `sessionLifetimeSeconds`, and `walletSelection`. Leave wallet selection undefined for the automatic default.

Open `started.authorizationUrl` in the platform authentication browser, then pass its returned URL to the SDK:

```typescript theme={null}
const callback = await omsWallet.wallet.handleOidcRedirectCallback({
  callbackUrl,
})

if (
  callback.type === 'completed' &&
  callback.result.type === 'walletSelected'
) {
  console.log('Active wallet:', callback.result.walletAddress)
}
```

An unrelated URL returns `notOidcRedirectCallback`; a callback without stored pending auth returns `noPendingAuth`. Provider failures reject with `OMSWalletError` rather than returning another callback result variant.

### Open the authentication browser

Bare React Native and Expo use different browser dependencies:

<Tabs>
  <Tab title="Bare React Native">
    ```bash theme={null}
    npm install react-native-inappbrowser-reborn
    npx pod-install
    ```

    ```typescript theme={null}
    import { InAppBrowser } from 'react-native-inappbrowser-reborn'

    const browser = await InAppBrowser.openAuth(
      started.authorizationUrl,
      callbackUri
    )

    if (browser.type === 'success') {
      await omsWallet.wallet.handleOidcRedirectCallback({
        callbackUrl: browser.url,
      })
    }
    ```
  </Tab>

  <Tab title="Expo">
    ```bash theme={null}
    npx expo install expo-web-browser
    ```

    ```typescript theme={null}
    import * as WebBrowser from 'expo-web-browser'

    const browser = await WebBrowser.openAuthSessionAsync(
      started.authorizationUrl,
      callbackUri
    )

    if (browser.type === 'success') {
      await omsWallet.wallet.handleOidcRedirectCallback({
        callbackUrl: browser.url,
      })
    }
    ```

    Add `expo-web-browser` to the `plugins` array in the Expo app configuration, set the app `scheme`, and rebuild the development client after changing native configuration.
  </Tab>
</Tabs>

Configure `callbackUri` in the app's native deep-link configuration.

### Configure the app callback

For a bare Android app, add a browsable intent filter to the activity that receives the callback. Keep `launchMode="singleTask"` so an existing activity receives warm links:

```xml theme={null}
<activity
  android:name=".MainActivity"
  android:exported="true"
  android:launchMode="singleTask">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
      android:scheme="com.example.app"
      android:host="auth"
      android:pathPrefix="/callback" />
  </intent-filter>
</activity>
```

For a bare iOS app, register `com.example.app` under `CFBundleURLTypes` in `Info.plist`. Expo generates both native configurations from the `scheme` field:

```json theme={null}
{
  "expo": {
    "scheme": "com.example.app",
    "plugins": ["expo-web-browser"]
  }
}
```

### Handle links delivered outside the authentication browser

The authentication-browser result covers the normal return. If the operating system instead delivers the callback as an app link, obtain warm links from React Native's `Linking.addEventListener('url', ...)` and cold-start links from `Linking.getInitialURL()`, then pass the URL directly to `handleOidcRedirectCallback`. Route each URL once; a repeated matching callback returns `noPendingAuth` after the first attempt is consumed.

## Use a custom OIDC provider

Use `CustomOidcProviderConfig` only when your project owns the provider configuration. `providerRedirectUri` must exactly match a URI registered with the provider.

```typescript theme={null}
import type { CustomOidcProviderConfig } from '@polygonlabs/oms-wallet-react-native'

const provider: CustomOidcProviderConfig = {
  issuer: 'https://issuer.example.com',
  clientId: 'YOUR_OIDC_CLIENT_ID',
  authorizationUrl: 'https://issuer.example.com/oauth2/authorize',
  providerRedirectUri: 'com.example.app://auth/callback',
  scopes: ['openid', 'email', 'profile'],
  authMode: 'auth-code-pkce',
}

const started = await omsWallet.wallet.startOidcRedirectAuth({
  provider,
})
```

Use `authorizeParams` on the start call for per-attempt authorization parameters.

## Select a wallet manually

Request manual selection only when your app provides its own wallet picker:

```typescript theme={null}
const result = await omsWallet.wallet.completeEmailAuth({
  code: '123456',
  walletSelection: 'manual',
})

if (result.type === 'walletSelection') {
  const selection = result.pendingSelection
  const existingWallet = selection.wallets[0]
  const activeWallet = existingWallet
    ? await selection.selectWallet(existingWallet.id)
    : await selection.createAndSelectWallet('primary')

  console.log('Active wallet:', activeWallet.walletAddress)
}
```

Use the methods on `pendingSelection` to finish the same authentication attempt. The same `walletSelection` option is available for ID-token and redirect authentication.
