> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hermis.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# React Quick Start

> Get started with Hermis in React applications

## Overview

This guide will walk you through integrating Hermis into a React application. You'll learn how to set up wallet connections, display wallet information, and perform basic Solana operations.

## Installation

Install the React package and its peer dependencies:

<CodeGroup>
  ```bash npm theme={null}
  npm install @hermis/solana-headless-react @solana/wallet-adapter-phantom @solana/wallet-adapter-solflare
  ```

  ```bash yarn theme={null}
  yarn add @hermis/solana-headless-react @solana/wallet-adapter-phantom @solana/wallet-adapter-solflare
  ```

  ```bash pnpm theme={null}
  pnpm add @hermis/solana-headless-react @solana/wallet-adapter-phantom @solana/wallet-adapter-solflare
  ```
</CodeGroup>

## Step 1: Set Up the Provider

Wrap your app with the `HermisProvider` to enable wallet functionality throughout your application:

```tsx App.tsx theme={null}
import React from 'react';
import { HermisProvider } from '@hermis/solana-headless-react';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import Home from './Home';

function App() {
  // Auto-detect wallet-standard compatible wallets
  const wallets = []; // Add custom wallet adapters here if needed

  return (
    <HermisProvider
      endpoint="https://api.devnet.solana.com"
      network={WalletAdapterNetwork.Devnet}
      autoConnect={true}
      wallets={wallets}
      onError={(error) => console.error('Wallet error:', error)}
    >
      <Home />
    </HermisProvider>
  );
}

export default App;
```

### Provider Options

<ParamField path="endpoint" type="string" required>
  The Solana RPC endpoint URL (e.g., `https://api.devnet.solana.com`)
</ParamField>

<ParamField path="network" type="WalletAdapterNetwork" required>
  The Solana network: `Mainnet`, `Devnet`, or `Testnet`
</ParamField>

<ParamField path="autoConnect" type="boolean" default="false">
  Automatically reconnect to the last used wallet on page load
</ParamField>

<ParamField path="wallets" type="Adapter[]">
  Array of wallet adapters to support
</ParamField>

<ParamField path="onError" type="(error: Error) => void">
  Callback function for handling wallet errors
</ParamField>

## Step 2: Create a Wallet Component

Use the `useWallet` hook to access wallet functionality:

```tsx Home.tsx theme={null}
import React from 'react';
import { useWallet, useSolanaBalance } from '@hermis/solana-headless-react';

function Home() {
  const {
    wallet,
    publicKey,
    connecting,
    connected,
    connect,
    disconnect,
    select
  } = useWallet();

  const { balance, loading } = useSolanaBalance(publicKey);

  const handleConnect = async () => {
    if (wallet) {
      await connect();
    } else {
      // Select a wallet first if none is selected
      select('Phantom');
      await connect();
    }
  };

  return (
    <div className="container">
      <h1>Solana Wallet Demo</h1>

      {!connected ? (
        <div>
          <button
            onClick={handleConnect}
            disabled={connecting}
            className="connect-button"
          >
            {connecting ? 'Connecting...' : 'Connect Wallet'}
          </button>
        </div>
      ) : (
        <div className="wallet-info">
          <p><strong>Wallet:</strong> {wallet?.adapter.name}</p>
          <p><strong>Address:</strong> {publicKey?.toBase58()}</p>
          <p><strong>Balance:</strong> {loading ? 'Loading...' : `${balance} SOL`}</p>
          <button onClick={disconnect} className="disconnect-button">
            Disconnect
          </button>
        </div>
      )}
    </div>
  );
}

export default Home;
```

## Step 3: Send a Transaction

Add transaction functionality using the `sendTransaction` method:

<CodeGroup>
  ```tsx Legacy (Web3.js) theme={null}
  import React, { useState } from 'react';
  import { useWallet, useConnection } from '@hermis/solana-headless-react';
  import { Transaction, SystemProgram, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js';

  function SendTransaction() {
    const { publicKey, sendTransaction } = useWallet();
    const { connection } = useConnection();
    const [recipient, setRecipient] = useState('');
    const [amount, setAmount] = useState('0.1');
    const [sending, setSending] = useState(false);
    const [signature, setSignature] = useState('');

    const handleSend = async () => {
      if (!publicKey || !recipient) return;

      setSending(true);
      setSignature('');

      try {
        const transaction = new Transaction();
        const recipientPubKey = new PublicKey(recipient);

        transaction.add(
          SystemProgram.transfer({
            fromPubkey: publicKey,
            toPubkey: recipientPubKey,
            lamports: parseFloat(amount) * LAMPORTS_PER_SOL
          })
        );

        // Get recent blockhash
        const { blockhash } = await connection.getLatestBlockhash();
        transaction.recentBlockhash = blockhash;
        transaction.feePayer = publicKey;

        // Send transaction
        const sig = await sendTransaction(transaction, connection);
        setSignature(sig);
        console.log('Transaction sent:', sig);
      } catch (error) {
        console.error('Error sending transaction:', error);
        alert('Failed to send transaction');
      } finally {
        setSending(false);
      }
    };

    return (
      <div className="send-transaction">
        <h2>Send SOL</h2>
        <div className="form">
          <input
            type="text"
            placeholder="Recipient address"
            value={recipient}
            onChange={(e) => setRecipient(e.target.value)}
            className="input"
          />
          <input
            type="number"
            placeholder="Amount (SOL)"
            value={amount}
            onChange={(e) => setAmount(e.target.value)}
            step="0.01"
            min="0"
            className="input"
          />
          <button
            onClick={handleSend}
            disabled={!publicKey || !recipient || sending}
            className="send-button"
          >
            {sending ? 'Sending...' : 'Send SOL'}
          </button>
        </div>
        {signature && (
          <div className="success">
            <p>Transaction successful!</p>
            <a
              href={`https://explorer.solana.com/tx/${signature}?cluster=devnet`}
              target="_blank"
              rel="noopener noreferrer"
            >
              View on Explorer
            </a>
          </div>
        )}
      </div>
    );
  }

  export default SendTransaction;
  ```

  ```tsx Kit theme={null}
  import React, { useState } from 'react';
  import { useWallet } from '@hermis/solana-headless-react';
  import {
    address,
    appendTransactionMessageInstruction,
    createSolanaRpc,
    createTransactionMessage,
    devnet,
    lamports,
    pipe,
    setTransactionMessageFeePayerSigner,
    setTransactionMessageLifetimeUsingBlockhash,
    type TransactionSigner
  } from '@solana/kit';

  // System Program Address
  const SYSTEM_PROGRAM_ADDRESS = address('11111111111111111111111111111111');

  // Create a transfer SOL instruction using Kit
  function getTransferSolInstruction({
    source,
    destination,
    amount,
  }: {
    source: TransactionSigner<string>
    destination: address<string>
    amount: ReturnType<typeof lamports>
  }) {
    const instructionData = new Uint8Array(12);
    const view = new DataView(instructionData.buffer);
    view.setUint32(0, 2, true); // instruction discriminator: 2 = Transfer
    view.setBigUint64(4, BigInt(amount), true); // amount in lamports

    return {
      programAddress: SYSTEM_PROGRAM_ADDRESS,
      accounts: [
        { address: source.address, role: 3 }, // from account (writable + signer)
        { address: destination, role: 1 },     // to account (writable)
      ],
      data: instructionData,
    };
  }

  function SendTransaction() {
    const { transactionSigner, signAndSendTransaction } = useWallet();
    const [recipient, setRecipient] = useState('');
    const [amount, setAmount] = useState('0.1');
    const [sending, setSending] = useState(false);
    const [signature, setSignature] = useState('');

    // Create Kit RPC (can be created once and reused, or stored in a context)
    const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));

    const handleSend = async () => {
      if (!transactionSigner || !recipient) return;

      setSending(true);
      setSignature('');

      try {
        const recipientAddr = address(recipient.trim());

        // Convert SOL to lamports
        const numDecimals = BigInt(amount.split('.')[1]?.length ?? 0);
        const amountLamports = lamports(
          BigInt(amount.replace('.', '')) * 10n ** (9n - numDecimals)
        );

        // Get latest blockhash from Kit RPC
        const { value: latestBlockhash } = await rpc
          .getLatestBlockhash({ commitment: 'confirmed' })
          .send();

        // Build transaction using Kit's pattern
        const message = pipe(
          createTransactionMessage({ version: 0 }),
          m => setTransactionMessageFeePayerSigner(transactionSigner, m),
          m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
          m => appendTransactionMessageInstruction(
            getTransferSolInstruction({
              amount: amountLamports,
              destination: recipientAddr,
              source: transactionSigner,
            }),
            m,
          ),
        );

        // Pass Kit RPC as the connection parameter
        const sig = await signAndSendTransaction(message, rpc);
        setSignature(sig);
        console.log('Transaction sent:', sig);
      } catch (error) {
        console.error('Error sending transaction:', error);
        alert('Failed to send transaction');
      } finally {
        setSending(false);
      }
    };

    return (
      <div className="send-transaction">
        <h2>Send SOL</h2>
        <div className="form">
          <input
            type="text"
            placeholder="Recipient address"
            value={recipient}
            onChange={(e) => setRecipient(e.target.value)}
            className="input"
          />
          <input
            type="number"
            placeholder="Amount (SOL)"
            value={amount}
            onChange={(e) => setAmount(e.target.value)}
            step="0.01"
            min="0"
            className="input"
          />
          <button
            onClick={handleSend}
            disabled={!transactionSigner || !recipient || sending}
            className="send-button"
          >
            {sending ? 'Sending...' : 'Send SOL'}
          </button>
        </div>
        {signature && (
          <div className="success">
            <p>Transaction successful!</p>
            <a
              href={`https://explorer.solana.com/tx/${signature}?cluster=devnet`}
              target="_blank"
              rel="noopener noreferrer"
            >
              View on Explorer
            </a>
          </div>
        )}
      </div>
    );
  }

  export default SendTransaction;
  ```
</CodeGroup>

## Available Hooks

### useWallet

Primary hook for wallet interactions:

```tsx theme={null}
const {
  // Wallet state
  autoConnect,           // Whether auto-connect is enabled
  wallets,               // Array of all available wallets
  wallet,                // Currently selected wallet
  publicKey,             // Public key of connected wallet (web3.js)
  connecting,            // Connection status
  connected,             // Whether wallet is connected
  disconnecting,         // Disconnection status

  // Kit-specific properties
  address,               // Kit Address type (null if not connected)
  addressString,         // Plain address string (null if not connected)
  chain,                 // Solana chain identifier (e.g., 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1')
  messageSigner,         // Message signer for Kit architecture (null if not available)
  transactionSigner,     // Transaction sending signer for Kit (null if not available)
  getChainId,            // Function to get chain ID: (network: 'devnet' | 'mainnet' | 'testnet') => `solana:${string}`

  // Methods
  select,                // Select a wallet by name
  connect,               // Connect to selected wallet
  disconnect,            // Disconnect wallet

  // Transaction methods (support both web3.js and Kit)
  sendTransaction,       // Send a transaction (dual architecture support)
  signTransaction,       // Sign a transaction (dual architecture support)
  signAllTransactions,   // Sign multiple transactions (dual architecture support)
  signAndSendTransaction, // Sign and send transaction (dual architecture support)

  // Message signing
  signMessage,           // Sign a message
  signIn,                // Sign in with wallet

  // Utilities
  hasFeature,            // Check if wallet supports a feature: (feature: 'signMessage' | 'signTransaction' | 'signAllTransactions' | 'signIn') => boolean
} = useWallet();
```

### useConnection

Access the Solana connection:

```tsx theme={null}
const {
  connection,  // DualConnection - supports both web3.js Connection and Kit Rpc
  network      // WalletAdapterNetwork (optional)
} = useConnection();

// Works with both architectures
const accountInfo = await connection.getAccountInfo(publicKey);

// For Kit RPC, use the .send() pattern
const { value } = await connection.getLatestBlockhash().send();
```

### useSolanaBalance

Fetch and track wallet balance:

```tsx theme={null}
const {
  balance,         // Balance in SOL
  balanceLamports, // Balance in lamports
  loading,         // Loading state
  error,           // Error if occurred
  refetch          // Manually refetch balance
} = useSolanaBalance(publicKey, 10000); // 10 second refresh
```

### useSolanaTokenAccounts

Fetch SPL token accounts:

```tsx theme={null}
const {
  tokenAccounts, // Array of token accounts
  loading,       // Loading state
  error,         // Error if occurred
  refetch        // Manually refetch
} = useSolanaTokenAccounts(publicKey);
```

### useSolanaNFTs

Fetch NFTs owned by a wallet:

```tsx theme={null}
const {
  nfts,    // Array of NFTs
  loading, // Loading state
  error,   // Error if occurred
  refetch  // Manually refetch
} = useSolanaNFTs(publicKey);
```

### useSolanaTransaction

Track transaction status with confirmations:

```tsx theme={null}
const {
  status,  // TransactionStatus object
  loading, // Loading state
  refetch  // Manually refetch status
} = useSolanaTransaction(signature, autoFetch);

// TransactionStatus includes:
// - signature: string
// - status: 'pending' | 'confirmed' | 'finalized' | 'failed'
// - confirmations: number
// - confirmationStatus: SignatureStatus['confirmationStatus']
// - error?: string
// - transactionDetails?: VersionedTransactionResponse
```

### useWalletAdapters

Get grouped and sorted wallet adapters:

```tsx theme={null}
const {
  installed,    // Installed wallet adapters
  loadable,     // Loadable wallet adapters
  notDetected,  // Not detected wallet adapters
  all           // All wallet adapters (sorted)
} = useWalletAdapters();
```

### useAnchorWallet

Get an Anchor-compatible wallet with dual architecture support:

```tsx theme={null}
const anchorWallet = useAnchorWallet();
// Returns AnchorWallet | undefined

// Primary use: Pass to Anchor programs (uses web3.js internally)
const program = new Program(idl, programId, { connection, wallet: anchorWallet });
await program.methods.myMethod().accounts({...}).rpc();

// Advanced use: Manual signing with web3.js
const signedTx = await anchorWallet.signTransaction(web3Transaction);

// Advanced use: Manual signing with Kit (also supported)
const signedKitTx = await anchorWallet.signTransaction(kitTransactionMessage);
```

### useWalletModal

Manage wallet selection modal state:

```tsx theme={null}
const {
  visible,           // Whether modal is visible
  showModal,         // Show the modal
  hideModal,         // Hide the modal
  selectedWallet,    // Currently selected wallet name
  setSelectedWallet  // Set selected wallet
} = useWalletModal();
```

## Next.js Integration

For Next.js 13+ with App Router, create a client-side provider:

```tsx app/providers.tsx theme={null}
'use client';

import { HermisProvider } from '@hermis/solana-headless-react';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';

export function Providers({ children }: { children: React.ReactNode }) {
  // Auto-detect wallet-standard compatible wallets
  const wallets = []; // Add custom wallet adapters here if needed

  return (
    <HermisProvider
      endpoint="https://api.devnet.solana.com"
      network={WalletAdapterNetwork.Devnet}
      autoConnect={true}
      wallets={wallets}
    >
      {children}
    </HermisProvider>
  );
}
```

Then use in your layout:

```tsx app/layout.tsx theme={null}
import { Providers } from './providers';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Handle Connection States">
    Always check `connecting`, `connected`, and `disconnecting` states to provide appropriate UI feedback to users.
  </Accordion>

  <Accordion title="Error Handling">
    Implement proper error handling for all wallet operations, especially during transactions. Use the `onError` callback in the provider.
  </Accordion>

  <Accordion title="Mobile Wallet Adapter Performance">
    For best performance with Solana Mobile Wallet Adapter, disable battery/power saving mode on your device. Power saving modes can interfere with wallet adapter connections, transaction signing, and deeplinking to wallet applications.

    Disabling power saving mode ensures:

    * Reliable wallet adapter connections
    * Smooth deeplinking between your dApp and wallet apps
    * Faster transaction signing responses

    **Tip:** Instruct users to disable power saving mode before connecting their mobile wallet for optimal experience.
  </Accordion>

  <Accordion title="Network Selection">
    Ensure your RPC endpoint matches the intended network. Don't mix mainnet and devnet operations.
  </Accordion>
</AccordionGroup>

## What's Next?

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/api-reference/react/overview">
    Explore the complete React API documentation
  </Card>

  <Card title="Cookbook" icon="book-open" href="/cookbook/connect-wallet">
    Learn practical patterns and examples
  </Card>

  <Card title="Send Transactions" icon="paper-plane" href="/cookbook/send-transaction">
    Learn how to send SOL and tokens
  </Card>

  <Card title="Sign Messages" icon="signature" href="/cookbook/sign-message">
    Implement message signing
  </Card>
</CardGroup>
