Skip to main content

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 v1.x.x to v2.0.0. To install the latest version, install the package from the latest tag:
npm i @privy-io/react-auth@latest

New features and improvements 🎉

  • Removed ethers v5 dependency, allowing developers to more easily use ethers v6
  • Added support for submitting transactions without waiting for confirmation
  • Added UIs for Ethereum signTransaction
For the full set of changes check out our changelog.

Breaking changes

Authentication

  • Guaranteed that user.wallet is the first linked wallet on the user object. To maintain state of the latest connected wallet, interact with the wallets array directly.
  • Removed the forkSession method. This feature was experimental and has been removed.
  • Removed the PrivyProvider’s deprecated onSuccess prop - use the onSuccess callback registered via the useLogin hook instead.

Embedded wallets

  • Apps using custom auth providers must now explicitly configure wallet UIs in the dashboard, or use the updated showWalletUIs option.
  • Removed the PrivyProvider’s deprecated createPrivyWalletOnLogin prop. Use config.embeddedWallets.createOnLogin instead.
<PrivyProvider
  createPrivyWalletOnLogin={true} // Remove
  config={{
    embeddedWallets: {createOnLogin: 'users-without-wallets'} // Add
  }}
>
  ...
</PrivyProvider>
  • Removed the deprecated additionalChains and rpcConfig props from PrivyProvider config, please configure these via the supportedChains
<PrivyProvider
  config={{
    additionalChains: [], // Remove
    rpcConfig: {}, // Remove
    supportedChains: [] // Add
  }}
>
  ...
</PrivyProvider>
  • Removed the deprecated noPromptOnSignature configuration option. Configure wallet UIs in the dashboard, or use the updated showWalletUIs option.
<PrivyProvider
  config={{
    embeddedWallets: {
      noPromptOnSignature: true, // Remove
      showWalletUIs: false // Add
    }
  }}
>
  ...
</PrivyProvider>

EVM

  • Removed the deprecated getEthersProvider and getWeb3jsProvider from the ConnectedWallet class. Use getEthereumProvider instead.
const provider = await wallet.getEthersProvider(); 
const privyProvider = await wallet.getEthereumProvider(); 
const provider = new ethers.providers.Web3Provider(privyProvider); 

const provider = await wallet.getWeb3jsProvider(); 
const privyProvider = await wallet.getEthereumProvider(); 
const provider = new Web3(privyProvider); 
  • Ethereum sendTransaction method now returns a Promise<{hash: string}> instead of a Promise<TransactionReceipt>. To get the full details of the submitted transaction, use a library like viem.
const receipt = await sendTransaction({...}); 
const {hash} = await sendTransaction({...}); 
const receipt = await publicClient.waitForTransactionReceipt({hash}); 
  • Removed the experimental waitForTransactionConfirmation config option as it is the default behavior.
<PrivyProvider
  config={{
    embeddedWallets: {
      waitForTransactionConfirmation: false
    }
  }}
>
  ...
</PrivyProvider>
  • Updated signMessage, signTypedData, sendTransaction, and signTransaction methods:
const {signMessage} = usePrivy();
// `uiOptions` and `address` are optional
const signature = await signMessage(message, uiOptions, address); 
// the first argument should be formatted `{message: string}`
const {signature} = await signMessage({message}, {uiOptions, address}); 

Smart Wallets

  • Updated signMessage, signTypedData, and sendTransaction methods of the smart wallet client:
import {useSmartWallets} from '@privy-io/react-auth/smart-wallets';

const {client} = useSmartWallets();
// `uiOptions` and `address` are optional
const signature = await client.signMessage({message}, uiOptions, address); 
const signature = await client.signMessage({message}, {uiOptions, address}); 

Solana

  • Migrated useSendSolanaTransaction from @privy-io/react-auth to useSendTransaction from @privy-io/react-auth/solana (Solana-specific export path)
import {useSendSolanaTransaction} from '@privy-io/react-auth'; 
import {useSendTransaction} from '@privy-io/react-auth/solana'; 

...

const {sendSolanaTransaction} = useSendSolanaTransaction(); 
const {sendTransaction} = useSendTransaction(); 
  • Removed sendSolanaTransaction from usePrivy in favor of exporting sendTransaction from useSendTransaction from @privy-io/react-auth/solana
import {usePrivy} from '@privy-io/react-auth'; 
import {useSendTransaction} from '@privy-io/react-auth/solana'; 

...

const {sendSolanaTransaction} = usePrivy(); 
const {sendTransaction} = useSendTransaction(); 
  • Removed delegateWalletAction from useSolanaWallets. Use delegateWallet from useDelegatedActions instead.
import {useSolanaWallets} from '@privy-io/react-auth/solana'; 
import {useDelegatedActions} from '@privy-io/react-auth'; 

...

const {delegateWalletAction} = useSolanaWallets(); 
delegateWalletAction(); 

const {delegateWallet} = useDelegatedActions(); 
await delegateWallet({  
  address: '<wallet to delegate>', 
  chainType: 'solana', 
}); 
  • Removed rpcUrl from fundWallet from useSolanaWallets. Set rpcUrl in config.solanaClusters prop of the PrivyProvider instead
import {useSolanaWallets} from '@privy-io/react-auth/solana';

const {fundWallet} = useSolanaWallets();
fundWallet({
  address: '<wallet to fund>',
  cluster: {name: 'mainnet-beta', rpcUrl: 'https://api.mainnet-beta.solana.com'}, 
  cluster: {name: 'mainnet-beta'} 
});

<PrivyProvider
  appId="your-privy-app-id"
  config={{
    ...theRestOfYourConfig,
    // Replace this with your required clusters and custom RPC URLs
    solanaClusters: [{name: 'mainnet-beta', rpcUrl: 'https://api.mainnet-beta.solana.com'}] 
  }}
>
  {/* your app's content */}
</PrivyProvider>;

Connectors

  • Removed the setActiveWallet method - use the wallets array directly to interact with wallets.

Callbacks

  • Updated all non-error callbacks to use named arguments instead of positional arguments.
const {login} = useLogin({
  onComplete: (user, isNewUser, wasAlreadyAuthenticated, loginMethod, linkedAccount) => { 
  onComplete: ({user, isNewUser, wasAlreadyAuthenticated, loginMethod, linkedAccount}) => { 

    console.log(user, isNewUser, wasAlreadyAuthenticated, loginMethod, linkedAccount);
    // Any logic you'd like to execute if the user is/becomes authenticated while this
    // component is mounted
  },
  ...
  onError: (error) => { // onError will continue to stay as a singular error argument
    console.log(error)
  }})

...
 const {reauthorize} = useOAuthTokens({
  onOAuthTokenGrant: (tokens: OAuthTokens, {user}: {user: User}) => {  
  onOAuthTokenGrant: ({tokens, user}) => {  
    const oAuthToken = tokens.accessToken

  ...
  }})