Skip to main content
The Phantom Connect React Native SDK provides React hooks for connecting to Phantom wallets with OAuth authentication and hardware-backed security.
Learn about Phantom Connect: For details about authentication flows, login, account selection, and session management, see the Phantom Connect guide.
The SDK includes a built-in bottom sheet modal that provides a user-friendly interface for connecting to Phantom. Use the useModal() hook to control it:
import React from "react";
import { View, Button, Text } from "react-native";
import { useModal, useAccounts } from "@phantom/react-native-sdk";

function WalletScreen() {
  const modal = useModal();
  const { isConnected, addresses } = useAccounts();

  if (!isConnected) {
    return (
      <View style={{ padding: 20 }}>
        <Button title="Connect Wallet" onPress={() => modal.open()} />
      </View>
    );
  }

  return (
    <View style={{ padding: 20 }}>
      <Text style={{ fontSize: 18, marginBottom: 10 }}>Wallet Connected</Text>
      {addresses.map((addr, index) => (
        <Text key={index}>
          {addr.addressType}: {addr.address}
        </Text>
      ))}
      <Button title="Manage Wallet" onPress={() => modal.open()} />
    </View>
  );
}
Modal features:
  • Multiple auth providers: Google, Apple
  • Bottom sheet design: Optimized for mobile
  • Automatic state management: Connect vs. wallet management views
  • Built-in error handling and loading states

useConnect hook (manual connection)

import React from "react";
import { View, Button, Alert } from "react-native";
import { useConnect } from "@phantom/react-native-sdk";

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

  const handleConnect = async () => {
    try {
      const result = await connect({ provider: "google" });
      Alert.alert("Success", "Wallet connected!");
      console.log("Connection successful:", result);
    } catch (error) {
      Alert.alert("Error", `Failed to connect: ${error.message}`);
    }
  };

  return (
    <View>
      <Button
        title={isConnecting ? "Connecting..." : "Connect Phantom"}
        onPress={handleConnect}
        disabled={isConnecting}
      />
      {error && (
        <Text style={{ color: "red", marginTop: 10 }}>
          Error: {error.message}
        </Text>
      )}
    </View>
  );
}

Authentication providers

The connect() method accepts a provider parameter to specify how users should authenticate. Available providers are configured in the PhantomProvider config:
import { PhantomProvider, AddressType } from "@phantom/react-native-sdk";

<PhantomProvider
  config={{
    providers: ["google", "apple"], // Specify enabled providers
    appId: "your-app-id",
    scheme: "myapp",
    addressTypes: [AddressType.solana],
  }}
>
  <App />
</PhantomProvider>
Then use the connect() method with one of the enabled providers:
const { connect } = useConnect();

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

Checking connection status

Use the useAccounts hook to check if a wallet is already connected:
import React from "react";
import { View, Text, Button } from "react-native";
import { useConnect, useAccounts } from "@phantom/react-native-sdk";

function WalletStatus() {
  const { connect } = useConnect();
  const { addresses, isConnected, walletId } = useAccounts();

  if (isConnected && addresses) {
    return (
      <View style={{ padding: 20 }}>
        <Text style={{ fontSize: 18, marginBottom: 10 }}>Connected to Phantom</Text>
        <Text>Wallet ID: {walletId}</Text>
        {addresses.map((account, index) => (
          <Text key={index} style={{ marginTop: 5 }}>
            {account.addressType}: {account.address}
          </Text>
        ))}
      </View>
    );
  }

  return (
    <View style={{ padding: 20 }}>
      <Button
        title="Connect Phantom"
        onPress={() => connect({ provider: "google" })}
      />
    </View>
  );
}

Handling connection errors

When a connection fails, the connect() promise rejects with an error.
import React from "react";
import { View, Button, Alert, Text } from "react-native";
import { useConnect } from "@phantom/react-native-sdk";

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

  const handleConnect = async () => {
    try {
      const result = await connect({ provider: "google" });
      // Connection successful
      Alert.alert("Success", "Wallet connected!");
      console.log("Connection successful:", result);
    } catch (error) {
      // Connection failed (user cancelled, network error, etc)
      Alert.alert("Error", `Failed to connect: ${error.message}`);
    }
  };

  return (
    <View>
      <Button
        title={isConnecting ? "Connecting..." : "Connect Phantom"}
        onPress={handleConnect}
        disabled={isConnecting}
      />
      {error && (
        <Text style={{ color: "red", marginTop: 10 }}>
          Error: {error.message}
        </Text>
      )}
    </View>
  );
}