# useOAuth & usePasskey

While the `DidConnect` component and `useConnect` hook provide a comprehensive, pre-built UI for all authentication methods, you may need to build a custom authentication flow. The `useOAuth` and `usePasskey` hooks offer direct access to the underlying logic for social logins (OAuth) and passwordless authentication (Passkey).

These hooks are powerful tools for creating bespoke user experiences. They depend on their respective context providers, `OAuthProvider` and `PasskeyProvider`, which are typically included within the main `SessionProvider`. For more information on session management, see the [SessionProvider documentation](./core-components-session-provider.md).

## useOAuth

The `useOAuth` hook provides functions and state for handling third-party social login flows.

### Import

```javascript icon=logos:javascript
import { useOAuth } from '@arcblock/did-connect-react/lib/OAuth';
```

### Return Value

The hook returns an object containing the following properties and methods:

<x-field-group>
  <x-field data-name="loginOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>Initiates a login flow with a specified OAuth provider. It opens a popup for user authorization and returns a promise that resolves with the login result.</x-field-desc>
  </x-field>
  <x-field data-name="bindOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>Binds a new OAuth account to the currently logged-in user's session.</x-field-desc>
  </x-field>
  <x-field data-name="unbindOAuth" data-type="function" data-required="true">
    <x-field-desc markdown>Unbinds an OAuth account from the current user's session.</x-field-desc>
  </x-field>
  <x-field data-name="getOAuthConfigList" data-type="function" data-required="true">
    <x-field-desc markdown>Fetches the list of enabled and configured OAuth providers from the blocklet settings. Returns a promise that resolves to an array of provider configuration objects.</x-field-desc>
  </x-field>
  <x-field data-name="switchOAuthPassport" data-type="function" data-required="true">
    <x-field-desc markdown>Initiates a flow to switch between different connected accounts (passports) of the same identity.</x-field-desc>
  </x-field>
  <x-field data-name="bindAuthLoading" data-type="boolean" data-required="true">
    <x-field-desc markdown>A boolean flag that is `true` while the `bindOAuth` operation is in progress.</x-field-desc>
  </x-field>
  <x-field data-name="unbindAuthLoading" data-type="boolean" data-required="true">
    <x-field-desc markdown>A boolean flag that is `true` while the `unbindOAuth` operation is in progress.</x-field-desc>
  </x-field>
  <x-field data-name="oauthState" data-type="object" data-required="true">
    <x-field-desc markdown>An object containing the real-time status of the authentication process.</x-field-desc>
    <x-field data-name="loading" data-type="boolean" data-desc="True if an OAuth operation is in progress."></x-field>
    <x-field data-name="error" data-type="string" data-desc="Contains an error message if the operation failed."></x-field>
    <x-field data-name="status" data-type="string" data-desc="The current status of the flow (e.g., 'scanned', 'succeed', 'error')."></x-field>
  </x-field>
</x-field-group>

### Usage Example

Here's an example of how to build a custom social login component.

```jsx CustomSocialLogin.jsx icon=logos:react
import React, { useEffect, useState } from 'react';
import { useOAuth } from '@arcblock/did-connect-react/lib/OAuth';
import { useSession } from '@arcblock/did-connect-react/lib/Session';

export default function CustomSocialLogin() {
  const { loginOAuth, getOAuthConfigList } = useOAuth();
  const { session } = useSession();
  const [providers, setProviders] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    // Fetch the list of available OAuth providers when the component mounts
    getOAuthConfigList().then(setProviders).catch(console.error);
  }, [getOAuthConfigList]);

  const handleLogin = async (provider) => {
    setLoading(true);
    setError('');
    try {
      const result = await loginOAuth({ provider: provider.provider });
      // After successful login, the session will be updated automatically by the SessionProvider.
      console.log('Login successful:', result);
      // You might want to refresh the session or redirect the user here.
    } catch (err) {
      setError(err.message);
      console.error('Login failed:', err);
    } finally {
      setLoading(false);
    }
  };

  if (session.user) {
    return <div>You are already logged in as {session.user.name}.</div>;
  }

  if (providers.length === 0) {
    return <div>No social login methods configured.</div>;
  }

  return (
    <div>
      <h3>Login with Social Media</h3>
      {providers.map((p) => (
        <button key={p.provider} onClick={() => handleLogin(p)} disabled={loading}>
          {loading ? 'Logging in...' : `Login with ${p.provider}`}
        </button>
      ))}
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

## usePasskey

The `usePasskey` hook provides functions and state for handling passwordless authentication using WebAuthn (Passkeys).

### Import

```javascript icon=logos:javascript
import { usePasskey } from '@arcblock/did-connect-react/lib/Passkey';
```

### Return Value

The hook returns an object containing the following properties and methods:

<x-field-group>
  <x-field data-name="loginPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>Initiates a login flow using an existing Passkey. It triggers the browser's native WebAuthn authentication prompt.</x-field-desc>
  </x-field>
  <x-field data-name="connectPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>Initiates a flow to create and bind a new Passkey to the current user's session.</x-field-desc>
  </x-field>
  <x-field data-name="disconnectPasskey" data-type="function" data-required="true">
    <x-field-desc markdown>Unbinds a Passkey from the current user's session after successful verification.</x-field-desc>
  </x-field>
  <x-field data-name="switchPassport" data-type="function" data-required="true">
    <x-field-desc markdown>Initiates a flow to switch between different connected accounts (passports).</x-field-desc>
  </x-field>
  <x-field data-name="connecting" data-type="boolean" data-required="true">
    <x-field-desc markdown>A boolean flag that is `true` while the `connectPasskey` operation is in progress.</x-field-desc>
  </x-field>
  <x-field data-name="disconnecting" data-type="boolean" data-required="true">
    <x-field-desc markdown>A boolean flag that is `true` while the `disconnectPasskey` operation is in progress.</x-field-desc>
  </x-field>
  <x-field data-name="passkeyState" data-type="object" data-required="true">
    <x-field-desc markdown>An object containing the real-time status of the Passkey operation.</x-field-desc>
    <x-field data-name="loading" data-type="boolean" data-desc="True if a Passkey operation is in progress."></x-field>
    <x-field data-name="creating" data-type="boolean" data-desc="True during the Passkey creation phase."></x-field>
    <x-field data-name="verifying" data-type="boolean" data-desc="True during the Passkey verification phase."></x-field>
    <x-field data-name="error" data-type="string" data-desc="Contains an error message if the operation failed."></x-field>
    <x-field data-name="status" data-type="string" data-desc="The current status of the flow (e.g., 'scanned', 'succeed', 'error')."></x-field>
  </x-field>
</x-field-group>

### Usage Example

Here's an example of how to create a "Login with Passkey" button.

```jsx PasskeyLoginButton.jsx icon=logos:react
import React, { useState } from 'react';
import { usePasskey } from '@arcblock/did-connect-react/lib/Passkey';

export default function PasskeyLoginButton() {
  const { loginPasskey, passkeyState } = usePasskey();
  const [error, setError] = useState('');

  const handleLogin = async () => {
    setError('');
    try {
      const result = await loginPasskey();
      console.log('Passkey login successful:', result);
      // The session will be updated automatically by the SessionProvider.
    } catch (err) {
      setError(err.message);
      console.error('Passkey login failed:', err);
    }
  };

  return (
    <div>
      <button onClick={handleLogin} disabled={passkeyState.loading}>
        {passkeyState.loading ? 'Verifying...' : 'Login with Passkey'}
      </button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

These hooks provide the flexibility to integrate DID Connect's powerful authentication features into any part of your application with a completely custom UI. To learn about programmatically controlling the pre-built `DidConnect` modal, proceed to the [useConnect hook documentation](./hooks-use-connect.md).