Phantom Wallet Integration (Solana)

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Phantom Wallet Integration (Solana)
Simple
~2-3 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Phantom Wallet Integration (Solana)

Phantom is the de-facto standard wallet in Solana ecosystem. Its API is injected into window.solana and follows SolanaProvider interface from wallet-standard spec. Integration is straightforward, but there are several places to shoot yourself in the foot.

Connection and Provider Detection

First mistake — check window.solana immediately on page load. Extension injects asynchronously, on fast machines it happens before your JS executes, on slow ones it doesn't. Reliable pattern:

const getProvider = (): PhantomProvider | undefined => {
  if ('phantom' in window) {
    const provider = (window as any).phantom?.solana;
    if (provider?.isPhantom) return provider;
  }
  return undefined;
};

window.phantom.solana — preferable to window.solana because latter might be intercepted by other wallets (Backpack, Solflare). For supporting multiple wallets, use wallet-adapter from Solana Labs — @solana/wallet-adapter-react, which abstracts all providers via single interface.

Connection, Signing and Transactions

// Connection
const response = await provider.connect();
const publicKey = response.publicKey.toString();

// Message signing (for authentication)
const message = new TextEncoder().encode("Sign in to MyApp");
const { signature } = await provider.signMessage(message, "utf8");

// Send transaction
const transaction = new Transaction().add(/* instruction */);
transaction.feePayer = provider.publicKey;
transaction.recentBlockhash = (
  await connection.getLatestBlockhash()
).blockhash;
const { signature: txSig } = await provider.signAndSendTransaction(transaction);

Important moment: signAndSendTransaction sends transaction via Phantom's own RPC. If you want to control RPC endpoint (e.g., use Helius or QuickNode with priority fees), use signTransaction + connection.sendRawTransaction manually.

State and Event Handling

Phantom emits connect, disconnect and accountChanged events. Mandatory to subscribe to accountChanged — user might switch account inside wallet without reconnecting, and your app won't know without explicit listener.

provider.on('accountChanged', (publicKey: PublicKey | null) => {
  if (publicKey) {
    // Update app state
  } else {
    // Wallet locked — logout user
    provider.connect().catch(() => {});
  }
});

For React apps better to wrap this layer in @solana/wallet-adapter-react — it manages lifecycle, memoization and reconnect automatically.