Skip to content
DexterDocs
Dexter Connect / Add Dexter Sign-In
Sections

Add Dexter Sign-In

Use useDexterConnection to connect a Dexter account and DexterButton to render the control. The SDK opens the passkey flow and verifies that the returned account and wallet belong together.

Install

In a React 18 or newer application:

npm install @dexterai/connect@0.29.1 @dexterai/vault@0.43.4

On third-party origins, sign-in opens Dexter's hosted authorization window.

Add the Control

This React client component stores its session in memory. Reloading clears it; connect your application's session adapter for persistence.

DexterSignIn.tsx
'use client';

import { useCallback, useState } from 'react';
import type { PasskeyLoginTokens } from '@dexterai/connect';
import {
  DexterButton,
  useDexterConnection,
  type DexterAccountSession,
} from '@dexterai/connect/react';

export function DexterSignIn() {
  const [accountSession, setAccountSession] = useState<DexterAccountSession>({
    status: 'signed_out',
  });
  const [message, setMessage] = useState('');

  const installAccountSession = useCallback((session: PasskeyLoginTokens) => {
    setAccountSession({ status: 'authenticated', accessToken: session.accessToken });
  }, []);
  const clearAccountSession = useCallback(() => {
    setAccountSession({ status: 'signed_out' });
  }, []);

  const dx = useDexterConnection({
    intent: 'identity',
    accountSession,
    installAccountSession,
    clearAccountSession,
  });
  const busy = dx.operation !== 'idle' || dx.model.stage === 'checking';
  const connected = dx.model.permissions.accountContentVisible;

  async function signIn() {
    setMessage('');
    try {
      await dx.connect();
    } catch {
      setMessage('Sign-in did not complete. Try again.');
    }
  }

  async function disconnect() {
    setMessage('');
    try {
      await dx.disconnectDexter();
    } catch {
      setMessage('Could not disconnect. Try again.');
    }
  }

  return (
    <section aria-label="Dexter account">
      {connected && <p>Connected: {dx.identity.walletLabel ?? dx.identity.userHandle}</p>}
      <DexterButton
        loading={busy}
        loadingLabel="Connecting"
        onClick={() => { void (connected ? disconnect() : signIn()); }}
      >
        {connected ? 'Disconnect Dexter' : 'Sign in with Dexter'}
      </DexterButton>
      {message && <p role="alert">{message}</p>}
    </section>
  );
}

Render <DexterSignIn /> in your page. The SDK supplies the button mark, interaction states, and styles.

Connect Your Session Store

Replace the two callbacks with your app's authentication adapter:

  • installAccountSession(session) installs the returned session and updates accountSession with that same access token. Reject if installation fails.
  • Clear the host session inside clearAccountSession() and update the state to signed_out.
  • While restoring a stored session, pass { status: 'loading' }. Update it after restoration completes.

Keep tokens and wallet identity proofs out of logs and page markup. Gate account content on model.permissions.accountContentVisible; the SDK keeps it unavailable while verification runs or identities conflict. Your backend must also authenticate and authorize its own requests.

Check the Integration

Click the control, complete the Dexter passkey prompt, and return to the app. The connected identity should appear after verification. Cancel a prompt and confirm that no connected state appears. Disconnect and confirm that account content disappears.

See Connect Reference for result fields, wallet creation, connection states, and styling.

Last Updated:

On this page