privy
Privy
Privy is an embedded wallet and authentication SDK that lets dApps onboard users with email, phone, social logins, passkeys, or existing wallets -- without requiring users to install a browser extension or manage seed phrases. The SDK creates non-custodial embedded wallets using 2-of-3 Shamir Secret Sharing (SSS) with TEE (Trusted Execution Environment) infrastructure. Privy was acquired by Stripe in June 2025, signaling deeper payment-rails integration ahead.
What You Probably Got Wrong
-
HTTPS is required -- WebCrypto fails silently on HTTP -- Privy's key sharding relies on the Web Crypto API, which only works in secure contexts. Loading your app over
http://(exceptlocalhost) silently fails with no error message. The SDK initializes but wallet operations produce cryptic failures. Always deploy behind HTTPS. On local dev,localhostgets a browser exception, buthttp://192.168.x.xdoes not. The primary threat vector for SSS key sharding is browser malware on the device share. In the 2-of-3 SSS model, compromising ANY 2 shares reconstructs the full private key: device share (browser malware) + Privy share (Privy infrastructure breach) = full key compromise. The recovery share alone cannot reconstruct the key, but it reduces the attack surface to 2 parties instead of 3. -
Creating a Solana embedded wallet before EVM permanently blocks EVM wallet creation -- Privy creates embedded wallets lazily after first login. If you call
createWallet({ type: 'solana' })before the EVM wallet exists, the EVM wallet slot is permanently blocked for that user. Always create the EVM wallet first, or usecreateOnLogin: 'all-users'to auto-create both in the correct order. -
Farcaster login +
createOnLogin: 'users-without-wallets'blocks embedded wallet creation -- Farcaster accounts already have a custody wallet, so Privy treats them as "users with wallets" and skips embedded wallet creation. But the Farcaster custody wallet is not usable in-browser for signing transactions. UsecreateOnLogin: 'all-users'if you support Farcaster login, or manually callcreateWallet()after login. -
verifyAuthTokenonly works on ACCESS tokens, not identity tokens -- Privy issues two token types: access tokens (short-lived, for API auth) and identity tokens (contain user profile data). CallingverifyAuthToken(identityToken)silently fails or throws a misleading error. For identity tokens, usegetUser({ idToken })instead. Server-side verification requires your app SECRET (not app ID). -
v3 Solana peer dep migration is the #1 upgrade failure point -- Privy v3 dropped
@solana/web3.jsin favor of@solana/kit. If you see peer dependency conflicts or runtime errors after upgrading, remove@solana/web3.jsentirely and install@solana/kit. The API surface changed significantly --ConnectionbecomescreateSolanaRpc,PublicKeybecomesaddress(). -
Privy wallets are NOT custodial -- The private key is split into 3 shares via Shamir Secret Sharing: (1) device share stored in the browser, (2) Privy share stored in TEE infrastructure, (3) recovery share set up by the user. Any 2 of 3 shares reconstruct the key. Privy alone cannot access user funds.
-
Embedded wallets are created AFTER first login, not during -- The
PrivyProviderconfigcreateOnLogincontrols this. The wallet does not exist during the login callback. Check for wallet existence after the login flow completes and theuseWallets()hook updates.