Skip to content

Callbacks

Callbacks allow your app to execute arbitrary logic after a Privy method completes.

As examples:

  • After a user logs in, you might want to execute a CAPTCHA test to verify that they are human.
  • After a user connects a wallet, you might want to prompt them to switch to a specific network.
  • After a user logs out, you might want to log an analytics event in your backend.

You can accomplish all of the above, and more, with callbacks! Read below to learn more.

TIP

We are actively updating every method in the Privy SDK to support usage of callbacks. If there's a particular method you urgently need callbacks support for, please reach out and we will prioritize it!

useLogin

To configure callbacks for Privy's login method, use the useLogin hook:

tsx
import {useLogin} from '@privy-io/react-auth';

const {login} = useLogin({
  onComplete: (user, isNewUser, wasAlreadyAuthenticated) => {
    console.log(user, isNewUser, wasAlreadyAuthenticated);
    // Any logic you'd like to execute if the user is/becomes authenticated while this
    // component is mounted
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the login flow or there is an error
  },
});

// Then call `login` in your code, which will invoke these callbacks on completion

As parameters to useLogin, you may include an onComplete callback and/or an onError callback.

onComplete

If set, the behavior of onComplete depends on if the user is already authenticated or not when the component is mounted to the page. Specifically:

  1. If the user is already authenticated when the component is mounted, the callback will execute immediately, as soon as the component mounts.
  2. If the user is not authenticated when the component is mounted, the callback will execute only after the user completes a successful login attempt and becomes authenticated.

Within this callback, you can access:

  • user: the user object with the user's DID, linked accounts, and more
  • isNewUser: a boolean indicating if this is the user's first login or if they are a returning user
  • wasAlreadyAuthenticated: a boolean indicating if the user was already authenticated when the component was mounted (case 1 from above) or if they became authenticated during this component's lifecycle (case 2 from above)
  • loginMethod: a string indicating the authentication method used if the user just logged in, or null if the user wasAlreadyAuthenticated when this component mounted.
    • Possible loginMethods are 'email', 'sms', 'siwe' (external wallet), 'apple', 'discord', 'github', 'google', 'linkedin', 'spotify', 'tiktok', and 'twitter'.

You can use the onComplete callback to invoke arbitrary logic for already-authenticated users and/or un-authenticated users who will login.

See an example of using the onComplete callback for login!

As an example, you might configure an onComplete callback to support the following behavior:

  • If the user wasAlreadyAuthenticated, redirect them away from your landing page to their profile page.
  • If the user logs in, and isNewUser, create the user in your own Users DB.
  • If the user logs in, and is a returning user, fetch their data from your own Users DB.

Below is a template for implementing the above with onComplete:

tsx
const onComplete = (user, isNewUser, wasAlreadyAuthenticated, loginMethod) => {
    if (wasAlreadyAuthenticated) {
        // In this case, the user was already `authenticated` when this component was mounted.
        //
        // For already-`authenticated` users, we redirect them to their profile page.
        router.push('/profile');
    } else {
        // In this case, the user was not already `authenticated` when the component was mounted
        // but successfully complete `login` during this component's lifecycle.
        //
        // For new `login`s, we make an API request to our backend to find or create the user in our
        // own DBs.
        if (isNewUser) {
            // If the user is new, create it in your backend
            await fetch('your-create-user-endpoint', {
                method: 'POST',
                body: JSON.stringify(user),
                ...
            });
        } else {
            // If the user is returning, fetch their data from your backend
            await fetch(`your-find-user-endpoint/${user.id}`, {
                method: 'GET',
                ...
            });
        }
    }
}

TIP

For redirects on login, we recommend using router.replace instead of window.location.replace to avoid a full page refresh where possible. This ensures that processes still occuring in memory (embedded wallet creation, processing of OAuth query parameters, and more) are not disrupted by the redirect.

onError

If set, the onError callback will execute after a user initiates a login attempt and there is an error, or if the user exits the login flow prematurely. Within this callback, you may access an error code with more information about the error.

useLinkAccount

To configure callbacks for Privy's link methods, use the useLinkAccount hook:

tsx
import {useLinkAccount} from '@privy-io/react-auth';

// can return any of the `link____` methods in the callback below
const {linkGoogle, linkEmail} = useLinkAccount({
  onSuccess: (user, linkedAccountType) => {
    console.log(user, linkedAccountType);
    // Any logic you'd like to execute if the user successfully links an account while this
    // component is mounted
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the link flow or there is an error
  },
});

// Then call one of the `link` methdos in your code, which will invoke these callbacks on completion

As parameters to useLinkAccount, you may include an onSuccess callback and/or an onError callback. Note that these callbacks will trigger whenever any new account is linked to a Privy user.

onSuccess

If set, the onSuccess callback will execute after a user has successfully links any type of new login method to their Privy account.

Within this callback, you can access:

  • user: the user object with the user's DID, linked accounts, and more mounted (case 1 from above) or if they became authenticated during this component's lifecycle (case 2 from above)
  • linkedAccountType: a string indicating the type of external account the user just linked to their Privy account.
    • Possible linkedAccountTypes are 'email', 'sms', 'siwe' (external wallet), 'apple', 'discord', 'github', 'google', 'linkedin', 'spotify', 'tiktok', and 'twitter'.

You can use the onSuccess callback to invoke arbitrary logic for users successfully adding a linkedAccount.

See an example of using the onSuccess callback for linking an account!

As an example, you might configure an onSuccess callback to support the following behavior:

  • If the user links an email to their account, add an email or phone number to your own Users DB.

Below is a template for implementing the above with onSuccess:

tsx
const onSuccess = (user, linkedAccountMethod) => {
    if (linkedAccountMethod === 'email') {
        // If the user is new, create it in your backend
        await fetch('your-add-email-to-user-endpoint', {
            method: 'POST',
            body: JSON.stringify(user),
            ...
        }
    } else if (linkedAccountMethod === 'sms') {
        // If the user is returning, fetch their data from your backend
        await fetch('your-add-phone-number-to-user-endpoint', {
            method: 'POST',
            body: JSON.stringify(user),
            ...
        }
    }
}

onError

If set, the onError callback will execute after a user initiates a link attempt and there is an error, or if the user exits the link flow prematurely. Within this callback, you may access an error code with more information about the error.

useConnectWallet

To configure callbacks for Privy's connectWallet method, use the useConnectWallet hook:

tsx
import {useConnectWallet} from '@privy-io/react-auth';

const {connectWallet} = useConnectWallet({
  onSuccess: (wallet) => {
    console.log(wallet);
    // Any logic you'd like to execute after a user successfully connects their wallet
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the connection flow or there is an error
  },
});

// Then call `connectWallet` in your code, which will invoke these callbacks on completion

As parameters to useConnectWallet, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of connectWallet will trigger the onSuccess callback or onError callback on completion, depending on if the connection attempt was successful or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully connected their wallet to your app. Within this callback, you can access a wallet parameter, which is the ConnectedWallet object for the wallet that the user has just connected.

onError

If set, the onError callback will execute after a user initiates a connection attempt and there is an error, or if the user exits the connection flow prematurely. Within this callback, you may access an error code with more information about the error.

useCreateWallet

To configure callbacks for Privy's createWallet method, use the useCreateWallet hook:

tsx
import {useCreateWallet} from '@privy-io/react-auth';

const {createWallet} = useCreateWallet({
  onSuccess: (wallet) => {
    console.log(wallet);
    // Any logic you'd like to execute after a user successfully creates their wallet
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the creation flow or there is an error
  },
});

// Then call `createWallet` in your code, which will invoke these callbacks on completion

As parameters to useCreateWallet, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of createWallet will trigger the onSuccess callback or onError callback on completion, depending on if the connection attempt was successful or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully created their wallet. Within this callback, you can access a wallet parameter, which is the Wallet object for the wallet that the user has just created.

onError

If set, the onError callback will execute after a user initiates a connection attempt and there is an error, or if the user exits the creation flow prematurely. Within this callback, you may access an error code with more information about the error.

useSetWalletPassword

To configure callbacks for Privy's setWalletPassword method, use the useSetWalletPassword hook:

tsx
import {useSetWalletPassword} from '@privy-io/react-auth';

const {setWalletPassword} = useSetWalletPassword({
  onSuccess: (wallet) => {
    console.log(wallet);
    // Any logic you'd like to execute after a user successfully sets a password on their wallet
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the password-setting flow or there is an error
  },
});

// Then call `setWalletPassword` in your code, which will invoke these callbacks on completion

As parameters to useSetWalletPassword, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of setWalletPassword will trigger the onSuccess callback or onError callback on completion, depending on if a password was successfully set on an embedded wallet or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully sets a password on their wallet. Within this callback, you can access a wallet parameter, which is the Wallet object for the wallet that the user has just created.

onError

If set, the onError callback will execute after a user attempts to set a password and there is an error, or if the user exits the creation flow prematurely. Within this callback, you may access an error code with more information about the error.

TIP

The onSuccess callback will fire only when a password is explicitly set using createWallet. Creating an embedded wallet password via wallet pregeneration or via createOnLogin will not fire this callback.

useLogout

To configure callbacks for Privy's logout method, use the useLogout hook:

tsx
import {useLogout} from '@privy-io/react-auth';

const {logout} = useLogout({
  onSuccess: () => {
    console.log('User logged out');
    // Any logic you'd like to execute after a user successfully logs out
  },
});

// Then call `logout` in your code, which will invoke this callback on completion

As a parameter to useLogout, you may include an onSuccess callback.

While this component is mounted, any successful invocation of logout will trigger the onSuccess callback on completion.

onSuccess

If set, the onSuccess callback will execute after a user successfully logs out from your app. A successful logout requires that the users auth tokens are cleared from their browser, and that their session is terminated in Privy's API.

useModalStatus

To attach a callback to whenever the Privy modal is opened or closed, use the useModalStatus hook:

tsx
import {useModalStatus} from '@privy-io/react-auth';

const {isOpen} = useModalStatus();

useModalStatus returns a boolean isOpen that indicates whether the Privy modal is currently opened or closed within your app's page.

You can then invoke arbitrary logic whenever the user opens or closes the Privy modal by listening to the isOpen variable in a dependency array, like so:

tsx
const {isOpen} = useModalStatus();

useEffect(() => {
  if (isOpen) {
    // Replace this with the logic you'd like to run when the modal is opened
    console.log('Privy modal is open');
  } else {
    // Replace this with the logic you'd like to run when the modal is closed
    console.log('Privy modal is closed');
  }
}, [isOpen]);

useToken

To configure callbacks for whenever Privy updates a user's app access token, use the useToken hook:

tsx
import {useToken} from '@privy-io/react-auth';

const {getAccessToken} = useToken({
  onAccessTokenGranted: (accessToken: string) => {
    // Any logic you'd like to execute after Privy has granted a user an app
    // access token or has refreshed their existing token
  },
  onAccessTokenRevoked: () => {
    // Any logic you'd like to execute when Privy revokes a user's app access token
    // and removes it from cookies or local storage
  },
});

// You may also call `getAccessToken` to get the user's current access token

As parameters to useToken, you may include an onAccessTokenGranted callback and/or an onAccessTokenRevoked callback.

TIP

The component where the useToken hook is invoked must be mounted while Privy grants or revokes the user's app access token in order for these callbacks to execute.

onAccessTokenGranted

If set, the onAccessTokenGranted callback will execute after Privy grants a new app access token for the user. This happens in two cases:

  • An unauthenticated user logs in, becomes authenticated, and receives an app access token to begin their session.
  • An authenticated user has their app access token refreshed by Privy.

Within this callback, you can access a accessToken parameter, which is the access token granted by Privy as a string.

Please note that this callback will execute whenever Privy grants a user a new app access token, and is not tied to any method call. In particular, calling getAccessToken will only invoke this callback if the user's existing access token must be refreshed, and Privy grants a new one.

onAccessTokenRevoked

If set, the onAccessTokenRevoked callback will execute after Privy logs out a user and removes their app access token from their browser local storage or cookies.

Please note that this callback will not execute if the user manually deletes their access token from their browser storage or cookies, outside of a Privy flow.

useSignMessage

To configure callbacks for Privy's signMessage method, use the useSignMessage hook:

tsx
import {useSignMessage} from '@privy-io/react-auth';

const {signMessage} = useSignMessage({
  onSuccess: (signature) => {
    console.log(signature);
    // Any logic you'd like to execute after a user successfully signs a message
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the message signing flow or there is an error
  },
});

// Then call `signMessage` in your code, which will invoke these callbacks on completion

As parameters to useSignMessage, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of signMessage will trigger the onSuccess callback or onError callback on completion, depending on if the message was successfully signed or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully signed the message. Within this callback, you can access a signature parameter, which is the signature string value generated by the wallet to sign the message.

onError

If set, the onError callback will execute after a user attempts to sign a message and there is an error, or if the user exits the signature flow prematurely. Within this callback, you may access an error code with more information about the error.

useSignTypedData

To configure callbacks for Privy's signTypedData method, use the useSignTypedData hook:

tsx
import {useSignTypedData} from '@privy-io/react-auth';

const {signTypedData} = useSignTypedData({
  onSuccess: (signature) => {
    console.log(signature);
    // Any logic you'd like to execute after a user successfully signs the EIP-712 typed data
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user exits the signing flow or there is an error
  },
});

// Then call `signTypedData` in your code, which will invoke these callbacks on completion

As parameters to useSignTypedData, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of signTypedData will trigger the onSuccess callback or onError callback on completion, depending on if the data was successfully signed or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully signed the message. Within this callback, you can access a signature parameter, which is the signature string value generated by the wallet to sign the data.

onError

If set, the onError callback will execute after a user attempts to sign the typed data and there is an error, or if the user exits the signature flow prematurely. Within this callback, you may access an error code with more information about the error.

useSendTransaction

To configure callbacks for Privy's sendTransaction method, use the useSendTransaction hook:

tsx
import {useSendTransaction} from '@privy-io/react-auth';

const {sendTransaction} = useSendTransaction({
  onSuccess: (response) => {
    console.log(response);
    // Any logic you'd like to execute after a user successfully sends a transaction
  },
  onError: (error) => {
    console.log(error);
    // Any logic you'd like to execute after a user fails to send a transaction
  },
});

// Then call `sendTransaction` in your code, which will invoke these callbacks on completion

As parameters to useSendTransaction, you may include an onSuccess callback and/or an onError callback.

While this component is mounted, any invocation of createWallet will trigger the onSuccess callback or onError callback on completion, depending on if the connection attempt was successful or not.

onSuccess

If set, the onSuccess callback will execute after a user has successfully created their wallet. Within this callback, you can access a response parameter, which is the response object of type TransactionResponse for the transaction that the embedded wallet just sent.

onError

If set, the onError callback will execute after a user initiates a transaction send attempt and there is an error, or if the user exits the transaction flow prematurely. Within this callback, you may access an error code with more information about the error.