Skip to content

Using external Solana wallets

Configuring connectors and the Privy Provider

In order to begin using Solana connectors in Privy, import and configure the toSolanaWalletConnectors function. Then, enable solana as a chain type on the PrivyProvider:

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

const solanaConnectors = toSolanaWalletConnectors({
  // By default, shouldAutoConnect is enabled
  shouldAutoConnect: true,
});

const Provider: React.FC<PropsWithChildren> = ({children}) => {
  return (
    <PrivyProvider
      config={{
        appearance: {
          // Use 'solana-only' or 'ethereum-and-solana'
          walletChainType: 'solana-only',
        },
        externalWallets: {
          solana: {
            connectors: solanaConnectors,
          },
        },
      }}
    >
      {children}
    </PrivyProvider>
  );
};

INFO

Some Solana wallet connectors do not gracefully support autoConnect, which will result in an extension pop-up on page load. If you would like to disable this feature, toggle it in the toSolanaWalletConnectors function.

Connecting the wallet

To prompt a user to connect an external wallet to your app, use the connectWallet method of the usePrivy hook. This is the same method that is used in the Ethereum wallet connection flow:

tsx
const {connectWallet} = usePrivy();

This method will prompt the user to select the wallet they want to connect. You can prompt users to connect as many wallets as you'd like to your app.

For example, you might have a "Connect" button in your app that prompts users to connect their wallet, like so:

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

export default function ConnectWalletButton() {
  const {connectWallet} = usePrivy();
  // Prompt user to connect a wallet with Privy modal
  return <button onClick={connectWallet}>Connect wallet</button>;
}

As an optional parameter to connectWallet, you may pass an object with the following optional fields:

FieldTypeDescription
suggestedAddressstringAn suggested address for the user to connect, which will be displayed in Privy's UI.
walletListWalletListEntry[]A list of wallet options that you would like Privy to display in the connection prompt.
tsx
connectWallet({
  suggestedAddress: '1111WS4xG97qPg6xehU4MadJZifPyQPgYPHfsS3X1111',
  walletList: ['phantom', 'solflare'],
});

Once a user has connected their external Solana wallet to your app, the wallet will appear in Privy's useSolanaWallets array, which you can then use to request signatures and transactions from the connected wallet.

Connecting or creating a wallet

You can also use Privy to connect a user's external wallet if they have one, or to create an embedded wallet for them if they do not. To do so, use the connectOrCreateWallet method of the usePrivy hook:

tsx
const {connectOrCreateWallet} = usePrivy();

This method will prompt the user to connect an external wallet, or log in with email, SMS, or socials, depending on your configured loginMethods, to create an embedded wallet.

For example, you might have a "Connect" button in your app that prompts users to connect their wallet, like so:

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

export default function ConnectWalletButton() {
  const {connectOrCreateWallet} = usePrivy();
  // Prompt user to connect a wallet with Privy modal
  return <button onClick={connectOrCreateWallet}>Connect wallet</button>;
}

TIP

This method functions exactly the same as Privy's login method, except when users connect their external wallet, they will not automatically be prompted to authenticate that wallet by signing a message

Once a user has connected their wallet to your app, and the wallet is available in the useSolanaWallets array, you can also prompt them to login with that wallet or link that wallet to their existing account, instead of prompting the entire login or linkWallet flow.

To do so, find the ConnectedWallet object from Privy's useSolanaWallets array, and call the object's loginOrLink method:

tsx
const {wallets} = useSolanaWallets();
...
wallets[0].loginOrLink();

When called, loginOrLink will directly request a SIWS signature from the user's connected wallet to authenticate the wallet.

If the user was not authenticated when the method was called, the user will become authenticated after signing the SIWS message.

If the user was already authenticated when the method was called, the user will remain authenticated after signing the SIWS message, and the connected wallet will become one of the user's linkedAccounts in their user object.

You might use the methods above to "split up" the connect and sign steps of external wallet login, like so:

tsx
import {usePrivy} from '@privy-io/react-auth';
import {useSolanaWallets} from '@privy-io/react-auth/solana';

export default function WalletButton() {
  const {connectWallet} = usePrivy();
  const {wallets} = useSolanaWallets();

  // Prompt user to connect a wallet with Privy modal
  return (
    {/* Button to connect wallet */}
    <button
        onClick={connectWallet}>
        Connect wallet
    </button>
    {/* Button to login with or link the most recently connected wallet */}
    <button
        disabled={!wallets[0]}
        onClick={() => { wallets[0].loginOrLink() }}>
        Login with wallet
    </button>
  );
}