Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

A Dynamic user can authenticate through multiple methods — email, social, passkey, or a wallet — and may add more over time. The user object captures every authentication method as a verified credential. This guide shows how to find which method was used most recently and how to inspect each credential’s type.

Finding the most recent login

user.lastVerifiedCredentialId points to the credential the user authenticated with most recently. Look it up in user.verifiedCredentials:
import { getDefaultClient } from '@dynamic-labs-sdk/client';

const { user } = getDefaultClient();
if (!user) return;

const lastCredential = user.verifiedCredentials.find(
  (vc) => vc.id === user.lastVerifiedCredentialId
);

if (lastCredential) {
  console.log('Login format:', lastCredential.format);
  // 'blockchain' | 'email' | 'oauth' | 'passkey' | 'phoneNumber' | 'externalUser' | 'totp'
}

Credential formats

The format field on each verified credential identifies the authentication method:
FormatDescription
blockchainSigned in by signing a message with a wallet
emailEmail OTP / magic link
oauthSocial provider (Google, Apple, Discord, …)
passkeyWebAuthn / passkey
phoneNumberSMS OTP
totpTOTP authenticator (typically MFA)
externalUserSign-in via external JWT

Wallet credentials

For format === 'blockchain', walletProvider describes the wallet kind:
walletProviderDescription
browserExtensionExtension wallet (MetaMask, Phantom, etc.)
embeddedWalletDynamic embedded MPC wallet
walletConnectWalletConnect session
qrCodeQR-code-paired wallet
deepLinkMobile deep-link wallet
custodialServiceCustodial service
smartContractWalletSmart contract wallet (account abstraction)
const wallet = user.verifiedCredentials.find(
  (vc) => vc.format === 'blockchain'
);

if (wallet) {
  console.log('Address:', wallet.address);
  console.log('Chain:', wallet.chain);
  console.log('Wallet provider:', wallet.walletProvider);
}

Social credentials

For format === 'oauth', oauthProvider identifies the social network. See Social Account Linking for the full provider list and management APIs.
import { getUserSocialAccounts } from '@dynamic-labs-sdk/client';

const socials = getUserSocialAccounts();
socials.forEach((account) => {
  console.log(account.provider, account.displayName);
});
getUserSocialAccounts is a typed helper that filters verifiedCredentials to OAuth entries and exposes provider, displayName, emails, photos, and verifiedCredentialId.

Helper: a single login-method label

Map credential formats and wallet providers to a single tag your UI can branch on:
import type { JwtVerifiedCredential } from '@dynamic-labs/sdk-api-core';
import { getDefaultClient } from '@dynamic-labs-sdk/client';

type LoginMethod =
  | 'email'
  | 'phone'
  | 'social'
  | 'passkey'
  | 'browser-wallet'
  | 'embedded-wallet'
  | 'wallet-connect'
  | 'smart-wallet'
  | 'external'
  | 'unknown';

const credentialToMethod = (credential: JwtVerifiedCredential): LoginMethod => {
  switch (credential.format) {
    case 'email':       return 'email';
    case 'phoneNumber': return 'phone';
    case 'oauth':       return 'social';
    case 'passkey':     return 'passkey';
    case 'externalUser':return 'external';
    case 'blockchain':
      switch (credential.walletProvider) {
        case 'embeddedWallet':      return 'embedded-wallet';
        case 'walletConnect':       return 'wallet-connect';
        case 'smartContractWallet': return 'smart-wallet';
        case 'browserExtension':    return 'browser-wallet';
        default:                    return 'browser-wallet';
      }
    default: return 'unknown';
  }
};

export const getLastLoginMethod = (): LoginMethod => {
  const { user } = getDefaultClient();
  const credential = user?.verifiedCredentials.find(
    (vc) => vc.id === user.lastVerifiedCredentialId
  );
  return credential ? credentialToMethod(credential) : 'unknown';
};
In React, drop this in a hook subscribed to userChanged:
import { useUser } from '@dynamic-labs-sdk/react-hooks';
import { getLastLoginMethod } from './loginMethod';

function WelcomeCopy() {
  const user = useUser();
  if (!user) return null;
  const method = getLastLoginMethod();
  return <p>You signed in with {method}.</p>;
}

Iterating all credentials

To show the user their full authentication history (e.g. an account-security panel), walk the array:
import { useUser } from '@dynamic-labs-sdk/react-hooks';

function CredentialList() {
  const user = useUser();
  if (!user) return null;

  return (
    <ul>
      {user.verifiedCredentials.map((vc) => (
        <li key={vc.id}>
          <strong>{vc.format}</strong>
          {vc.publicIdentifier && ` — ${vc.publicIdentifier}`}
          {vc.format === 'blockchain' && ` (${vc.walletProvider})`}
          {vc.format === 'oauth' && ` (${vc.oauthProvider})`}
          {vc.id === user.lastVerifiedCredentialId && ' — last used'}
        </li>
      ))}
    </ul>
  );
}