Skip to main content

Connecting to Phantom Wallets

After instantiating the SDK, use sdk.connect() to establish a connection to the wallet and access 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.

Basic Connection

User Wallet Connection

import { BrowserSDK, AddressType } from "@phantom/browser-sdk";

// 1. Create SDK instance
const sdk = new BrowserSDK({
  providerType: "embedded", // or "injected" for browser extension
  addressTypes: [AddressType.solana, AddressType.ethereum],
  appId: "your-app-id",
});

// 2. Connect to wallet with OAuth provider
const { addresses } = await sdk.connect({ provider: "google" });
console.log("Connected addresses:", addresses);

// 3. Use chain-specific methods
const signature = await sdk.solana.signMessage("Hello!");
const ethResult = await sdk.ethereum.sendTransaction({
  to: "0x...",
  value: "1000000000000000000",
  gas: "21000",
});

Authentication Providers

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

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

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

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

Connecting with Phantom Extension (Embedded Wallet)

The "phantom" provider option allows users to authenticate an embedded wallet using their existing Phantom browser extension. Before using this option, check if Phantom login is available:
import { BrowserSDK, AddressType } from "@phantom/browser-sdk";

const sdk = new BrowserSDK({
  providerType: "embedded",
  addressTypes: [AddressType.solana, AddressType.ethereum],
  appId: "your-app-id",
});

// Check if Phantom extension login is available
const isAvailable = await sdk.isPhantomLoginAvailable();

if (isAvailable) {
  // User has Phantom extension installed and can use extension login
  await sdk.connect({ provider: "phantom" });
} else {
  // Fallback to OAuth providers
  await sdk.connect({ provider: "google" });
}
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

Connecting to Injected Extension

The "injected" provider directly connects to the user’s Phantom browser extension (not an embedded wallet). Before using this option, check if the extension is installed:
import { BrowserSDK, AddressType } from "@phantom/browser-sdk";

const sdk = new BrowserSDK({
  providerType: "embedded", // Start with embedded, but can connect to injected
  addressTypes: [AddressType.solana, AddressType.ethereum],
  appId: "your-app-id",
});

// Check if Phantom extension is installed
const isInstalled = await sdk.isPhantomInstalled();

if (isInstalled) {
  // Connect directly to the extension wallet
  await sdk.connect({ provider: "injected" });
} else {
  // Fallback to embedded wallet with OAuth
  await sdk.connect({ provider: "google" });
}
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

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
const sdk = new BrowserSDK({
  providerType: "embedded",
  addressTypes: [AddressType.solana, AddressType.ethereum],
  appId: "your-app-id",
  authOptions: {
    redirectUrl: "https://yourapp.com/auth/callback",
  },
});

Chain-Specific Operations

After connection, use dedicated chain interfaces:

Solana Operations

// Message signing
const signature = await sdk.solana.signMessage("Hello Solana!");

// Transaction signing (without sending)
const signedTx = await sdk.solana.signTransaction(transaction);

// Sign and send transaction
const result = await sdk.solana.signAndSendTransaction(transaction);

// Network switching (works on embedded for solana)
await sdk.solana.switchNetwork('devnet');

// Utilities
const publicKey = await sdk.solana.getPublicKey();
const isConnected = sdk.solana.isConnected();

Ethereum Operations

// EIP-1193 requests
const accounts = await sdk.ethereum.request({ method: 'eth_accounts' });
const chainId = await sdk.ethereum.request({ method: 'eth_chainId' });

// Message signing
const signature = await sdk.ethereum.signPersonalMessage(message, address);

// EIP-712 typed data signing
const typedDataSignature = await sdk.ethereum.signTypedData(typedData, address);

// Transaction sending
const result = await sdk.ethereum.sendTransaction({
  to: "0x...",
  value: "1000000000000000000", // 1 ETH in wei
  gas: "21000",
});

// Network switching
await sdk.ethereum.switchChain(1); // Ethereum mainnet
await sdk.ethereum.switchChain(137); // Polygon

// Utilities
const chainId = await sdk.ethereum.getChainId();
const accounts = await sdk.ethereum.getAccounts();
const isConnected = sdk.ethereum.isConnected();

Auto-Connect Feature

The SDK can automatically reconnect to existing sessions when instantiated, providing a seamless user experience.
const sdk = new BrowserSDK({
  providerType: "embedded",
  addressTypes: [AddressType.solana],
  appId: "your-app-id",
  autoConnect: true, // Default: true
});

// SDK will automatically check for existing valid session and connect in background
// No need to call connect() if user already has a session

// Check if already connected
if (sdk.isConnected()) {
  console.log("Already connected!");
  const addresses = await sdk.getAddresses();
} else {
  // First time or session expired, need to connect manually
  await sdk.connect({ provider: "google" });
}