- React
- React Native
- Flutter
- Android
- Swift
- Unity
To get the current user, inspect the
If a user has not linked an account of a given type, the corresponding field on the Below is an example of how you might use the Refreshing the
In order to update a
user object returned by the usePrivy hook:Report incorrect code
Copy
Ask AI
const { user } = usePrivy();
Unauthenticated users
For unauthenticated users, theuser object will be null.Authenticated users
For authenticated users, you can use the following fields:Hide User
Hide User
The Privy-issued DID for the user. If you need to store additional information about a user, you
can use this DID to reference them.
The datetime of when the user was created, in ISO 8601 format.
The list of accounts associated with this user. Each account contains additional metadata that may
be helpful for advanced use cases.
Show Properties
Show Properties
Show Wallet
Show Wallet
Denotes that this is a wallet account
The wallet ID of the wallet. Null if the wallet is not delegated. Only applies to embedded
wallets (walletClientType === ‘privy’)
The wallet address
Chain type of the wallet address
The wallet client used for this wallet during the most recent verification. If the value is
‘privy’, then this is a privy embedded wallet
The connector type used for this wallet during the most recent verification
If this is a ‘privy’ embedded wallet, stores the recovery method
Whether the wallet is imported. Only applies to embedded wallets (walletClientType === ‘privy’)
Whether the wallet is delegated. Only applies to embedded wallets (walletClientType === ‘privy’)
HD index for the wallet. Only applies to embedded wallets (walletClientType === ‘privy’)
Show SmartWallet
Show SmartWallet
Show Email
Show Email
Show Phone
Show Phone
Show Google
Show Google
Show Twitter
Show Twitter
Denotes that this is a Twitter account
The ‘sub’ claim from the Twitter-issued JWT for this account
The username associated with the Twitter account
The name associated with the Twitter account
The profile picture URL associated with the Twitter account
Show Discord
Show Discord
Show Github
Show Github
Denotes that this is a Github account
The ‘sub’ claim from the Github-issued JWT for this account
The username associated with the Github account
The name associated with the Github account
The email associated with the Github account
Show Spotify
Show Spotify
Show Instagram
Show Instagram
Show Tiktok
Show Tiktok
Show Line
Show Line
Denotes that this is a Line account
The ‘sub’ claim from the Line-issued JWT for this account
The name associated with the Line account
The email associated with the Line account
The profile image URL associated with the Line account
Show LinkedIn
Show LinkedIn
Denotes that this is a LinkedIn account
The ‘sub’ claim from the LinkedIn-issued JWT for this account
The name associated with the LinkedIn account
The email associated with the LinkedIn account
The vanityName/profile URL associated with the LinkedIn account
Show Apple
Show Apple
Show CustomJwt
Show CustomJwt
Show Farcaster
Show Farcaster
Denotes that this is a Farcaster account
The Farcaster on-chain FID
The Farcaster ethereum address that owns the FID
The Farcaster protocol username
The Farcaster protocol display name
The Farcaster protocol bio
The Farcaster protocol profile picture
The Farcaster protocol profile url
The public key of the signer, if set. This is not guaranteed to be valid, as the user can revoke
the key at any time
Show Passkey
Show Passkey
Denotes that this is a Passkey account
The passkey credential ID
Whether or not this passkey can be used for MFA
The type of authenticator holding the passkey
Metadata about the device that registered the passkey
Metadata about the OS that registered the passkey
Metadata about the browser that registered the passkey
Show Telegram
Show Telegram
Denotes that this is a Telegram account
The user ID that owns this Telegram account
The first name of the user
The last name of the user
The username associated with the Telegram account
The url of the user’s profile picture
Show CrossApp
Show CrossApp
Denotes that this is a cross-app account
The user’s embedded wallet address(es) from the provider app
The user’s smart wallet address(es) from the provider app
Metadata about the provider app
The subject identifier for this cross-app account
The list of MFA Methods associated with this user.
Whether or not the user has explicitly accepted the Terms and Conditions and/or Privacy Policy
Whether or not the user is a guest
Show Optional fields
Show Optional fields
The user’s email address, if they have linked one. It cannot be linked to another user.
Show Properties
Show Properties
The email address.
The user’s phone number, if they have linked one. It cannot be linked to another user.
Show Properties
Show Properties
The phone number.
The user’s first verified wallet, if they have linked at least one wallet. It cannot be linked to
another user.
The user’s Twitter account, if they have linked one. It cannot be linked to another user.
The user’s Github account, if they have linked one. It cannot be linked to another user.
The user’s Tiktok account, if they have linked one. It cannot be linked to another user.
The user’s Line account, if they have linked one. It cannot be linked to another user.
The user’s LinkedIn account, if they have linked one. It cannot be linked to another user.
The user’s Farcaster account, if they have linked one. It cannot be linked to another user.
Show Properties
Show Properties
The Farcaster on-chain FID
The Farcaster ethereum address that owns the FID
The Farcaster protocol username
The Farcaster protocol display name
The Farcaster protocol bio
The Farcaster protocol profile picture
The Farcaster protocol profile url
The public key of the signer, if set. This is not guaranteed to be valid, as the user can
revoke the key at any time
The user’s Telegram account, if they have linked one. It cannot be linked to another user.
Custom metadata field for a given user account
You can set custom metadata for a user via Privy’s backend server SDK and/or
API endpoints.
user object will be undefined.Users can have multiple passkeys linked to their account. To find all linked
passkeys, use the
linkedAccounts list and filter by passkey account type.user object in a minimal user profile:Example User Profile
Report incorrect code
Copy
Ask AI
import { usePrivy } from "@privy-io/react-auth";
function User() {
const { ready, authenticated, user } = usePrivy();
// Show nothing if user is not authenticated or data is still loading
if (!(ready && authenticated) || !user) {
return null;
}
return (
<div>
<p>User {user.id} has linked the following accounts:</p>
<ul>
<li>Apple: {user.apple ? user.apple.email : "None"}</li>
<li>Discord: {user.discord ? user.discord.username : "None"}</li>
<li>Email: {user.email ? user.email.address : "None"}</li>
<li>Farcaster: {user.farcaster ? user.farcaster.username : "None"}</li>
<li>GitHub: {user.github ? user.github.username : "None"}</li>
<li>Google: {user.google ? user.google.email : "None"}</li>
<li>Instagram: {user.instagram ? user.instagram.username : "None"}</li>
<li>LinkedIn: {user.linkedin ? user.linkedin.email : "None"}</li>
<li>Line: {user.line ? user.line.email : "None"}</li>
<li>Phone: {user.phone ? user.phone.number : "None"}</li>
<li>Spotify: {user.spotify ? user.spotify.email : "None"}</li>
<li>Telegram: {user.telegram ? user.telegram.username : "None"}</li>
<li>TikTok: {user.tiktok ? user.tiktok.username : "None"}</li>
<li>Twitter: {user.twitter ? user.twitter.username : "None"}</li>
<li>Wallet: {user.wallet ? user.wallet.address : "None"}</li>
</ul>
</div>
);
}
Refreshing the user object
In order to update a user object after any type of backend update, (i.e. unlinking an account or setting custom metadata) you can ensure the user object in the application is up-to-date by invoking the refreshUser method from the useUser hook:Example refresh User
Report incorrect code
Copy
Ask AI
import { useUser } from "@privy-io/react-auth";
const { user, refreshUser } = useUser();
const updateMetadata = async (value: string) => {
// Make API request to update custom metadata for a user from the backend
const response = await updateUserMetadata({ value });
await refreshUser();
// `user` object should be updated
console.log(user);
};
You can get information about the current user from the For unauthenticated users, the Refreshing the
In order to update a
user object in the usePrivy hook:Report incorrect code
Copy
Ask AI
const {user} = usePrivy();
user object will be null. For authenticated users, you can use:user.idto get their Privy DID, which you may use to identify your user on your backenduser.created_atto get a UNIX timestamp of when the user was created.user.linked_accountsto get an array of the user’s linked accounts
Parsing linked accounts
Each entry in thelinked_accounts array has different fields depending on the user data associated with that account type.See the dropdowns below to see the specific fields associated with each account type.Refreshing the user object
In order to update a user object after any type of backend update, (i.e. unlinking an account or setting custom metadata) you can ensure the user object in the application is up-to-date by invoking the get method from the privyClient.user object:- _layout.tsx
- index.tsx
Report incorrect code
Copy
Ask AI
import { createPrivyClient, PrivyProvider } from "@privy-io/expo";
export const privyClient = createPrivyClient({
appId: "your-app-id",
})
export default function RootLayout() {
return (
<PrivyProvider
appId={Constants.expoConfig?.extra?.privyAppId}
client={privyClient}
>
<Stack>
<Stack.Screen name="index" />
</Stack>
</PrivyProvider>
);
}
Report incorrect code
Copy
Ask AI
import {privyClient} from '@/_layout';
const updateMetadata = async (value: string) => {
// Make API request to update custom metadata for a user from the backend
const response = await updateUserMetadata({ value });
// Refresh the user object to ensure it reflects the latest backend updates
await privyClient.user.get();
// `user` object should be updated
};
Show Wallet
Show Wallet
Denotes that this is a wallet account
The wallet ID of the wallet. Null if the wallet is not delegated. Only applies to embedded
wallets (walletClientType === ‘privy’)
The wallet address
Chain type of the wallet address
The wallet client used for this wallet during the most recent verification. If the value is
‘privy’, then this is a privy embedded wallet
The connector type used for this wallet during the most recent verification
If this is a ‘privy’ embedded wallet, stores the recovery method
Whether the wallet is imported. Only applies to embedded wallets (walletClientType === ‘privy’)
Whether the wallet is delegated. Only applies to embedded wallets (walletClientType === ‘privy’)
HD index for the wallet. Only applies to embedded wallets (walletClientType === ‘privy’)
Show SmartWallet
Show SmartWallet
Show Email
Show Email
Show Phone
Show Phone
Show Google
Show Google
Show Twitter
Show Twitter
Denotes that this is a Twitter account
The ‘sub’ claim from the Twitter-issued JWT for this account
The username associated with the Twitter account
The name associated with the Twitter account
The profile picture URL associated with the Twitter account
Show Discord
Show Discord
Show Github
Show Github
Denotes that this is a Github account
The ‘sub’ claim from the Github-issued JWT for this account
The username associated with the Github account
The name associated with the Github account
The email associated with the Github account
Show Spotify
Show Spotify
Show Instagram
Show Instagram
Show Tiktok
Show Tiktok
Show Line
Show Line
Denotes that this is a Line account
The ‘sub’ claim from the Line-issued JWT for this account
The name associated with the Line account
The email associated with the Line account
The profile image URL associated with the Line account
Show LinkedIn
Show LinkedIn
Denotes that this is a LinkedIn account
The ‘sub’ claim from the LinkedIn-issued JWT for this account
The name associated with the LinkedIn account
The email associated with the LinkedIn account
The vanityName/profile URL associated with the LinkedIn account
Show Apple
Show Apple
Show CustomJwt
Show CustomJwt
Show Farcaster
Show Farcaster
Denotes that this is a Farcaster account
The Farcaster on-chain FID
The Farcaster ethereum address that owns the FID
The Farcaster protocol username
The Farcaster protocol display name
The Farcaster protocol bio
The Farcaster protocol profile picture
The Farcaster protocol profile url
The public key of the signer, if set. This is not guaranteed to be valid, as the user can revoke
the key at any time
Show Passkey
Show Passkey
Denotes that this is a Passkey account
The passkey credential ID
Whether or not this passkey can be used for MFA
The type of authenticator holding the passkey
Metadata about the device that registered the passkey
Metadata about the OS that registered the passkey
Metadata about the browser that registered the passkey
Show Telegram
Show Telegram
Denotes that this is a Telegram account
The user ID that owns this Telegram account
The first name of the user
The last name of the user
The username associated with the Telegram account
The url of the user’s profile picture
Show CrossApp
Show CrossApp
Denotes that this is a cross-app account
The user’s embedded wallet address(es) from the provider app
The user’s smart wallet address(es) from the provider app
Metadata about the provider app
The subject identifier for this cross-app account
Once a user has authenticated with Privy, you will have access to the Refreshing the
To ensure the If the refresh operation is successful,
PrivyUser object. This will be the main entry point for all user actions.Report incorrect code
Copy
Ask AI
abstract class PrivyUser {
/// Unique identifier for the user.
String get id;
/// List of linked accounts associated with the user.
List<LinkedAccounts> get linkedAccounts;
/// List of embedded Ethereum wallets associated with the user.
List<EmbeddedEthereumWallet> get embeddedEthereumWallets;
/// List of embedded Solana wallets associated with the user.
List<EmbeddedSolanaWallet> get embeddedSolanaWallets;
/// Creates an Ethereum embedded wallet for the user.
Future<Result<EmbeddedEthereumWallet>> createEthereumWallet(
{bool allowAdditional = false});
/// Creates a Solana embedded wallet for the user.
Future<Result<EmbeddedSolanaWallet>> createSolanaWallet();
}
Linked accounts
A user contains a list of LinkedAccounts, which are all account types associated with the user.Report incorrect code
Copy
Ask AI
/// A sealed class representing different types of linked accounts.
sealed class LinkedAccount {}
/// Represents a phone number-based linked account.
class PhoneAccount extends LinkedAccount {}
/// Represents an email-based linked account.
class EmailAccount extends LinkedAccount {}
/// Represents a custom authentication-linked account.
class CustomAuth extends LinkedAccount {}
/// Represents an Ethereum embedded wallet linked account.
class EmbeddedEthereumWalletAccount extends LinkedAccount {}
/// Represents a Solana embedded wallet linked account.
class EmbeddedSolanaWalletAccount extends LinkedAccount {}
Refreshing the user object
To ensure the user object reflects the latest backend updates, invoke the refresh method on the user instance to synchronize it with the current data:Report incorrect code
Copy
Ask AI
final refreshResult = await privy.user?.refresh();
refresh() will return Result.success with no additional data.
If an error occurs during the refresh operation, refresh() will return Result.failure with an encapsulated PrivyException.Once a user has authenticated with Privy, you will have access to the
PrivyUser object. This will be the main entry point for all user actions.Report incorrect code
Copy
Ask AI
public data class PrivyUser(
// The user's Privy ID
val id: String,
// A list of all linked accounts - can be authentication methods or embedded wallets
val linkedAccounts: List<LinkedAccount>,
// A list of user's ethereum wallets
val ethereumWallets: List<EmbeddedEthereumWallet>,
// A list of the user's solana wallets
val solanaWallets: List<EmbeddedSolanaWallet>
// Refresh the user
public suspend fun refresh(): Result<Unit>
// Other user methods
)
public sealed interface LinkedAccount {
public data class PhoneAccount(/* Account specific data */) : LinkedAccount
public data class EmailAccount(/* Account specific data */) : LinkedAccount
public data class CustomAuth(/* Account specific data */) : LinkedAccount
public data class EmbeddedEthereumWalletAccount(/* Account specific data */) : LinkedAccount
public data class EmbeddedSolanaWalletAccount(/* Account specific data */) : LinkedAccount
// Other linked account types
}
Once a user has authenticated with Privy, you will have access to the
PrivyUser object. This will be the main entry point for all user actions.Report incorrect code
Copy
Ask AI
public protocol PrivyUser {
/// The user's Privy ID
var id: String { get }
/// The user's ID token
var identityToken: String? { get }
/// The point in time at which the logged in user was created.
/// Value will only be nil if there is no user currently logged in.
var createdAt: Date? { get }
// A list of all linked accounts - can be authentication methods or embedded wallets
var linkedAccounts: [LinkedAccount] { get }
// A list of user's ethereum wallets
var embeddedEthereumWallets: [EmbeddedEthereumWallet] { get }
// A list of the user's solana wallets
var embeddedSolanaWallets: [EmbeddedSolanaWallet] { get }
// Refresh the user
func refresh() async throws
// Returns the user's access token, but will first refresh the user session if needed.
func getAccessToken() async throws -> String
// Other user methods
}
public enum LinkedAccount {
case phone(PhoneNumberAccount)
case email(EmailAccount)
case customAuth(CustomAuth)
case embeddedEthereumWallet(EmbeddedEthereumWalletAccount)
case embeddedSolanaWallet(EmbeddedSolanaWalletAccount)
// Other linked account types
}
Once your user has successfully authenticated, you can get a The
PrivyUser object containing their account data via:Report incorrect code
Copy
Ask AI
// User will be null if no user is authenticated
PrivyUser user = PrivyManager.Instance.User;
PrivyUser implements the interface below:Report incorrect code
Copy
Ask AI
public interface IPrivyUser
{
// The user's ID
string Id { get; }
// List of the User's linked accounts
PrivyLinkedAccount[] LinkedAccounts { get; }
// A list of the user's embedded ethereum wallets
IEmbeddedEthereumWallet[] EmbeddedWallets { get; }
// A list of the user's embedded solana wallets
IEmbeddedSolanaWallet[] EmbeddedSolanaWallets { get; }
// Creates an embedded ethereum wallet for the user
Task<IEmbeddedEthereumWallet> CreateWallet(bool allowAdditional = false);
// Creates an embedded solana wallet for the user
Task<IEmbeddedSolanaWallet> CreateSolanaWallet(bool allowAdditional = false);
// Custom user metadata, stored as a set of key-value pairs.
// This custom metadata is set server-side.
Dictionary<string, string> CustomMetadata { get; }
}
Make sure you subscribe to the Authentication State Updates and avoid calling the
IPrivyUser object without being Authenticated, as properties will return a default value otherwise.See the default values for the PrivyUser when the user is not authenticated:
See the default values for the PrivyUser when the user is not authenticated:
user.Id = ""user.LinkedAccounts = []user.EmbeddedWallets = []user.CustomMetadata = new Dictionary()
You can set custom metadata for a user via Privy’s backend server SDK and/or API endpoints.

