@exe-pay/react-hooks

React hooks for seamless integration of ExePay features into your React applications. Built on top of Solana Wallet Adapter.

Installation

npm install @exe-pay/react-hooks @solana/wallet-adapter-react

Available Hooks

useWallet

Core wallet connection hook from Solana Wallet Adapter.

import { useWallet } from '@solana/wallet-adapter-react';

export function MyComponent() {
  const { 
    publicKey,           // User's wallet address
    connected,           // Connection status
    connecting,          // Loading state
    disconnect,          // Disconnect function
    signMessage,         // Sign arbitrary message
    signTransaction,     // Sign transaction
    sendTransaction      // Sign and send transaction
  } = useWallet();

  return (
    <div>
      {connected ? (
        <p>Connected: {publicKey?.toBase58()}</p>
      ) : (
        <button onClick={() => {}}>Connect Wallet</button>
      )}
    </div>
  );
}

useConnection

Access Solana RPC connection for blockchain queries.

import { useConnection } from '@solana/wallet-adapter-react';
import { LAMPORTS_PER_SOL } from '@solana/web3.js';

export function BalanceDisplay() {
  const { connection } = useConnection();
  const { publicKey } = useWallet();
  const [balance, setBalance] = useState(0);

  useEffect(() => {
    if (!publicKey) return;

    // Fetch balance
    connection.getBalance(publicKey).then(lamports => {
      setBalance(lamports / LAMPORTS_PER_SOL);
    });

    // Subscribe to balance changes
    const subscriptionId = connection.onAccountChange(
      publicKey,
      (accountInfo) => {
        setBalance(accountInfo.lamports / LAMPORTS_PER_SOL);
      }
    );

    return () => {
      connection.removeAccountChangeListener(subscriptionId);
    };
  }, [publicKey, connection]);

  return <p>Balance: {balance.toFixed(4)} SOL</p>;
}

Custom Hook: useStealthAddress

Hook for managing stealth addresses and private payments.

import { useState } from 'react';
import { useWallet } from '@solana/wallet-adapter-react';
import { generateStealthAddress, generateStealthMetaAddress } from '@exe-pay/privacy';

export function useStealthAddress() {
  const { publicKey, signMessage } = useWallet();
  const [metaAddress, setMetaAddress] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  const generateMeta = async () => {
    if (!publicKey || !signMessage) throw new Error('Wallet not connected');
    
    setLoading(true);
    try {
      const message = new TextEncoder().encode('Generate Stealth Meta-Address');
      const signature = await signMessage(message);
      
      const meta = await generateStealthMetaAddress(publicKey, signature);
      setMetaAddress(meta);
      return meta;
    } finally {
      setLoading(false);
    }
  };

  const generateStealth = async (recipientMeta: string) => {
    const { stealthAddress, ephemeralPubkey, viewTag } = 
      await generateStealthAddress(recipientMeta);
    return { stealthAddress, ephemeralPubkey, viewTag };
  };

  return { metaAddress, generateMeta, generateStealth, loading };
}

Custom Hook: useViewKeys

Hook for generating and managing view keys.

import { useState } from 'react';
import { useWallet } from '@solana/wallet-adapter-react';
import { generateViewKeys, encodeViewKeys } from '@exe-pay/privacy';

export function useViewKeys() {
  const { publicKey, signMessage } = useWallet();
  const [viewKeys, setViewKeys] = useState(null);
  const [loading, setLoading] = useState(false);

  const generate = async () => {
    if (!publicKey || !signMessage) throw new Error('Wallet not connected');
    
    setLoading(true);
    try {
      const message = new TextEncoder().encode(
        `Generate View Keys - ${Date.now()}`
      );
      const signature = await signMessage(message);
      
      const keys = await generateViewKeys(publicKey, signature);
      const encoded = encodeViewKeys(keys);
      setViewKeys(encoded);
      return encoded;
    } finally {
      setLoading(false);
    }
  };

  const exportKeys = () => {
    if (!viewKeys) return;
    
    const data = JSON.stringify(viewKeys, null, 2);
    const blob = new Blob([data], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = 'exepay-view-keys.json';
    a.click();
    
    URL.revokeObjectURL(url);
  };

  return { viewKeys, generate, exportKeys, loading };
}

Custom Hook: usePaymentScanner

Hook for scanning blockchain for stealth payments.

import { useState, useCallback } from 'react';
import { useWallet, useConnection } from '@solana/wallet-adapter-react';
import { scanForPayments } from '@exe-pay/privacy';

export function usePaymentScanner() {
  const { publicKey } = useWallet();
  const { connection } = useConnection();
  const [payments, setPayments] = useState([]);
  const [scanning, setScanning] = useState(false);

  const scan = useCallback(async () => {
    if (!publicKey) throw new Error('Wallet not connected');
    
    setScanning(true);
    try {
      const found = await scanForPayments(connection, publicKey, {
        limit: 100,
        useViewTags: true,
        onProgress: (count) => console.log(`Found ${count} payments`)
      });
      
      setPayments(found);
      return found;
    } finally {
      setScanning(false);
    }
  }, [publicKey, connection]);

  return { payments, scan, scanning };
}

Provider Setup

import { WalletProvider } from '@solana/wallet-adapter-react';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets';
import { ConnectionProvider } from '@solana/wallet-adapter-react';
import '@solana/wallet-adapter-react-ui/styles.css';

const wallets = [
  new PhantomWalletAdapter(),
  new SolflareWalletAdapter(),
];

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ConnectionProvider endpoint="https://api.mainnet-beta.solana.com">
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          {children}
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
}

Best Practices

  • Always check wallet connection before transactions
  • Handle loading states to improve user experience
  • Implement error boundaries for transaction failures
  • Use confirmation strategy appropriate for your use case
  • Cache RPC calls to reduce API usage
  • Implement retry logic for failed transactions

✅ Production Ready

All hooks are tested on Solana mainnet and ready for production use. Visit our examples page for complete implementations.