Documentation Index Fetch the complete documentation index at: https://docs.privy.io/llms.txt
Use this file to discover all available pages before exploring further.
This guide will help you migrate your Privy React SDK from v2.x.x to v3.0.0.
To install the latest version:
npm i @privy-io/react-auth@3
New features and improvements 🎉
Simplified Solana integration with one wallet per account and direct method access
Streamlined peer dependencies required for Solana
Removal of deprecated fields and methods
For the full set of changes check out our changelog .
Solana Updates
Update Peer Dependencies
If your app uses Privy’s Solana wallets, the required peer dependencies have changed in v3.0:
Remove these peer dependencies:
@solana/web3.js
@solana/spl-token
Install these new peer dependencies:
@solana/kit
@solana-program/memo
@solana-program/system
@solana-program/token
Additionally, if you are using webpack, include the following configurations to add them to webpack’s externals config. Note that these configurations are not needed if you are using Turbopack: // webpack.config.js
module . exports = {
//...
externals: {
[ '@solana/kit' ]: 'commonjs @solana/kit' ,
[ '@solana-program/memo' ]: 'commonjs @solana-program/memo' ,
[ '@solana-program/system' ]: 'commonjs @solana-program/system' ,
[ '@solana-program/token' ]: 'commonjs @solana-program/token'
}
};
// next.config.js
module . exports = {
webpack : ( config ) => {
// ...
config . externals [ '@solana/kit' ] = 'commonjs @solana/kit' ;
config . externals [ '@solana-program/memo' ] = 'commonjs @solana-program/memo' ;
config . externals [ '@solana-program/system' ] = 'commonjs @solana-program/system' ;
config . externals [ '@solana-program/token' ] = 'commonjs @solana-program/token' ;
return config ;
}
};
Solana RPC configuration
For Privy embedded wallet flows only (UI signTransaction and signAndSendTransaction), set RPCs in config.solana.rpcs. This replaces solanaClusters.
import { createSolanaRpc , createSolanaRpcSubscriptions } from '@solana/kit' ;
< PrivyProvider
appId = "your-privy-app-id"
config = { {
... theRestOfYourConfig ,
solanaClusters: [{ name: 'mainnet-beta' , rpcUrl: 'https://api.mainnet-beta.solana.com' }]
solana : {
rpcs: {
'solana:mainnet' : {
rpc: createSolanaRpc ( 'https://api.mainnet-beta.solana.com' ),
rpcSubscriptions: createSolanaRpcSubscriptions ( 'wss://api.mainnet-beta.solana.com' )
},
}
}
} }
>
{ /* your app's content */ }
</ PrivyProvider > ;
Replace useSolanaWallets
Replace useSolanaWallets with useWallets, useCreateWallet, and useExportWallet from the Solana entrypoint. The new useWallets hook returns ConnectedStandardSolanaWallet[].
import { useSolanaWallets } from '@privy-io/react-auth/solana' ;
import { useWallets , useCreateWallet , useExportWallet } from '@privy-io/react-auth/solana' ;
const { ready , wallets , createWallet , exportWallet } = useSolanaWallets ();
const { ready , wallets } = useWallets ();
const { createWallet } = useCreateWallet ();
const { exportWallet } = useExportWallet ();
Key differences between ConnectedSolanaWallet and ConnectedStandardSolanaWallet:
Each wallet represents a single connected account
Methods are available directly on the wallet instance:
wallet.signMessage({message})
wallet.signTransaction({transaction, chain})
wallet.signAndSendTransaction({transaction, chain})
wallet.signAndSendAllTransaction({transaction, chain}[])
wallet.disconnect()
The Solana standard wallet is available at wallet.standardWallet (for icon/name/etc.)
Removed wallet.loginOrLink() method - Use useLoginWithSiws and useLinkWithSiws instead:
import { useLoginWithSiws , useLinkWithSiws } from '@privy-io/react-auth' ;
const { generateSiwsMessage , loginWithSiws } = useLoginWithSiws ();
const { generateSiwsMessage , linkWithSiws } = useLinkWithSiws ();
// Login flow
await wallets [ 0 ]. loginOrLink ();
const message = await generateSiwsMessage ({ address: wallets [ 0 ]. address });
const encodedMessage = new TextEncoder (). encode ( message );
const results = await wallets [ 0 ]. signMessage ({ message: encodedMessage });
await loginWithSiws ({ message: encodedMessage , signature: results . signature });
// Link flow (similar pattern with linkWithSiws)
const results = await wallets [ 0 ]. signMessage ({ message: encodedMessage });
await linkWithSiws ({ message: encodedMessage , signature: results . signature });
Rename useSendTransaction
Update useSendTransaction from @privy-io/react-auth/solana to useSignAndSendTransaction from @privy-io/react-auth/solana
import { useSendTransaction } from '@privy-io/react-auth/solana' ;
import { useSignAndSendTransaction } from '@privy-io/react-auth/solana' ;
...
const { sendTransaction } = useSendTransaction ();
const { signAndSendTransaction } = useSignAndSendTransaction ();
Usage Examples
All Solana RPCs now expect buffer inputs.
New solana wallet usage
import { useWallets , type ConnectedStandardSolanaWallet } from '@privy-io/react-auth/solana' ;
import { TextEncoder } from '@solana/kit' ;
export function SolanaWallets () {
const { ready , wallets } = useWallets ();
if ( ! ready ) return < p > Loading... </ p > ;
return (
< div >
{ wallets . map (( wallet : ConnectedStandardSolanaWallet ) => (
< div key = { wallet . address } >
< img src = { wallet . standardWallet . icon } width = { 16 } height = { 16 } />
< span > { wallet . standardWallet . name } </ span >
< code > { wallet . address } </ code >
< button
onClick = {async () => {
const message = new TextEncoder (). encode ( 'Hello, world!' );
const { signature } = await wallet . signMessage ({ message });
console . log ( 'signature' , signature );
} }
>
Sign message
</ button >
</ div >
)) }
</ div >
);
}
Sign and send via hooks (with optional UI configuration)
import {
useWallets ,
useSignMessage ,
useSignTransaction ,
useSignAndSendTransaction
} from '@privy-io/react-auth/solana' ;
export function Actions () {
const { wallets } = useWallets ();
const { signMessage } = useSignMessage ();
const { signTransaction } = useSignTransaction ();
const { signAndSendTransaction } = useSignAndSendTransaction ();
const wallet = wallets [ 0 ];
if ( ! wallet ) return null ;
return (
< div >
< button
onClick = {async () => {
const message = new TextEncoder (). encode ( 'Hello from Privy' );
const { signature } = await signMessage ({
wallet ,
message ,
options: { uiOptions: { showWalletUIs: true }}
});
console . log ( signature );
} }
>
Sign message (hook)
</ button >
< button
onClick = {async () => {
// Create an encoded transaction using @solana/kit or @web3.js
const transaction = tx ; // type Uint8Array
const { signedTransaction } = await signTransaction ({
wallet ,
transaction ,
chain: 'solana:devnet'
});
console . log ( signedTransaction );
} }
>
Sign transaction (hook)
</ button >
< button
onClick = {async () => {
// Create an encoded transaction using @solana/kit or @web3.js
const transaction = tx ; // type Uint8Array
const { signature } = await signAndSendTransaction ({
wallet ,
transaction ,
chain: 'solana:devnet'
});
console . log ( signature );
} }
>
Sign & send (hook)
</ button >
</ div >
);
}
Other interface changes
Funding
Updated fundWallet interface
import { useFundWallet : useFundSolanaWallet } from '@privy-io/react-auth/solana' ;
import { useFundWallet : useFundEthereumWallet } from '@privy-io/react-auth' ;
...
const { fundWallet } = useFundSolanaWallet ();
await fundWallet ( '<solana address>' , { amount: '1' , asset: 'native-currency' , chain: 'solana:devnet' });
await fundWallet ({
address: '<solana address>' ,
options: { amount: '1' , asset: 'SOL' , chain: 'solana:devnet' }
});
const { fundWallet } = useFundEthereumWallet ();
await fundWallet ( '<ethereum address>' , { amount: '1000' , asset: 'native-currency' , chain: { id: 1 }});
await fundWallet ({
address: '<ethereum address>' ,
options: { amount: '1000' , asset: 'native-currency' , chain: { id: 1 }}
});
Removed/Deprecated Items
Removed suggestedAddress from connectWallet and linkWallet
connectWallet ({ suggestedAddress: '0x123...' });
connectWallet ({ description: `Connect the wallet with address ${ address } ` });
Removed detected_wallets from wallet lists/configuration
< PrivyProvider
config = { {
appearance: {
walletList: [
'detected_wallets' ,
'detected_ethereum_wallets' ,
'detected_solana_wallets' ,
'metamask'
// ...
]
}
// ...
} }
>
{ /* your app's content */ }
</ PrivyProvider >
Removed deprecated Moonpay config and types, add config to PrivyProviderConfig instead
fundEvmWallet ( address , {
config: {
currencyCode: 'ETH_ETHEREUM' ,
quoteCurrencyAmount: 0.01
},
provider: 'moonpay'
});
< PrivyProvider
config = { {
fundingMethodConfig: { moonpay: { useSandbox: true }}
// ...
} }
>
...
</ PrivyProvider > ;
fundEvmWallet ( address , {
chain: mainnet ,
amount: '0.01' ,
defaultFundingMethod: 'card'
});
Removed deprecated requireUserPasswordOnCreate and related embedded wallet config fields
**Removed embeddedWallets level createOnLogin field. Use embeddedWallets.etherum.createOnLogin or embeddedWallets.solana.createOnLogin instead. **
< PrivyProvider
config = { {
embeddedWallets: {
requireUserPasswordOnCreate: true ,
createOnLogin: 'all-users' ,
ethereum: { createOnLogin: 'all-users' }
// ...
}
// ...
} }
>
{ /* your app's content */ }
</ PrivyProvider >
Removed useLoginToFrame and replaced with useLoginToMiniApp
export { useLoginToFrame } from '@privy-io/react-auth' ;
export { useLoginToMiniApp } from '@privy-io/react-auth' ;
Removed useSignAuthorization() - Use useSign7702Authorization() instead
import { useSignAuthorization } from '@privy-io/react-auth' ;
import { useSign7702Authorization } from '@privy-io/react-auth' ;
const { signAuthorization } = useSignAuthorization ();
const { sign7702Authorization } = useSign7702Authorization ();
Removed useSetWalletPassword() - Use useSetWalletRecovery instead
import { useSetWalletPassword } from '@privy-io/react-auth' ;
import { useSetWalletRecovery } from '@privy-io/react-auth' ;
const { setWalletPassword } = useSetWalletPassword ();
const { setWalletRecovery } = useSetWalletRecovery ();
Updated Types
Removed verifiedAt from LinkMetadata and all linked accounts. Use firstVerifiedAt and latestVerifiedAt instead of the deprecated verifiedAt.
const verifiedDate = user . wallet . verifiedAt ;
const verifiedDate = user . wallet . firstVerifiedA ;