@privy-io/react-auth
Version:
React client for the Privy Auth API
1,251 lines (1,236 loc) • 101 kB
text/typescript
import { createCoinbaseWalletSDK } from '@coinbase/wallet-sdk';
import { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/browser';
import { Rpc, SolanaRpcApi, RpcSubscriptions, SolanaRpcSubscriptionsApi } from '@solana/kit';
import { ReactElement, ReactNode } from 'react';
import { Hex } from 'viem';
import { OAuthProviderID, AppResponse, SmartWalletType, PasskeyAuthenticateRequestBody, CustomOAuthProviderID, WalletChainType, User as User$1 } from '@privy-io/api-types';
import { CountryCode, Chain, ConnectedStandardSolanaWallet, RpcConfig, ChainLikeWithId } from '@privy-io/js-sdk-core';
import { createBaseAccountSDK } from '@base-org/account';
import { WalletWithFeatures, Wallet as Wallet$1 } from '@wallet-standard/base';
import { SolanaSignMessageFeature, SolanaSignTransactionFeature, SolanaSignAndSendTransactionFeature, SolanaSignInFeature } from '@solana/wallet-standard-features';
import { StandardConnectFeature, StandardDisconnectFeature, StandardEventsFeature } from '@wallet-standard/features';
import EventEmitter from 'eventemitter3';
/**
* Internationalization strings for Privy UI components.
*
* Keys follow the pattern: `component.semanticDescription`
*/
type PrivyI18nStrings = {
'connectionStatus.successfullyConnected': string;
'connectionStatus.errorTitle': string;
'connectionStatus.connecting': string;
'connectionStatus.connectOneWallet': string;
'connectionStatus.checkOtherWindows': string;
'connectionStatus.stillHere': string;
'connectionStatus.tryConnectingAgain': string;
'connectionStatus.or': string;
'connectionStatus.useDifferentLink': string;
'connectWallet.connectYourWallet': string;
'connectWallet.waitingForWallet': string;
'connectWallet.connectToAccount': string;
'connectWallet.installAndConnect': string;
'connectWallet.tryConnectingAgain': string;
'connectWallet.openInApp': string;
'connectWallet.copyLink': string;
'connectWallet.retry': string;
'connectWallet.searchPlaceholder': string;
'connectWallet.noWalletsFound': string;
'connectWallet.lastUsed': string;
'connectWallet.selectYourWallet': string;
'connectWallet.selectNetwork': string;
'connectWallet.goToWallet': string;
'connectWallet.scanToConnect': string;
'connectWallet.openOrInstall': string;
};
interface ConnectorEvents {
walletsUpdated(): void;
initialized(): void;
}
/**
* @hidden
*
* A WalletConnector is identified by a connectorType and walletClientType. A
* connectorType includes injected, wallet_connect, etc. A walletClientType
* includes metamask, trustwallet, etc.
*
* Each WalletConnector manages a list of wallets, identified by an address
* and chainId. Each wallet has a connected property indicating its current
* connection status, which is determined based on events emitted by the
* underlying provider.
*
* The WalletConnector also emits two events: walletsUpdated and initialized.
* The walletsUpdated event is triggered when the list of wallets changes,
* while the initialized event is triggered when the WalletConnector is
* ready and has successfully executed the syncAccounts() function for
* the first time.
*/
declare abstract class WalletConnector extends EventEmitter<ConnectorEvents> {
connected: boolean;
initialized: boolean;
walletClientType: WalletClientType;
abstract wallets: (BaseConnectedEthereumWallet | BaseConnectedSolanaWallet)[];
abstract chainType: 'ethereum' | 'solana';
abstract connectorType: ConnectorType;
constructor(walletClientType: WalletClientType);
abstract isConnected(): Promise<boolean>;
abstract subscribeListeners(): void;
abstract unsubscribeListeners(): void;
abstract get walletBranding(): WalletBranding;
abstract initialize(): Promise<void>;
abstract connect(options: {
showPrompt?: boolean;
chainId?: number;
}): Promise<BaseConnectedWallet | null>;
abstract disconnect(): void;
abstract promptConnection(walletClientType: WalletClientType): void;
}
/**
* We support a subset of the provider methods found here:
*
* https://ethereum.org/en/developers/docs/apis/json-rpc/#json-rpc-methods
*
* For now, we're focused on signing-related methods because the iframe (this code)
* is the only place that has access to the private key and thus is the only one
* who can create signatures. All other methods do not need the private key and
* can therefore be implemented by clients of the iframe.
*/
declare const SUPPORTED_ETHEREUM_RPC_METHODS: readonly ["eth_sign", "eth_populateTransactionRequest", "eth_signTransaction", "personal_sign", "eth_signTypedData_v4", "csw_signUserOperation", "secp256k1_sign"];
type EthereumRpcMethodType = (typeof SUPPORTED_ETHEREUM_RPC_METHODS)[number];
declare const SUPPORTED_SOLANA_RPC_METHODS: string[];
type SolanaRpcMethodType = (typeof SUPPORTED_SOLANA_RPC_METHODS)[number];
type Quantity = string | number | bigint;
type UnsignedTransactionRequest = {
from?: string;
to?: string;
nonce?: Quantity;
gasLimit?: Quantity;
gasPrice?: Quantity;
data?: ArrayLike<number> | string;
value?: Quantity;
chainId?: number;
type?: number;
accessList?: Array<{
address: string;
storageKeys: Array<string>;
}> | Array<[string, Array<string>]> | Record<string, Array<string>>;
maxPriorityFeePerGas?: Quantity;
maxFeePerGas?: Quantity;
};
type TransactionLog = {
blockNumber: number;
blockHash: string;
transactionIndex: number;
removed: boolean;
address: string;
data: string;
topics: Array<string>;
transactionHash: string;
logIndex: number;
};
type TransactionReceipt = {
to: string;
from: string;
contractAddress: string;
transactionIndex: number;
root?: string;
logs: Array<TransactionLog>;
logsBloom: string;
blockHash: string;
transactionHash: string;
blockNumber: number;
confirmations: number;
byzantium: boolean;
type: number;
status?: number;
gasUsed: string;
cumulativeGasUsed: string;
effectiveGasPrice?: string;
};
interface BaseEthereumRpcRequestType {
method: EthereumRpcMethodType;
}
interface BaseSolanaRpcRequestType {
method: SolanaRpcMethodType;
}
interface eth_populateTransactionRequest extends BaseEthereumRpcRequestType {
method: 'eth_populateTransactionRequest';
params: [UnsignedTransactionRequest];
}
interface eth_populateTransactionRequestResponse {
method: 'eth_populateTransactionRequest';
data: UnsignedTransactionRequest;
}
interface eth_signTransaction extends BaseEthereumRpcRequestType {
method: 'eth_signTransaction';
params: [UnsignedTransactionRequest];
}
interface eth_sign extends BaseEthereumRpcRequestType {
method: 'eth_sign';
params: [address: string, message: string];
}
interface eth_signResponse {
method: 'eth_sign';
data: string;
}
interface personal_sign extends BaseEthereumRpcRequestType {
method: 'personal_sign';
params: [string, string];
}
interface personal_signResponse {
method: 'personal_sign';
data: string;
}
interface eth_signTransactionResponse {
method: 'eth_signTransaction';
data: string;
}
interface eth_signTypedData_v4 extends BaseEthereumRpcRequestType {
method: 'eth_signTypedData_v4';
params: [string, TypedMessage<MessageTypes> | string];
}
interface eth_signTypedData_v4Response {
method: 'eth_signTypedData_v4';
data: string;
}
interface secp256k1_sign extends BaseEthereumRpcRequestType {
method: 'secp256k1_sign';
params: [`0x${string}`];
}
interface secp256k1_signResponse {
method: 'secp256k1_sign';
data: `0x${string}`;
}
interface solana_signMessage extends BaseSolanaRpcRequestType {
method: 'signMessage';
params: {
message: string;
};
}
interface solana_signMessageResponse {
method: 'signMessage';
data: {
signature: string;
};
}
type EthereumRpcRequestType = eth_signTransaction | eth_populateTransactionRequest | eth_sign | personal_sign | eth_signTypedData_v4 | secp256k1_sign;
type EthereumRpcResponseType = eth_signTransactionResponse | eth_populateTransactionRequestResponse | eth_signResponse | personal_signResponse | eth_signTypedData_v4Response | secp256k1_signResponse;
type SolanaRpcRequestType = solana_signMessage;
type SolanaRpcResponseType = solana_signMessageResponse;
declare abstract class PrivyError extends Error {
/**
* Privy error type.
*/
abstract type: string;
/**
* Original Error object, it the error originated client-side.
*/
cause?: Error;
/**
* An optional error code, often included in Privy API responses.
*/
privyErrorCode?: PrivyErrorCode;
/**
* @param type Privy error type.
* @param message Human-readable message.
* @param cause Source of this error.
*/
protected constructor(message: string, cause?: unknown, privyErrorCode?: PrivyErrorCode);
toString(): string;
}
/**
* The PrivyConnector instance threw an exception.
*/
declare class PrivyConnectorError extends PrivyError {
type: string;
constructor(message: string, cause?: unknown, privyErrorCode?: PrivyErrorCode);
}
declare enum PrivyErrorCode {
OAUTH_ACCOUNT_SUSPENDED = "oauth_account_suspended",
MISSING_OR_INVALID_PRIVY_APP_ID = "missing_or_invalid_privy_app_id",
MISSING_OR_INVALID_PRIVY_ACCOUNT_ID = "missing_or_invalid_privy_account_id",
MISSING_OR_INVALID_TOKEN = "missing_or_invalid_token",
INVALID_DATA = "invalid_data",
INVALID_CAPTCHA = "invalid_captcha",
LINKED_TO_ANOTHER_USER = "linked_to_another_user",
CANNOT_LINK_MORE_OF_TYPE = "cannot_link_more_of_type",
FAILED_TO_LINK_ACCOUNT = "failed_to_link_account",
FAILED_TO_UPDATE_ACCOUNT = "failed_to_update_account",
USER_EXITED_UPDATE_FLOW = "exited_update_flow",
ALLOWLIST_REJECTED = "allowlist_rejected",
OAUTH_USER_DENIED = "oauth_user_denied",
OAUTH_UNEXPECTED = "oauth_unexpected",
UNKNOWN_AUTH_ERROR = "unknown_auth_error",
USER_EXITED_AUTH_FLOW = "exited_auth_flow",
USER_EXITED_LINK_FLOW = "exited_link_flow",
USER_EXITED_SET_PASSWORD_FLOW = "user_exited_set_password_flow",
MUST_BE_AUTHENTICATED = "must_be_authenticated",
UNKNOWN_CONNECT_WALLET_ERROR = "unknown_connect_wallet_error",
GENERIC_CONNECT_WALLET_ERROR = "generic_connect_wallet_error",
CLIENT_REQUEST_TIMEOUT = "client_request_timeout",
INVALID_CREDENTIALS = "invalid_credentials",
MISSING_MFA_CREDENTIALS = "missing_or_invalid_mfa",
UNKNOWN_MFA_ERROR = "unknown_mfa_error",
EMBEDDED_WALLET_ALREADY_EXISTS = "embedded_wallet_already_exists",
EMBEDDED_WALLET_NOT_FOUND = "embedded_wallet_not_found",
EMBEDDED_WALLET_CREATE_ERROR = "embedded_wallet_create_error",
UNKNOWN_EMBEDDED_WALLET_ERROR = "unknown_embedded_wallet_error",
EMBEDDED_WALLET_PASSWORD_UNCONFIRMED = "embedded_wallet_password_unconfirmed",
EMBEDDED_WALLET_PASSWORD_ALREADY_EXISTS = "embedded_wallet_password_already_exists",
EMBEDDED_WALLET_RECOVERY_ALREADY_EXISTS = "embedded_wallet_recovery_already_exists",
TRANSACTION_FAILURE = "transaction_failure",
UNSUPPORTED_CHAIN_ID = "unsupported_chain_id",
NOT_SUPPORTED = "not_supported",
CAPTCHA_TIMEOUT = "captcha_timeout",
INVALID_MESSAGE = "invalid_message",
UNABLE_TO_SIGN = "unable_to_sign",
CAPTCHA_FAILURE = "captcha_failure",
CAPTCHA_DISABLED = "captcha_disabled",
SESSION_STORAGE_UNAVAILABLE = "session_storage_unavailable",
TOO_MANY_REQUESTS = "too_many_requests",
USER_LIMIT_REACHED = "max_accounts_reached",
DISALLOWED_LOGIN_METHOD = "disallowed_login_method",
DISALLOWED_PLUS_EMAIL = "disallowed_plus_email",
PASSKEY_NOT_ALLOWED = "passkey_not_allowed",
USER_DOES_NOT_EXIST = "user_does_not_exist",
INSUFFICIENT_BALANCE = "insufficient_balance",
ACCOUNT_TRANSFER_REQUIRED = "account_transfer_required",
BUFFER_NOT_DEFINED = "buffer_not_defined",
UNSUPPORTED_WALLET_TYPE = "unsupported_wallet_type",
NO_SOLANA_ACCOUNTS = "no_solana_accounts",
UNKNOWN_FUNDING_ERROR = "unknown_funding_error"
}
declare class WalletTimeoutError extends PrivyConnectorError {
type: string;
constructor();
}
/**
* A ProviderRpcError combines the necessary bits of the {PrivyError} with the
* EIP-compliant ProviderRpcError. This is meant to be a type around errors raised
* by the ethereum provider.
*/
declare class ProviderRpcError extends PrivyError {
type: string;
readonly code: number;
readonly data?: unknown;
constructor(message: string, code: number, data?: unknown);
}
type ProviderConnectInfo = {
chainId: string;
};
type OnConnectEventHandler = (connectInfo: ProviderConnectInfo) => void;
type OnDisconnectEventHandler = (error: ProviderRpcError) => void;
type OnChainChangedEventHandler = (chainId: string | number) => void;
type OnAccountsChangedEventHandler = (accounts: string[]) => void;
type ProviderMessage = {
type: string;
data: unknown;
};
type OnMessageEventHandler = (message: ProviderMessage) => void;
type EIP1193OnEventHandler = OnConnectEventHandler | OnDisconnectEventHandler | OnChainChangedEventHandler | OnAccountsChangedEventHandler | OnMessageEventHandler;
interface EIP1193Provider {
rpcTimeoutDuration?: number;
request: (request: {
method: string;
params?: Array<any> | undefined;
}) => Promise<any>;
on: (eventName: string, listener: EIP1193OnEventHandler) => any;
removeListener: (eventName: string | symbol, listener: (...args: any[]) => void) => any;
}
interface RequestArguments {
readonly method: string;
readonly params?: readonly unknown[] | object | any;
}
declare global {
interface Window {
ethereum?: any;
}
}
/**
* @hidden
*
* The PrivyProxyProvider adds a middleware layer on top of the underlying wallet provider.
* */
declare class PrivyProxyProvider implements EIP1193Provider {
rpcTimeoutDuration: number;
walletProvider?: EIP1193Provider;
private _subscriptions;
constructor(walletProvider?: EIP1193Provider, rpcTimeoutDuration?: number);
on(eventName: string, listener: (...args: any[]) => void): any;
request(request: {
method: string;
params?: any[] | undefined;
}): Promise<any>;
removeListener: (eventName: string | symbol, listener: (...args: any[]) => void) => any;
walletTimeout: (error?: WalletTimeoutError, timeoutMs?: number) => Promise<string[]>;
setWalletProvider: (provider: EIP1193Provider) => void;
}
type BaseAccountSdkCreateParams = Parameters<typeof createBaseAccountSDK>[0];
type BaseAccountSdkType = ReturnType<typeof createBaseAccountSDK>;
type SetBaseAccountSdkType = (sdk: BaseAccountSdkType | undefined) => void;
/**
* Type of all Solana chains supported by Privy.
*/
type SolanaChain = (typeof SOLANA_CHAINS)[number];
/**
* Helper type for defining a Standard Wallet with a union of Solana features.
*/
type SolanaStandardWallet = WalletWithFeatures<{
'standard:connect'?: StandardConnectFeature['standard:connect'];
'standard:disconnect'?: StandardDisconnectFeature['standard:disconnect'];
'standard:events'?: StandardEventsFeature['standard:events'];
'solana:signMessage'?: SolanaSignMessageFeature['solana:signMessage'];
'solana:signTransaction'?: SolanaSignTransactionFeature['solana:signTransaction'];
'solana:signAndSendTransaction'?: SolanaSignAndSendTransactionFeature['solana:signAndSendTransaction'];
'solana:signIn'?: SolanaSignInFeature['solana:signIn'];
}>;
/**
* Represents a connection with a single Solana wallet provider. Manages wallet state
* including ongoing connection status, and exposes methods for connecting and disconnecting.
*/
declare class SolanaWalletConnector extends WalletConnector {
chainType: "solana";
connectorType: string;
wallets: BaseConnectedSolanaWallet[];
private _wallet;
private autoConnectEnabled;
private _unsubscribeListeners;
constructor(wallet: Wallet$1, autoConnectEnabled: boolean);
get isInstalled(): boolean;
get wallet(): SolanaStandardWallet;
/**
* Builds a connected wallet object to be exposed to the developer. This object
* contains the address and a few helper methods.
*
* Provider methods share the PrivyProxyProvider instance. This means that multiple
* wallets may share the same provider if one wallet was disconnected and another
* wallet was connected.
*
* A wallet is considered connected if it is present in the wallets array and is
* in a connected state.
*
* @hidden
*/
buildConnectedWallet(): BaseConnectedSolanaWallet[];
/**
* @hidden
*/
syncAccounts(): Promise<void>;
/**
* @hidden
*/
get walletBranding(): WalletBranding;
/**
* @hidden
*/
initialize(): Promise<void>;
/**
* @hidden
*/
connect(options: {
showPrompt: boolean;
}): Promise<BaseConnectedWallet | null>;
/**
* @hidden
*/
disconnect: () => Promise<void>;
/**
* @hidden
*/
promptConnection: () => Promise<void>;
protected onChange: () => void;
/**
* Get the most recently connected wallet.
*
* @hidden
*/
getConnectedWallet(): Promise<BaseConnectedSolanaWallet | null>;
/**
* We depend on the adapter to manage the connection state. We consider a wallet
* connected if the adapter is connected and its readyState is 'Installed'.
*
* @hidden
*/
isConnected(): Promise<boolean>;
/**
* @hidden
*/
subscribeListeners(): void;
/**
* @hidden
*/
unsubscribeListeners(): void;
private shouldAttemptAutoConnect;
}
interface SolanaWalletConnectorsOptions {
shouldAutoConnect?: boolean;
}
/**
* Plugin object to add solana support to the Privy SDK
*/
type SolanaWalletConnectorsConfig = {
/**
* Creates listeners for when solana wallets are registered or unregistered
*/
onMount: () => void;
/**
* Remove listener registered by `onMount`
*/
onUnmount: () => void;
/**
* Get all Wallets that have been registered, converted to `SolanaWalletConnectors`.
*/
get: () => SolanaWalletConnector[];
};
/**
* Wraps the wallet detection logic found in `@solana/wallet-standard-wallet-adapter-base`
* and `@wallet-standard-app`. Returns a `SolanaWalletConnectors` object to be used with the `PrivyProvider`.
*
* @param {SolanaWalletConnectorsOptions} args Configuration object
* @param {boolean} args.shouldAutoConnect Whether to automatically connect to the wallet.
* Defaults to `true` and should not prompt the user loudly for connection. However, some legacy
* adapters may still auto-connect loudly, so this flag can be used to disable that behavior.
*/
declare const toSolanaWalletConnectors: (args?: SolanaWalletConnectorsOptions) => SolanaWalletConnectorsConfig;
/**
* Accepted payment methods for the MoonPay fiat on-ramp.
*/
type MoonpayPaymentMethod = 'ach_bank_transfer' | 'credit_debit_card' | 'gbp_bank_transfer' | 'gbp_open_banking_payment' | 'mobile_wallet' | 'sepa_bank_transfer' | 'sepa_open_banking_payment' | 'pix_instant_payment' | 'yellow_card_bank_transfer';
type MoonpayUiConfig = {
accentColor?: string;
theme?: 'light' | 'dark';
};
/**
* Cryptocurrency codes for the MoonPay fiat on-ramp. These codes
* follow the format {TOKEN_NAME}_{NETWORK_NAME}.
*/
type MoonpayCurrencyCode = 'AVAX_CCHAIN' | 'CELO_CELO' | 'CUSD_CELO' | 'DAI_ETHEREUM' | 'ETH_ETHEREUM' | 'ETH_ARBITRUM' | 'ETH_POLYGON' | 'ETH_BASE' | 'FIL_FVM' | 'MATIC_ETHEREUM' | 'MATIC_POLYGON' | 'POL_POLYGON' | 'POL_ETHEREUM' | 'USDC_ETHEREUM' | 'USDC_ARBITRUM' | 'USDC_OPTIMISM' | 'USDC_POLYGON' | 'USDC_BASE' | 'USDC_CCHAIN' | 'USDT_ETHEREUM' | 'USDT_POLYGON' | 'WETH_POLYGON' | 'WBTC_ETHEREUM' | 'BNB_BNB' | 'BNB_BSC' | 'SOL' | 'USDC_SOL';
/**
* Configuration parameter for the MoonPay fiat on-ramp.
*/
type MoonpayConfig = {
currencyCode?: MoonpayCurrencyCode;
quoteCurrencyAmount?: number;
paymentMethod?: MoonpayPaymentMethod;
uiConfig?: MoonpayUiConfig;
};
type MoonpaySignRequest = {
address: string;
config: MoonpayConfig;
useSandbox: boolean;
};
type MoonpaySignResponse = {
signedUrl: string;
externalTransactionId: string;
};
declare const DEFAULT_BICONOMY_PAYMASTER_CONTEXT: {
mode: string;
calculateGasLimits: boolean;
expiryDuration: number;
sponsorshipInfo: {
webhookData: {};
smartAccountInfo: {
name: string;
version: string;
};
};
};
type BiconomyPaymasterContext = typeof DEFAULT_BICONOMY_PAYMASTER_CONTEXT;
type AlchemyPaymasterContextClient = {
policyId: string;
};
type CustomMetadataType = User$1['custom_metadata'];
declare const SUPPORTED_RECOVERY_PROVIDERS: readonly ["google-drive", "icloud"];
declare const SUPPORTED_MFA_METHODS: readonly ["sms", "totp", "passkey"];
type MfaMethod = (typeof SUPPORTED_MFA_METHODS)[number];
type MfaSubmitArgs = {
mfaMethod: MfaMethod;
mfaCode: string | PasskeyAuthenticateRequestBody['authenticator_response'];
relyingParty: string;
};
type EntropyIdVerifier = 'ethereum-address-verifier' | 'solana-address-verifier';
/**
* Supported OAuth providers for the recovery flow. Can be `'google-drive'`
*/
type RecoveryProviderType = (typeof SUPPORTED_RECOVERY_PROVIDERS)[number];
type LoginMethod = 'email' | 'sms' | 'siwe' | 'siws' | 'farcaster' | OAuthProviderID | 'passkey' | 'telegram' | 'custom' | 'guest';
type LoginWithCode = {
/**
* One-time password _([OTP](https://en.wikipedia.org/wiki/One-time_password))_ that was sent to user during first login step
*/
code: string;
};
declare const EMBEDDED_WALLET_CLIENT_TYPES: readonly ["privy"];
type EmbeddedWalletClientType = (typeof EMBEDDED_WALLET_CLIENT_TYPES)[number];
declare const INJECTED_WALLET_CLIENT_TYPES: readonly ["metamask", "phantom", "brave_wallet", "rainbow", "uniswap_wallet_extension", "uniswap_extension", "rabby_wallet", "bybit_wallet", "ronin_wallet", "haha_wallet", "crypto.com_wallet_extension", "crypto.com_onchain", "binance", "bitget_wallet"];
type InjectedWalletClientType = (typeof INJECTED_WALLET_CLIENT_TYPES)[number];
declare const COINBASE_WALLET_CLIENT_TYPES: readonly ["coinbase_wallet", "coinbase_smart_wallet", "base_account"];
type CoinbaseWalletClientType = (typeof COINBASE_WALLET_CLIENT_TYPES)[number];
type WalletConnectWalletClientType = (typeof WALLET_CONNECT_WALLET_CLIENT_TYPES)[number];
declare const UNKNOWN_WALLET_CLIENT_TYPES: readonly ["unknown"];
type UnknownWalletClientType = (typeof UNKNOWN_WALLET_CLIENT_TYPES)[number];
declare const SOLANA_WALLET_CLIENT_TYPES: readonly ["phantom", "solflare", "glow", "backpack", "jupiter", "mobile_wallet_adapter"];
type SolanaWalletClientType = (typeof SOLANA_WALLET_CLIENT_TYPES)[number];
type WalletClientType = InjectedWalletClientType | CoinbaseWalletClientType | WalletConnectWalletClientType | EmbeddedWalletClientType | UnknownWalletClientType | SolanaWalletClientType;
declare const SUPPORTED_CONNECTOR_TYPES: string[];
type ConnectorType = (typeof SUPPORTED_CONNECTOR_TYPES)[number];
/**
* Wallet metadata currently for internal use only
*/
type WalletBranding = {
name: string;
id: string;
icon?: string | EmbeddedSVG;
};
type LinkedAccountType = 'wallet' | 'smart_wallet' | 'email' | 'phone' | 'google_oauth' | 'twitter_oauth' | 'discord_oauth' | 'github_oauth' | 'spotify_oauth' | 'instagram_oauth' | 'tiktok_oauth' | 'line_oauth' | 'twitch_oauth' | 'linkedin_oauth' | 'apple_oauth' | 'custom_auth' | 'farcaster' | 'passkey' | 'telegram' | 'cross_app' | 'authorization_key' | CustomOAuthProviderID | 'guest';
/** @ignore */
interface LinkMetadata {
/** Account type, most commonly useful when filtering through linkedAccounts */
type: LinkedAccountType;
/** Datetime when this account was linked to the user. */
firstVerifiedAt: Date | null;
/** Datetime when this account was most recently used as a login/link method by the user. */
latestVerifiedAt: Date | null;
}
/**
* Config for preferred credit card provider. We will default to using this method first if available.
*/
type PreferredCardProvider = 'coinbase' | 'moonpay';
/**
* Configuration for the funding flow UIs.
*/
type FundingUiConfig = {
receiveFundsTitle?: string;
receiveFundsSubtitle?: string;
landing?: {
title?: string;
};
};
/**
* Configuration for Solana funding
*/
type SolanaFundingConfig = {
/** The chain used for connections */
chain?: SolanaChain;
/** The default amount in SOL */
amount?: string;
/** The default funding method */
defaultFundingMethod?: DefaultFundingMethod;
card?: {
/** The preferred card provider for funding */
preferredProvider?: PreferredCardProvider;
};
/** Customization for the funding UIs */
uiConfig?: FundingUiConfig;
/** The asset to fund with */
asset?: 'native-currency' | 'USDC';
};
/**
* Configuration for native funding amount.
*/
type NativeFundingConfig = {
chain?: ChainLikeWithId;
amount?: string;
defaultFundingMethod?: DefaultFundingMethod;
card?: {
/** The preferred card onramp for funding */
preferredProvider?: PreferredCardProvider;
};
/** Customization for the funding UIs */
uiConfig?: FundingUiConfig;
} | {
chain?: ChainLikeWithId;
amount: string;
asset: {
erc20: Hex;
} | 'USDC' | 'native-currency';
defaultFundingMethod?: DefaultFundingMethod;
card?: {
/** The preferred card onramp for funding */
preferredProvider?: PreferredCardProvider;
};
/** Customization for the funding UIs */
uiConfig?: FundingUiConfig;
};
/**
* Optional configuration parameter for the fiat on-ramp.
*/
type FundWalletConfig = NativeFundingConfig;
/**
* Status of a funding transaction
*/
type FundingStatus = 'completed' | 'cancelled';
/**
* Result returned when fundWallet() promise resolves
*/
interface FundingResult {
/**
* Status of the funding transaction
*/
status: FundingStatus;
/**
* Wallet address that was funded
*/
address: string;
/**
* Method used to fund the wallet
*/
fundingMethod: FundingMethod | undefined;
/**
* Transaction hash (if available from on-chain transfer or fiat provider)
*/
transactionHash?: string;
/**
* Amount transferred
*/
amount?: string;
/**
* Asset type transferred (e.g., 'Ether', 'USDC')
*/
assetType?: string;
/**
* Additional provider-specific metadata
*/
metadata?: {
/** Type of wallet used (e.g., 'metamask', 'rainbow', 'phantom') */
walletClientType?: string;
};
}
/**
* Possible methods of user-driven recovery.
* This is set, per app, on the server.
*/
type UserRecoveryMethod = 'user-passcode' | RecoveryProviderType;
/**
* Object representation of a user's wallet.
*/
interface Wallet {
/** The server wallet ID of the wallet. Null if the wallet is not delegated. Only applies to embedded wallets (`walletClientType === 'privy'` or `walletClientType === 'privy-v2'`). */
id?: string | null;
/** The wallet address. */
address: string;
/**
* Chain type of the wallet address.
*/
chainType: WalletChainType;
/**
* The wallet client used for this wallet during the most recent verification.
*
* If the value is `privy`, then this is a privy embedded wallet.
*
* Other values include but are not limited to `metamask`, `rainbow`, `coinbase_wallet`, etc.
*/
walletClientType?: string;
/**
* The connector type used for this wallet during the most recent verification.
*
* This includes but is not limited to `injected`, `wallet_connect`, `coinbase_wallet`, `embedded`.
*/
connectorType?: string;
/**
* If this is a 'privy' embedded wallet, stores the recovery method:
*
* 1. 'privy': privy escrow of the recovery material
* 2. 'user-passcode': recovery protected by user-input passcode
*/
recoveryMethod?: RecoveryMethod;
/** Whether the wallet is imported. Only applies to embedded wallets (`walletClientType === 'privy'` or `walletClientType === 'privy-v2'`). */
imported: boolean;
/** Whether the wallet is delegated. Only applies to embedded wallets (`walletClientType === 'privy'` or `walletClientType === 'privy-v2'`). */
delegated: boolean;
/** HD index for the wallet. Only applies to embedded wallets (`walletClientType === 'privy'` or `walletClientType === 'privy-v2'`). */
walletIndex: number | null;
/** Public key for the wallet. Only applies to tier 2 chains */
publicKey?: string;
}
/**
*
* Object representation of a base connected wallet from a wallet connector.
*/
interface BaseConnectedSolanaWallet extends BaseConnectedWallet {
type: 'solana';
provider: ConnectedStandardSolanaWallet;
}
/**
* Union type of all possible base connected wallets.
*/
type BaseConnectedWalletType = BaseConnectedEthereumWallet | BaseConnectedSolanaWallet;
/**
* Object representation of metadata reported by a connected wallet from a wallet connector
*/
interface ConnectedWalletMetadata {
/** The wallet name (e.g. MetaMask). */
name: string;
/** The wallet RDNS, falls back to the wallet name if none is available. */
id: string;
/** The wallet logo */
icon?: string;
}
/**
* Object representation of a base connected wallet from a wallet connector.
*/
interface BaseConnectedWallet {
type: 'ethereum' | 'solana';
/** The wallet address. */
address: string;
/** The first time this wallet was connected without break. */
connectedAt: number;
/**
* The wallet client where this key-pair is stored.
* e.g. metamask, rainbow, coinbase_wallet, etc.
*/
walletClientType: WalletClientType;
/**
* The connector used to initiate the connection with the wallet client.
* e.g. injected, wallet_connect, coinbase_wallet, etc.
*/
connectorType: ConnectorType;
/** Whether the wallet is imported. */
imported: boolean;
/**
* Metadata for the wallet.
*/
meta: ConnectedWalletMetadata;
/** Returns true if the wallet is connected, false otherwise */
isConnected: () => Promise<boolean>;
/**
* @experimental **Experimental**: This property is subject to change at any time.
*
* Not all wallet clients support programmatic disconnects (e.g. MetaMask, Phantom).
* In kind, if the wallet's client does not support programmatic disconnects,
* this method will no-op.
*/
disconnect: () => void;
}
/**
* Object representation of a base connected Ethereum wallet from a wallet connector.
*/
interface BaseConnectedEthereumWallet extends BaseConnectedWallet {
type: 'ethereum';
/** The current chain ID with CAIP-2 formatting. */
chainId: string;
/**
* Switch the network chain to a specified ID.
* Note: The chainId must be a supported network: https://docs.privy.io/guide/frontend/embedded/networks
* Note: This will not update any existing provider instances, re-request `wallet.getEthereumProvider` (e.g.)
* to get a provider with the updated chainId.
*
* @param targetChainId The specified chain ID to switch to, as a number or 0x prefixed string.
* @returns void
*/
switchChain: (targetChainId: `0x${string}` | number) => Promise<void>;
/** Helper methods to build providers for interfacing with this wallet. */
getEthereumProvider: () => Promise<EIP1193Provider>;
/**
* Perform personal_sign with the user's wallet.
*
* @param {string} message The message to sign.
* @returns {string} The resulting signature.
*/
sign: (message: string) => Promise<string>;
}
interface PrivyConnectedWallet {
/** True if this wallet is linked to the authenticated user. False if it is not yet linked or
* the user has not yet authenticated. */
linked: boolean;
/** Login with this wallet or link this wallet to the authenticated user.
*
* Throws a PrivyClientError if the wallet is not connected.
*/
loginOrLink: () => Promise<void>;
/** Unlink this wallet to the authenticated user. Throws a PrivyClientError if the user is not
* authenticated. */
unlink: () => Promise<void>;
/** The HD wallet index */
walletIndex?: number;
}
/**
* Object representation of a connected wallet, with additional Privy flows
*/
interface ConnectedWallet extends BaseConnectedEthereumWallet, PrivyConnectedWallet {
/**
* Prompt the user to go through the funding flow and for the connected wallet.
*
* This will open the modal with a prompt for the user to select a funding method (if multiple are enabled).
*
* Once the user continues to the funding flow, Privy will display the funding status screen, and wait
* for the transaction to complete.
*
* Note: Even after a successful funding, funds can take a few minutes to arrive in the user's wallet.
*
* Privy currently supports funding via external wallets and Moonpay.
*
* @param {FundWalletConfig} fundWalletConfig Funding configuration to specify chain and funding amount (if enabled)
* **/
fund: (fundWalletConfig?: FundWalletConfig) => Promise<void>;
}
/**
* Object representation of a smart wallet.
*/
interface SmartWallet {
/** The wallet address. */
address: string;
/** The provider of the smart wallet. */
smartWalletType: SmartWalletType;
/** The version of the smart wallet. */
smartWalletVersion?: string;
}
/** Object representation of a user's email. */
interface Email {
/** The email address. */
address: string;
}
/** Object representation of a user's phone number. */
interface Phone {
/** The phone number. */
number: string;
}
/** Object representation of a user's Google account. */
interface Google {
/** The `sub` claim from the Google-issued JWT for this account. */
subject: string;
/** The email associated with the Google account. */
email: string;
/** The name associated with the Google account. */
name: string | null;
}
/** Object representation of a user's Twitter account. */
interface Twitter {
/** The `sub` claim from the Twitter-issued JWT for this account. */
subject: string;
/** The username associated with the Twitter account. */
username: string | null;
/** The name associated with the Twitter account. */
name: string | null;
/** The profile picture URL associated with the Twitter account.
* Note that the Twitter image URL returned is appended with `_normal`
* to return a 48x48px image. In order to retrieve the original-sized image,
* remove the `_normal` from the URL as specified in the Twitter API docs:
* https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/user-profile-images-and-banners
*/
profilePictureUrl: string | null;
}
/** Object representation of a user's Discord account. */
interface Discord {
/** The `sub` claim from the Discord-issued JWT for this account. */
subject: string;
/** The username associated with the Discord account. */
username: string | null;
/** The email associated with the Discord account. */
email: string | null;
}
/** Object representation of a user's Github account. */
interface Github {
/** The `sub` claim from the Github-issued JWT for this account. */
subject: string;
/** The username associated with the Github account. */
username: string | null;
/** The name associated with the Github account. */
name: string | null;
/** The email associated with the Github account. */
email: string | null;
}
/** Object representation of a user's Spotify account. */
interface Spotify {
/** The user id associated with the Spotify account. */
subject: string;
/** The email associated with the Spotify account. */
email: string | null;
/** The display name associated with the Spotify account. */
name: string | null;
}
/** Object representation of a user's Instagram account. */
interface Instagram {
/** The user id associated with the Instagram account. */
subject: string;
/** The username associated with the Instagram account. */
username: string | null;
}
/** Object representation of a user's Tiktok account. */
interface Tiktok {
/** The `sub` claim from the Tiktok-issued JWT for this account. */
subject: string;
/** The username associated with the Tiktok account. */
username: string | null;
/** The display name associated with the Tiktok account. */
name: string | null;
}
/** Object representation of a user's Line account. */
interface Line {
/** The `sub` claim from the Line-issued JWT for this account. */
subject: string;
/** The name associated with the Line account. */
name: string | null;
/** The email associated with the Line account. */
email: string | null;
/** The profile image URL associated with the Line account. */
profilePictureUrl: string | null;
}
/** Object representation of a user's Twitch account. */
interface Twitch {
/** The unique identifier for the Twitch account. */
subject: string;
/** The username associated with the Twitch account. */
username: string | null;
}
/** Object representation of a user's LinkedIn account. */
interface LinkedIn {
/** The `sub` claim from the LinkedIn-issued JWT for this account. */
subject: string;
/** The name associated with the LinkedIn account. */
name: string | null;
/** The email associated with the LinkedIn account. */
email: string | null;
/** The vanityName/profile URL associated with the LinkedIn account. */
vanityName: string | null;
}
/** Object representation of a user's Apple account. */
interface Apple {
/** The `sub` claim from the Apple-issued JWT for this account. */
subject: string;
/** The email associated with the Apple account. */
email: string;
}
/** Object representation of a user's Custom OAuth Account. */
interface CustomOAuth {
/** The `sub` claim from the Custom OAuth-issued JWT for this account. */
subject: string;
/** The name associated with the Custom OAuth account. */
name: string | null;
/** The username associated with the Custom OAuth account. */
username: string | null;
/** The email associated with the Custom OAuth account. */
email: string | null;
/** The profile picture URL associated with the Custom OAuth account. */
profilePictureUrl: string | null;
}
interface CustomJwtAccount {
/** The user ID given by the custom auth provider */
customUserId: string;
}
interface Farcaster {
/** The Farcaster on-chain FID */
fid: number | null;
/** The Farcaster ethereum address that owns the FID */
ownerAddress: string;
/** The Farcaster protocol username */
username: string | null;
/** The Farcaster protocol display name */
displayName: string | null;
/** The Farcaster protocol bio */
bio: string | null;
/** The Farcaster protocol profile picture */
pfp: string | null;
/** The Farcaster protocol profile url */
url: string | null;
/** 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 */
signerPublicKey: string | null;
}
interface Telegram {
/** The user ID that owns this Telegram account. */
telegramUserId: string;
/** The first name of the user . */
firstName: string | null;
/** The last name of the user . */
lastName: string | null;
/** The username associated with the Telegram account. */
username: string | null;
/** The url of the user's profile picture. */
photoUrl: string | null;
}
interface Passkey {
/** The passkey credential ID */
credentialId: string;
/** The passkey public key (base64 encoded) */
publicKey?: string;
/** Whether or not this passkey can be used for MFA */
enrolledInMfa: boolean;
/** The type of authenticator holding the passkey */
authenticatorName?: string;
/** Metadata about the device that registered the passkey */
createdWithDevice?: string;
/** Metadata about the OS that registered the passkey */
createdWithOs?: string;
/** Metadata about the browser that registered the passkey */
createdWithBrowser?: string;
}
/** Metadata about the provider app for a cross-app account */
interface ProviderAppMetadata {
/** Privy app ID for the provider app. */
id: string;
/** Name for the provider app. */
name?: string;
/** Logo URL for the provider app. */
logoUrl?: string;
}
interface CrossAppAccount {
/** The user's embedded wallet address(es) from the provider app */
embeddedWallets: {
address: string;
}[];
smartWallets: {
address: string;
}[];
providerApp: ProviderAppMetadata;
subject: string;
}
/** Object representation of a user's email, with additional metadata for advanced use cases. */
interface EmailWithMetadata extends LinkMetadata, Email {
/** Denotes that this is an email account. */
type: 'email';
}
/** Object representation of a user's phone number, with additional metadata for advanced use cases. */
interface PhoneWithMetadata extends LinkMetadata, Phone {
/** Denotes that this is a phone account. */
type: 'phone';
}
/** Object representation of a user's wallet, with additional metadata for advanced use cases. */
interface WalletWithMetadata extends LinkMetadata, Wallet {
/** Denotes that this is a wallet account. */
type: 'wallet';
}
interface SmartWalletWithMetadata extends LinkMetadata, SmartWallet {
/** Denotes that this is a smart wallet account. */
type: 'smart_wallet';
}
/** Object representation of an HD embedded wallet with a defined `walletIndex` */
type HDWalletWithMetadata = WalletWithMetadata & {
walletIndex: number;
};
/** Object representation of a user's Google Account, with additional metadata for advanced use cases. */
interface GoogleOAuthWithMetadata extends LinkMetadata, Google {
/** Denotes that this is a Google account. */
type: 'google_oauth';
}
/** Object representation of a user's Twitter Account, with additional metadata for advanced use cases. */
interface TwitterOAuthWithMetadata extends LinkMetadata, Twitter {
/** Denotes that this is a Twitter account. */
type: 'twitter_oauth';
}
/** Object representation of a user's Discord Account, with additional metadata for advanced use cases. */
interface DiscordOAuthWithMetadata extends LinkMetadata, Discord {
/** Denotes that this is a Discord account. */
type: 'discord_oauth';
}
/** Object representation of a user's Github Account, with additional metadata for advanced use cases. */
interface GithubOAuthWithMetadata extends LinkMetadata, Github {
/** Denotes that this is a Github account. */
type: 'github_oauth';
}
/** Object representation of a user's Spotify Account, with additional metadata for advanced use cases. */
interface SpotifyOAuthWithMetadata extends LinkMetadata, Spotify {
/** Denotes that this is a Spotify account. */
type: 'spotify_oauth';
}
/** Object representation of a user's Instagram Account, with additional metadata for advanced use cases. */
interface InstagramOAuthWithMetadata extends LinkMetadata, Instagram {
/** Denotes that this is a Instagram account. */
type: 'instagram_oauth';
}
/** Object representation of a user's Tiktok Account, with additional metadata for advanced use cases. */
interface TiktokOAuthWithMetadata extends LinkMetadata, Tiktok {
/** Denotes that this is a Tiktok account. */
type: 'tiktok_oauth';
}
/** Object representation of a user's Line Account, with additional metadata for advanced use cases. */
interface LineOAuthWithMetadata extends LinkMetadata, Line {
/** Denotes that this is a Line account. */
type: 'line_oauth';
}
/** Object representation of a user's Twitch Account, with additional metadata for advanced use cases. */
interface TwitchOAuthWithMetadata extends LinkMetadata, Twitch {
/** Denotes that this is a Twitch account. */
type: 'twitch_oauth';
}
/** Object representation of a user's LinkedIn Account, with additional metadata for advanced use cases. */
interface LinkedInOAuthWithMetadata extends LinkMetadata, LinkedIn {
/** Denotes that this is a LinkedIn account. */
type: 'linkedin_oauth';
}
/** Object representation of a user's Apple Account, with additional metadata for advanced use cases. */
interface AppleOAuthWithMetadata extends LinkMetadata, Apple {
/** Denotes that this is a Apple account. */
type: 'apple_oauth';
}
/** Object representation of a user's Custom OAuth Account, with additional metadata for advanced use cases. */
interface CustomOAuthWithMetadata extends LinkMetadata, CustomOAuth {
/** Denotes that this is a Custom OAuth account. */
type: CustomOAuthProviderID;
}
/** Object representation of a user's Custom JWT Account, with additional metadata for advanced use cases. */
interface CustomJwtAccountWithMetadata extends LinkMetadata, CustomJwtAccount {
/** Denotes that this is an custom account. */
type: 'custom_auth';
}
/** Object representation of a user's Farcaster Account, with additional metadata for advanced use cases. */
interface FarcasterWithMetadata extends LinkMetadata, Farcaster {
/** Denotes that this is a Farcaster account. */
type: 'farcaster';
}
/** Object representation of a user's Passkey Account, with additional metadata for advanced use cases. */
interface PasskeyWithMetadata extends LinkMetadata, Passkey {
/** Denotes that this is a Passkey account. */
type: 'passkey';
}
/** Object representation of a user's Telegram Account, with additional metadata for advanced use cases. */
interface TelegramWithMetadata extends LinkMetadata, Telegram {
/** Denotes that this is a Telegram account. */
type: 'telegram';
}
/** Object representation of a user's cross-app account, with additional metadata for advanced use cases. */
interface CrossAppAccountWithMetadata extends LinkMetadata, CrossAppAccount {
/** Denotes that this is a cross-app account */
type: 'cross_app';
}
/**
* Object representation of a user's linked accounts
*/
type LinkedAccountWithMetadata = WalletWithMetadata | SmartWalletWithMetadata | EmailWithMetadata | PhoneWithMetadata | GoogleOAuthWithMetadata | TwitterOAuthWithMetadata | DiscordOAuthWithMetadata | GithubOAuthWithMetadata | SpotifyOAuthWithMetadata | InstagramOAuthWithMetadata | TiktokOAuthWithMetadata | LineOAuthWithMetadata | TwitchOAuthWithMetadata | LinkedInOAuthWithMetadata | AppleOAuthWithMetadata | CustomOAuthWithMetadata | CustomJwtAccountWithMetadata | FarcasterWithMetadata | PasskeyWithMetadata | TelegramWithMetadata | CrossAppAccountWithMetadata;
interface 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. */
id: string;
/** The datetime of when the user was created. */
createdAt: Date;
/** The user's email address, if they have linked one. It cannot be linked to another user. */
email?: Email;
/** The user's phone number, if they have linked one. It cannot be linked to another user. */
phone?: Phone;
/** The user's first verified wallet, if they have linked at least one wallet.
* It cannot be linked to another user.
**/
wallet?: Wallet;
/**
* The user's smart wallet, if they have set up through the Privy Smart Wallet SDK.
*/
smartWallet?: SmartWallet;
/** The user's Google account, if they have linked one. It cannot be linked to another user. */
google?: Google;
/** The user's Twitter account, if they have linked one. It cannot be linked to another user. */
twitter?: Twitter;
/** The user's Discord account, if they have linked one. It cannot be linked to another user. */
discord?: Discord;
/** The user's Github account, if they have linked one. It cannot be linked to another user. */
github?: Github;
/** The user's Spotify account, if they have linked one. It cannot be linked to another user. */
spotify?: Spotify;
/** The user's Instagram account, if they have linked one. It cannot be linked to another user. */
instagram?: Instagram;
/** The user's Tiktok account, if they have linked one. It cannot be linked to another user. */
tiktok?: Tiktok;
/** The user's Line account, if they have linked one. It cannot be linked to another user. */
line?: Line;
/** The user's Twitch account, if they have linked one. It cannot be linked to another user. */
twitch?: Twitch;
/** The user's LinkedIn account, if they have linked one. It cannot be linked to another user. */
linkedin?: LinkedIn;
/** The user's Apple account, if they have linked one. It cannot be linked to another user. */
apple?: Apple;
/** The user's Farcaster account, if they have linked one. It cannot be linked to another user. */
farcaster?: Farcaster;
/** The user's Telegram account, if they have linked one. It cannot be linked to another user. */
telegram?: Telegram;
/** The list of accounts associated with this user. Each account contains additional metadata
* that may be helpful for advanced use cases. */
linkedAccounts: Array<LinkedAccountWithMetadata>;
/** The list of MFA Methods associated with this user. */
mfaM