Skip to main content
Complete guide to integrating Phantom Connect in a React Native app.

1. Install dependencies

npm install @phantom/react-native-sdk @solana/web3.js

# Required polyfill for cryptographic operations
npm install react-native-get-random-values

# Install peer dependencies
npx expo install expo-secure-store expo-web-browser expo-auth-session react-native-svg
If you’re using Expo, use npx expo install to ensure compatibility. For bare React Native projects, you can install the packages directly with npm.

2. Configure app scheme

Add your custom scheme to app.json:
{
  "expo": {
    "name": "My App",
    "slug": "my-app",
    "scheme": "myapp",
    "plugins": [
      "expo-router",
      "expo-secure-store",
      "expo-web-browser",
      "expo-auth-session"
    ]
  }
}
For bare React Native projects, configure deep linking in your native project files. See React Native deep linking documentation for details.

3. Create the app entry point

The polyfill must be the first import:
The react-native-get-random-values import must be the very first import in your app’s entry point, before any other imports.

With Expo Router

// app/_layout.tsx
import "react-native-get-random-values"; // Must be first!

import { Stack } from "expo-router";
import { PhantomProvider, AddressType, darkTheme } from "@phantom/react-native-sdk";

export default function Layout() {
  return (
    <PhantomProvider
      config={{
        providers: ["google", "apple"],
        appId: "your-app-id", // Get from phantom.com/portal
        scheme: "myapp",
        addressTypes: [AddressType.solana],
        authOptions: {
          redirectUrl: "myapp://phantom-auth-callback",
        },
      }}
      theme={darkTheme}
      appName="My App"
    >
      <Stack />
    </PhantomProvider>
  );
}

Without Expo Router

// App.tsx or index.js
import "react-native-get-random-values"; // Must be first!

import React from "react";
import { PhantomProvider, AddressType, darkTheme } from "@phantom/react-native-sdk";
import { WalletScreen } from "./WalletScreen";

export default function App() {
  return (
    <PhantomProvider
      config={{
        providers: ["google", "apple"],
        appId: "your-app-id", // Get from phantom.com/portal
        scheme: "myapp",
        addressTypes: [AddressType.solana],
        authOptions: {
          redirectUrl: "myapp://phantom-auth-callback",
        },
      }}
      theme={darkTheme}
      appName="My App"
    >
      <WalletScreen />
    </PhantomProvider>
  );
}

4. Create the wallet screen

// WalletScreen.tsx
import React from "react";
import { View, Text, Button, StyleSheet, Alert } from "react-native";
import {
  useModal,
  usePhantom,
  useAccounts,
  useDisconnect,
  useSolana,
} from "@phantom/react-native-sdk";

export function WalletScreen() {
  const { open } = useModal();
  const { isConnected } = usePhantom();
  const addresses = useAccounts();
  const { disconnect } = useDisconnect();
  const { solana } = useSolana();

  if (isConnected && addresses) {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Wallet Connected</Text>
        <Text style={styles.address}>{addresses[0]?.address}</Text>
        <Button
          title="Sign Message"
          onPress={async () => {
            try {
              const { signature } = await solana.signMessage("Hello!");
              Alert.alert("Success", `Signature: ${signature.slice(0, 10)}...`);
            } catch (error) {
              Alert.alert("Error", error instanceof Error ? error.message : "Failed to sign");
            }
          }}
        />
        <Button
          title="Disconnect"
          onPress={() => disconnect()}
        />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Welcome</Text>
      <Button title="Connect Wallet" onPress={open} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    padding: 20,
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
    fontWeight: "bold",
  },
  address: {
    fontSize: 14,
    marginBottom: 20,
    color: "#666",
  },
});

5. Configure Phantom Portal

  1. Go to phantom.com/portal
  2. Create or select your app
  3. Add your redirect URL (e.g., myapp://phantom-auth-callback) to redirect URLs
  4. Copy your App ID