Skip to content
DexterDocs
Dexter Connect / Connect With Dexter
Sections

Connect With Dexter

Let someone use their Dexter Wallet from your app. Connect opens the passkey flow and returns the wallet with its matching account session. Your app can show the connected wallet and request owner-approved operations through the Vault SDK.

For account access alone, start with Sign In With Dexter. The Connect overview explains the integration choices.

Install

Use a React 18 or newer application served over HTTPS. The owner needs a Dexter Wallet.

npm install @dexterai/connect@0.29.1 @dexterai/vault@0.43.4 @solana/web3.js@1

Connect the Owner

This client component displays the wallet's receive address after connection. Its session stays in memory for the example; use your app's session adapter to preserve sign-in across reloads.

ConnectWallet.tsx
'use client';

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

export function ConnectWallet() {
  const [session, setSession] = useState<DexterAccountSession>({
    status: 'signed_out',
  });
  const [vault, setVault] = useState<ConnectVault | null>(null);
  const [error, setError] = useState('');
  const installAccountSession = useCallback((next: PasskeyLoginTokens) => {
    setSession({ status: 'authenticated', accessToken: next.accessToken });
  }, []);
  const clearAccountSession = useCallback(() => {
    setSession({ status: 'signed_out' });
  }, []);
  const dx = useDexterConnection({
    intent: 'wallet',
    accountSession: session,
    installAccountSession,
    clearAccountSession,
  });
  const busy = dx.operation !== 'idle' || dx.model.stage === 'checking';
  const connected = dx.model.permissions.ownerWalletUseEnabled
    && vault?.userHandle === dx.activeWallet?.userHandle
    && vault !== null;

  async function connect(switchWallet = false) {
    setError('');
    setVault(null);
    try {
      const result = switchWallet
        ? await dx.useAnotherDexterWallet()
        : await dx.connect();
      setVault(result.vault);
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : 'Connection failed.');
    }
  }

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

  return (
    <section aria-label="Dexter Wallet connection">
      {connected ? (
        <>
          <p>{vault.walletLabel ?? 'Dexter Wallet'} is connected.</p>
          {vault.receiveAddress && <p>Receive address: {vault.receiveAddress}</p>}
          <button type="button" disabled={busy} onClick={() => void connect(true)}>
            Use another Dexter Wallet
          </button>
          <button type="button" disabled={busy} onClick={() => void disconnect()}>
            Disconnect Dexter
          </button>
        </>
      ) : (
        <DexterButton loading={busy} onClick={() => void connect()}>
          Connect Dexter
        </DexterButton>
      )}
      {error && <p role="alert">{error}</p>}
    </section>
  );
}

Render <ConnectWallet /> in your page. Choose Connect Dexter, complete the passkey prompt, and return to the app. The connected wallet appears after verification. Cancelling leaves the connection closed. Use another Dexter Wallet starts a fresh ceremony; Disconnect Dexter clears this connection while keeping the device passkey available for later use.

Obtain the Owner Signer

Pass the vault returned by dx.connect() to createPasskeySigner when preparing a Vault operation:

owner-signer.ts
import { createPasskeySigner, type ConnectVault } from '@dexterai/connect';

export function ownerSigner(vault: ConnectVault) {
  return createPasskeySigner(vault);
}

Creating the signer prepares the integration. A call to its signOperation method opens the owner approval for the specific Vault message. Use the Vault SDK's message and instruction builders to construct that operation and submit its transaction.

The activeWallet hook field supplies display metadata. Use the full connection result for the signer. For a browser wallet exposing signTransaction, follow the separate browser payment guide.

Check Your Connection

Connect, switch to another wallet, and disconnect. The displayed address and enabled wallet actions should follow the active identity. While the SDK reports checking, keep those actions disabled. Gate private account data separately with accountContentVisible; the API reference describes the permission fields.

Last Updated:

On this page