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'
}
import { useUser } from '@dynamic-labs-sdk/react-hooks';
function LastLoginIndicator() {
const user = useUser();
if (!user) return null;
const lastCredential = user.verifiedCredentials.find(
(vc) => vc.id === user.lastVerifiedCredentialId
);
if (!lastCredential) return <p>No verified credentials</p>;
return <p>Last login: {lastCredential.format}</p>;
}
The format field on each verified credential identifies the authentication method:
| Format | Description |
|---|
blockchain | Signed in by signing a message with a wallet |
email | Email OTP / magic link |
oauth | Social provider (Google, Apple, Discord, …) |
passkey | WebAuthn / passkey |
phoneNumber | SMS OTP |
totp | TOTP authenticator (typically MFA) |
externalUser | Sign-in via external JWT |
Wallet credentials
For format === 'blockchain', walletProvider describes the wallet kind:
walletProvider | Description |
|---|
browserExtension | Extension wallet (MetaMask, Phantom, etc.) |
embeddedWallet | Dynamic embedded MPC wallet |
walletConnect | WalletConnect session |
qrCode | QR-code-paired wallet |
deepLink | Mobile deep-link wallet |
custodialService | Custodial service |
smartContractWallet | Smart 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>
);
}