Skip to main content

Connecting to Phantom Wallets

The React SDK follows a clear connection pattern using hooks for wallet connection and chain-specific operations.
Learn about Phantom Connect: For details about authentication flows, OAuth login, extension login, account selection, and session management, see the Phantom Connect guide.

Connection Flow

  1. Provider Setup: Wrap your app with PhantomProvider
  2. Connection: Use useConnect() to establish wallet connection
  3. Chain Operations: Use chain-specific hooks (useSolana(), useEthereum()) for transactions and signing
import { useConnect, useSolana, useEthereum } from "@phantom/react-sdk";

function WalletExample() {
  const { connect } = useConnect();
  const { solana } = useSolana();
  const { ethereum } = useEthereum();

  // 1. Connect first with authentication provider
  const handleConnect = async () => {
    await connect({ provider: "google" });
  };

  // 2. Then use chain-specific operations
  const sendSolanaTransaction = async () => {
    const result = await solana.signAndSendTransaction(transaction);
  };

  const sendEthereumTransaction = async () => {
    const result = await ethereum.sendTransaction(transaction);
  };
}

Core Connection Hooks

useConnect

Connect to wallet with an authentication provider:
import { useConnect } from "@phantom/react-sdk";

function ConnectButton() {
  const { connect, isConnecting, error } = useConnect();

  const handleConnect = async () => {
    try {
      const { walletId, addresses } = await connect({ provider: "google" });
      console.log("Connected addresses:", addresses);
    } catch (err) {
      console.error("Failed to connect:", err);
    }
  };

  return (
    <button onClick={handleConnect} disabled={isConnecting}>
      {isConnecting ? "Connecting..." : "Connect Wallet"}
    </button>
  );
}

Authentication Providers

The connect() method accepts a provider parameter to specify how users should authenticate:
// Connect with Google OAuth
await connect({ provider: "google" });

// Connect with Apple OAuth
await connect({ provider: "apple" });

// Connect with Phantom extension for embedded wallets (if available)
await connect({ provider: "phantom" });

// Connect directly to the injected Phantom extension
await connect({ provider: "injected" });

useIsPhantomLoginAvailable

The "phantom" provider option allows users to authenticate an embedded wallet using their existing Phantom browser extension. Use the useIsPhantomLoginAvailable hook to check if this option is available:
import { useConnect, useIsPhantomLoginAvailable } from "@phantom/react-sdk";

function ConnectOptions() {
  const { connect, isConnecting } = useConnect();
  const { isAvailable, isLoading } = useIsPhantomLoginAvailable();

  const handlePhantomConnect = async () => {
    if (isAvailable) {
      await connect({ provider: "phantom" });
    }
  };

  const handleGoogleConnect = async () => {
    await connect({ provider: "google" });
  };

  if (isLoading) {
    return <div>Checking available login options...</div>;
  }

  return (
    <div>
      {isAvailable && (
        <button onClick={handlePhantomConnect} disabled={isConnecting}>
          Connect with Phantom Extension
        </button>
      )}
      <button onClick={handleGoogleConnect} disabled={isConnecting}>
        Connect with Google
      </button>
    </div>
  );
}
Benefits of Phantom extension login:
  • Faster authentication for existing Phantom users
  • No need to create a new account
  • Familiar Phantom interface
  • Same security and permission controls

useIsExtensionInstalled

The "injected" provider directly connects to the user’s Phantom browser extension (not an embedded wallet). Use the useIsExtensionInstalled hook to check if the extension is installed:
import { useConnect, useIsExtensionInstalled } from "@phantom/react-sdk";

function InjectedConnectButton() {
  const { connect, isConnecting } = useConnect();
  const { isInstalled, isLoading } = useIsExtensionInstalled();

  const handleInjectedConnect = async () => {
    if (isInstalled) {
      await connect({ provider: "injected" });
    }
  };

  if (isLoading) {
    return <div>Checking for Phantom extension...</div>;
  }

  if (!isInstalled) {
    return (
      <div>
        <p>Phantom extension not found.</p>
        <a href="https://phantom.app/download" target="_blank">
          Install Phantom
        </a>
      </div>
    );
  }

  return (
    <button onClick={handleInjectedConnect} disabled={isConnecting}>
      Connect to Phantom Extension
    </button>
  );
}
When to use injected provider:
  • User wants to use their existing extension wallet directly
  • No embedded wallet creation needed
  • Direct access to extension accounts and balances

Core Account Hooks

useAccounts

Get connected wallet addresses:
import { useAccounts } from "@phantom/react-sdk";

function WalletAddresses() {
  const addresses = useAccounts();

  if (!addresses) {
    return <div>Not connected</div>;
  }

  return (
    <div>
      {addresses.map((addr, index) => (
        <div key={index}>
          <strong>{addr.addressType}:</strong> {addr.address}
        </div>
      ))}
    </div>
  );
}

useDisconnect

Disconnect from wallet:
import { useDisconnect } from "@phantom/react-sdk";

function DisconnectButton() {
  const { disconnect, isDisconnecting } = useDisconnect();

  return (
    <button onClick={disconnect} disabled={isDisconnecting}>
      {isDisconnecting ? "Disconnecting..." : "Disconnect"}
    </button>
  );
}

Configuration Options

Important notes about redirectUrl (for embedded provider):
  • Must be an existing page/route in your application
  • Must be whitelisted in your Phantom Portal app configuration
  • This is where users will be redirected after completing OAuth authentication
Configure this in your PhantomProvider:
import { PhantomProvider, AddressType } from "@phantom/react-sdk";

function App() {
  return (
    <PhantomProvider
      config={{
        appId: "your-app-id",
        addressTypes: [AddressType.solana, AddressType.ethereum],
        authOptions: {
          redirectUrl: "https://yourapp.com/auth/callback",
        },
      }}
    >
      <YourApp />
    </PhantomProvider>
  );
}