The Phantom Connect Browser SDK provides sdk.connect() to establish a connection to the wallet and access chain-specific operations.
Learn about Phantom Connect: For details about authentication flows, login, account selection, and session management, see the Phantom Connect guide.
Basic connection
Connection flow
After instantiating the SDK, use sdk.connect() to establish a connection to the wallet:
import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
// 1. Create SDK instance with allowed providers
const sdk = new BrowserSDK({
providers: ["google", "apple", "injected"], // Allowed auth providers
addressTypes: [AddressType.solana, AddressType.ethereum],
appId: "your-app-id", // Required when using embedded providers
});
// 2. Connect to wallet (provider parameter must be in allowed providers list)
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 requires a provider parameter and automatically switches between providers based on the authentication method you specify:
// Connect with injected provider (Phantom extension)
// Automatically switches to injected provider if not already using it
await sdk.connect({ provider: "injected" });
// Connect with Google authentication (embedded provider)
// Automatically switches to embedded provider if not already using it
await sdk.connect({ provider: "google" });
// Connect with Apple authentication (embedded provider)
await sdk.connect({ provider: "apple" });
The "deeplink" provider opens the Phantom mobile app on mobile devices. It only appears when the Phantom extension is not installed. Include it in your providers array for mobile support.
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({
providers: ["google", "apple", "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 the 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
SDK configuration
const sdk = new BrowserSDK({
// List of allowed authentication providers (REQUIRED)
providers: ["google", "apple", "injected", "deeplink"],
// Networks to enable
addressTypes: [AddressType.solana, AddressType.ethereum],
// Required when using embedded providers (google, apple, deeplink)
appId: "your-app-id",
// Optional configuration
authOptions: {
authUrl: "https://connect.phantom.app/login", // optional
redirectUrl: "https://yourapp.com/auth/callback", // optional, defaults to current page
},
// Auto-connect to existing session (default: true when embedded providers are used)
autoConnect: true,
});
Notes about redirectUrl (for embedded provider):
- Must be an existing page/route in your app.
- Must be allowlisted in your Phantom Portal app configuration.
- This is where users will be redirected after completing OAuth authentication.
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
EVM support for Phantom Connect embedded wallets will go live later in 2026.
// 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({
providers: ["google", "apple"],
addressTypes: [AddressType.solana],
appId: "your-app-id",
autoConnect: true, // Default: true when embedded providers are used, false for injected-only
});
// 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" });
}
Disabling auto-connect
const sdk = new BrowserSDK({
providers: ["google", "apple"],
appId: "your-app-id",
addressTypes: [AddressType.solana],
autoConnect: false, // Disable auto-connect
});
// Now you must manually call connect() every time
await sdk.connect({ provider: "google" });
Auto-connect events
You can listen for connection events to update your UI accordingly:
// Set up event listeners BEFORE autoConnect
sdk.on("connect", (data) => {
console.log("Connected successfully!");
console.log("Source:", data.source); // "auto-connect" | "manual-connect"
console.log("Provider type:", data.provider);
console.log("Addresses:", data.addresses);
// Update your UI state here
});
sdk.on("connect_error", (data) => {
console.log("Connection failed:", data.error);
console.log("Source:", data.source); // "auto-connect" | "manual-connect"
// Show connect button to user
});
// Auto-connect will trigger events
await sdk.autoConnect();
Handling connection errors
When a connection fails, the connect() promise rejects with an error.
try {
const { addresses } = await sdk.connect({ provider: "google" });
// Connection successful
console.log("Connected addresses:", addresses);
} catch (error) {
// Connection failed (user cancelled, network error, etc)
console.error("Connection failed:", error);
}