UNPKG

@privy-io/react-auth

Version:

React client for the Privy Auth API

1,170 lines (1,159 loc) • 82.1 kB
import { Adapter, WalletError, MessageSignerWalletAdapterProps, WalletAdapterProps, SignerWalletAdapterProps } from '@solana/wallet-adapter-base'; import { ReactElement } from 'react'; import { Hex } from 'viem'; import { Cluster as Cluster$1, ChainLikeWithId, CountryCode, Chain } from '@privy-io/js-sdk-core'; import { SmartWalletType, CustomMetadataType, PasskeyAuthenticateInputType } from '@privy-io/public-api'; import { TypedMessage as TypedMessage$1, MessageTypes as MessageTypes$1 } from '@metamask/eth-sig-util'; import { Transaction, VersionedTransaction, ParsedTransactionWithMeta, Cluster } from '@solana/web3.js'; import EventEmitter from 'eventemitter3'; 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; } 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" } 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; } /** * 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 adapter; private autoConnectEnabled; constructor(adapter: Adapter, autoConnectEnabled: boolean); get isInstalled(): boolean; /** * 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(wallet: Adapter, meta: ConnectedWalletMetadata): BaseConnectedSolanaWallet; /** * @hidden */ syncAccounts(): Promise<void>; /** * @hidden */ get walletBranding(): WalletBranding; /** * @hidden */ initialize(): Promise<void>; /** * @hidden */ connect(options: { showPrompt: boolean; }): Promise<BaseConnectedSolanaWallet | null>; /** * @hidden */ disconnect: () => void; /** * @hidden */ promptConnection: () => Promise<void>; protected onDisconnect: () => void; protected onConnect: (_: any) => void; protected onError: (_: WalletError) => void; protected onReadyStateChange: (readyState: string) => 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; interface SolanaProvider { request: (request: { method: string; params?: any; }) => Promise<any>; } /** * 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' | 'USDC_ETHEREUM' | 'USDC_ARBITRUM' | 'USDC_OPTIMISM' | 'USDC_POLYGON' | 'USDC_BASE' | 'USDT_ETHEREUM' | 'USDT_POLYGON' | 'WETH_POLYGON' | 'WBTC_ETHEREUM' | 'BNB_BNB' | 'BNB_BSC' | '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; }; /** * A transaction that can be sent to the Solana network. Legacy transactions or v0 transactions (versioned) are supported. * Refer to {@link https://solana-labs.github.io/solana-web3.js/classes/Transaction.html Transaction} and {@link https://solana-labs.github.io/solana-web3.js/classes/VersionedTransaction.html VersionedTransaction} */ type SupportedSolanaTransaction = Transaction | VersionedTransaction; /** * Result of the transaction sent to the Solana network. */ type SolanaTransactionReceipt = { /** The signature of the transaction */ signature: string; /** The signed transaction */ signedTransaction: SupportedSolanaTransaction; /** The parsed transaction result. Refer to {@link https://solana-labs.github.io/solana-web3.js/types/ParsedTransactionWithMeta.html ParsedTransactionWithMeta}*/ parsedTransaction: ParsedTransactionWithMeta | null; /** The fees payed for the transaction in lamports */ fees: bigint; }; type SolanaCluster = { /** * The network name * Refer to {@link https://solana-labs.github.io/solana-web3.js/types/Cluster.html Cluster} for more information * */ name: Cluster; /** The RPC endpoint */ rpcUrl?: string; }; declare const SUPPORTED_OAUTH_PROVIDERS: readonly ["google", "discord", "twitter", "github", "spotify", "instagram", "tiktok", "linkedin", "apple"]; 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 | PasskeyAuthenticateInputType['authenticator_response']; relyingParty: string; }; type EntropyIdVerifier = 'ethereum-address-verifier' | 'solana-address-verifier' | 'p256'; /** * Supported OAuth providers. Can be `'google'`, `'discord'`, `'twitter'`, `'github'`, `'spotify'`, * `'instagram'`, `'tiktok'`, `'linkedin'`, or `'apple'` */ type OAuthProviderType = (typeof SUPPORTED_OAUTH_PROVIDERS)[number]; /** * 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' | OAuthProviderType | 'passkey' | 'telegram' | 'custom' | `privy:${string}` | '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"]; type InjectedWalletClientType = (typeof INJECTED_WALLET_CLIENT_TYPES)[number]; declare const COINBASE_WALLET_CLIENT_TYPES: readonly ["coinbase_wallet", "coinbase_smart_wallet"]; 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"]; 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' | 'linkedin_oauth' | 'apple_oauth' | 'custom_auth' | 'farcaster' | 'passkey' | 'telegram' | 'cross_app' | 'authorization_key' | 'guest'; /** @ignore */ interface LinkMetadata { /** Account type, most commonly useful when filtering through linkedAccounts */ type: LinkedAccountType; /** * @deprecated use `firstVerifiedAt` instead. * Datetime when this account was linked to the user or created. */ verifiedAt: Date; /** 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; } /** * Legacy configuration for the Moonpay funding selection. * * @deprecated */ type MoonpayFundingConfig = { config: MoonpayConfig; provider?: 'moonpay'; }; /** * 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; }; /** * Configuration for Solana funding */ type SolanaFundingConfig = { /** The cluster used for connections */ cluster?: { name: Cluster$1; }; /** 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; }; /** * 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 = MoonpayFundingConfig | NativeFundingConfig; /** * 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'`). */ id?: string | null; /** The wallet address. */ address: string; /** * Chain type of the wallet address. */ chainType: 'ethereum' | 'solana'; /** * 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?: 'privy' | UserRecoveryMethod; /** Whether the wallet is imported. Only applies to embedded wallets (`walletClientType === 'privy'`). */ imported: boolean; /** Whether the wallet is delegated. Only applies to embedded wallets (`walletClientType === 'privy'`). */ delegated: boolean; /** HD index for the wallet. Only applies to embedded wallets (`walletClientType === 'privy'`). */ walletIndex: number | null; } /** * 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 Solana wallet from a wallet connector. */ interface BaseConnectedSolanaWallet extends BaseConnectedWallet { type: 'solana'; /** * Returns a light provider for interfacing with this wallet. Support message signing * on embedded and external wallets using an internal interface. */ getProvider: () => Promise<SolanaProvider>; signMessage: MessageSignerWalletAdapterProps['signMessage']; sendTransaction: WalletAdapterProps['sendTransaction']; signTransaction: SignerWalletAdapterProps['signTransaction']; signAllTransactions: SignerWalletAdapterProps['signAllTransactions']; } /** * 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 connected Solana wallet for the user. */ interface ConnectedSolanaWallet extends BaseConnectedSolanaWallet, PrivyConnectedWallet { /** * @deprecated use the `useFundWallet` hook from the solana package instead. * **/ fund: (fundWalletConfig?: SolanaFundingConfig) => Promise<void>; } /** * Object representation of a smart wallet. */ interface SmartWallet { /** The wallet address. */ address: string; /** The provider of the smart wallet. */ smartWalletType: SmartWalletType; } /** 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 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; } 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; /** 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; } interface AuthorizationKeyAccount { publicKey: 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 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 Tiktok Account, with additional metadata for advanced use cases. */ interface SpotifyOAuthWithMetadata extends LinkMetadata, Spotify { /** Denotes that this is a Tiktok 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 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 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 authorization key, with additional metadata for advanced use cases. */ interface AuthorizationKeyAccountWithMetadata extends LinkMetadata, AuthorizationKeyAccount { /** Denotes that this is an authorization key */ type: 'authorization_key'; } /** * Object representation of a user's linked accounts */ type LinkedAccountWithMetadata = WalletWithMetadata | SmartWalletWithMetadata | EmailWithMetadata | PhoneWithMetadata | GoogleOAuthWithMetadata | TwitterOAuthWithMetadata | DiscordOAuthWithMetadata | GithubOAuthWithMetadata | SpotifyOAuthWithMetadata | InstagramOAuthWithMetadata | TiktokOAuthWithMetadata | LinkedInOAuthWithMetadata | AppleOAuthWithMetadata | CustomJwtAccountWithMetadata | FarcasterWithMetadata | PasskeyWithMetadata | TelegramWithMetadata | CrossAppAccountWithMetadata | AuthorizationKeyAccountWithMetadata; 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 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. */ mfaMethods: Array<MfaMethod>; /** * Whether or not the user has explicitly accepted the Terms and Conditions * and/or Privacy Policy */ hasAcceptedTerms: boolean; /** Whether or not the user is a guest */ isGuest: boolean; /** Custom metadata field for a given user account */ customMetadata?: CustomMetadataType; } type OAuthTokens = { /** The OAuth provider. */ provider: OAuthProviderType; /** The OAuth access token. */ accessToken: string; /** The number of seconds until the OAuth access token expires. */ accessTokenExpiresInSeconds?: number; /** The OAuth refresh token. */ refreshToken?: string; /** The number of seconds until the OAuth refresh token expires. * if the refresh token is present and this field is undefined, it is assumed * that the refresh token does not have an expiration date */ refreshTokenExpiresInSeconds?: number; /** The list of OAuth scopes the access token is approved for. */ scopes?: string[]; }; type FundingMethod = 'moonpay' | 'coinbase-onramp' | 'external'; /** The default funding method to immediately trigger when funding is requested */ type DefaultFundingMethod = 'card' | 'exchange' | 'wallet' | 'manual'; type HexColor = `#${string}`; /** * Options to customize the display of transaction prices in the embedded wallet's transaction prompt. */ type PriceDisplayOptions = { primary: 'fiat-currency'; secondary: 'native-token'; } | { primary: 'native-token'; secondary: null; }; type WalletListEntry = 'metamask' | 'coinbase_wallet' | 'rainbow' | 'phantom' | 'zerion' | 'cryptocom' | 'uniswap' | 'okx_wallet' | 'universal_profile' /** @deprecated Use `detected_ethereum_wallets` or `detected_solana_wallets` instead */ | 'detected_wallets' | 'detected_solana_wallets' | 'detected_ethereum_wallets' | 'wallet_connect' | 'rabby_wallet' | 'bybit_wallet' | 'ronin_wallet' | 'haha_wallet' | 'safe' | 'solflare' | 'backpack'; type NonEmptyArray<T> = [T, ...T[]]; type LoginMethodOrderOption = 'email' | 'sms' | WalletListEntry | OAuthProviderType | `privy:${string}` | 'farcaster' | 'telegram'; type ExternalWalletsConfig = { /** * Options to configure connections to the Coinbase Wallet (browser extension wallet, mobile wallet, and * passkey-based smart wallet). * * @experimental This is an experimental config designed to give Privy developers a way to test the Coinbase Smart Wallet * ahead of its mainnet launch. The smart wallet currently only supports the Base Sepolia testnet. In kind, DO NOT use this * configuration in production as it will prevent users from using the Coinbase Wallet on networks other than Base Sepolia. */ coinbaseWallet?: { /** * Whether Coinbase wallet connections should prompt the smart wallet, the extension wallet, or intelligently decide between the two. * - If 'eoaOnly', Coinbase wallet connections will only prompt the Coinbase wallet browser extension or mobile app (an externally-owned account) * - If 'smartWalletOnly', Coinbase wallet connections will only prompt the Coinbase smart wallet and will not allow users to use the extension or mobile app. * DO NOT use this setting in production. * - If 'all', Coinbase wallet connections will prompt the Coinbase wallet browser extension if it is detected as installed, and will otherwise prompt the smart wallet. */ connectionOptions: 'all' | 'eoaOnly' | 'smartWalletOnly'; }; /** * Options to configure WalletConnect behavior. * * @experimental This may change in future releases */ walletConnect?: { /** * If disabled, stops WalletConnect from being initialized by the Privy SDK. * * WARNING: If you allow WalletConnect or WalletConnect-powered wallets, this will cause issues. * * Note that even if disabled, WalletConnect code may still be loaded in the browser. Defaults to true. * * @experimental This feature is very experimental and may break your wallet connector experience if you use external wallets. */ enabled: boolean; }; solana?: { connectors?: SolanaWalletConnectorsConfig; }; }; interface PrivyClientConfig { /** All UI and theme related configuration */ appearance?: { /** Primary theme for the privy UI. This dictates the foreground and background colors within the UI. * * 'light' (default): The privy default light UI. * 'dark': The privy default dark UI. * custom hex code (i.e. '#13152F'): A custom background. This will generate the remainder of the foreground and * background colors for the UI by modulating the luminance of the passed color. This value should be _either_ dark * or light (<20% or >80% luminance), for accessibility. */ theme?: 'light' | 'dark' | HexColor; /** Accent color for the privy UI. * Used for buttons, active borders, etc. This will generate light and dark variants. * This overrides the server setting `accent_color`. */ accentColor?: HexColor; /** Logo for the main privy modal screen. * This can be a string (url) or an img / svg react element. * If passing an element, Privy will overwrite the `style` props, to ensure proper rendering. * This overrides the server setting `logo_url` */ logo?: string | ReactElement; /** * Header text for the landing screen of the Privy login modal. We strongly recommend using a string * of length 35 or less. Strings longer than the width of the login modal will be ellipsified. * * Defaults to 'Log in or sign up'. */ landingHeader?: string; /** * Subtitle text for the landing screen of the Privy login modal. * * This text will renders below the logo and will be capped at 100 characters. * * Defaults to undefined. */ loginMessage?: string; /** Determines the order of the login options in the privy modal. If true, the wallet login will render above * social and email / sms login options. * This overrides the server setting `show_wallet_login_first` */ showWalletLoginFirst?: boolean; /** * An array of {@link WalletListEntry wallet names} to configure the wallet buttons shown within * the `login`, `connectWallet`, and `linkWallet` modals. Privy will show buttons for each option * present in the list, in the order in which they are configured. * * On 'detected_wallets': * - This option serves as a fallback to include all wallets that detected by Privy, that might not be * individually configured in the `walletList`. Browser extension wallets that are not explicitly configured * in the `walletList` will fall into this category. * - If Privy detects a wallet, _and_ that wallet is configured within the `walletList` (e.g. 'metamask'), * the order of the wallet's explicit name (e.g. 'metamask') in the `walletList` will take priority * over the order of 'detected_wallets'. * * Defaults to ['detected_wallets', 'metamask', 'coinbase_wallet', 'rainbow', 'wallet_connect'] * * @default ['detected_wallets', 'metamask', 'coinbase_wallet', 'rainbow', 'wallet_connect'] */ walletList?: WalletListEntry[]; /** * Determines which external wallet types to show in the modal. By default, only Ethereum external wallets * are shown. If you want to show Solana wallets, set this to 'solana-only' or 'ethereum-and-solana'. * * When 'ethereum-and-solana' is set, Solana wallets will have a badge indicating that they are Solana wallets. * * @defaults 'ethereum-only' */ walletChainType?: 'ethereum-only' | 'solana-only' | 'ethereum-and-solana'; }; /** * Login methods for the privy modal. * * This parameter enables you to display a subset of the login methods specified in the developer dashboard. `loginMethods` cannot be an empty array if specified. The order of this array does not dictate order of the login methods in the UI. * * Note that any login method included in this parameter must also be enabled as a login method in the developer dashboard. * * If both `loginMethodsAndOrder` and `loginMethods` are defined, `loginMethodsAndOrder` will take precedence. */ loginMethods?: Array<'wallet' | 'email' | 'sms' | 'google' | 't