Skip to main content
MoonKey supports all Solana clusters including Mainnet Beta, Devnet, and Testnet. This guide shows you how to configure Solana RPC endpoints and work with different Solana environments in your application.

Solana Clusters

Solana provides three primary clusters for different purposes:
ClusterPurposeUse Case
Mainnet BetaProduction networkLive applications with real SOL and tokens
DevnetDevelopment networkTesting and development with free test SOL
TestnetPerformance testingStress testing before mainnet deployment

Configuring RPC Endpoints

To configure custom RPC endpoints for Solana embedded wallets, set them in the MoonKeyProvider configuration:
import { MoonKeyProvider } from '@moon-key/react-auth';

export default function Providers({ children }) {
  return (
    <MoonKeyProvider
      publishableKey="your-moonkey-publishableKey"
      config={{
        solana: {
          rpcs: {
            'solana:mainnet': {
              rpc: 'https://api.mainnet-beta.solana.com',
              rpcSubscriptions: 'wss://api.mainnet-beta.solana.com'
            },
            'solana:devnet': {
              rpc: 'https://api.devnet.solana.com',
              rpcSubscriptions: 'wss://api.devnet.solana.com'
            },
            'solana:testnet': {
              rpc: 'https://api.testnet.solana.com',
              rpcSubscriptions: 'wss://api.testnet.solana.com'
            }
          }
        }
      }}
    >
      {children}
    </MoonKeyProvider>
  );
}
Custom RPC configuration is only required for embedded wallet UIs. If you’re using external Solana wallets (Phantom, Solflare, etc.) without embedded wallet functionality, you don’t need to configure RPCs.

Default Configuration

If you don’t configure custom RPC endpoints, MoonKey uses default Solana cluster endpoints:
  • Mainnet Beta: https://api.mainnet-beta.solana.com
  • Devnet: https://api.devnet.solana.com
  • Testnet: https://api.testnet.solana.com
These default endpoints work for development and moderate usage, but production applications should use dedicated RPC providers.

Custom RPC Providers

For production applications, we strongly recommend using dedicated RPC providers to ensure reliability and performance.
ProviderFeaturesNotes
HeliusHigh-performance RPCs, webhooks, DAS APIRecommended for production
QuickNodeGlobal infrastructure, analyticsEnterprise features
AlchemyEnhanced APIs, developer toolsFull-featured platform
TritonGeyser plugin supportAdvanced use cases

Configuring a Custom Provider

Example using Helius:
import { MoonKeyProvider } from '@moon-key/react-auth';

const HELIUS_API_KEY = process.env.NEXT_PUBLIC_HELIUS_API_KEY;

export default function Providers({ children }) {
  return (
    <MoonKeyProvider
      publishableKey="your-moonkey-publishableKey"
      config={{
        solana: {
          rpcs: {
            'solana:mainnet': {
              rpc: `https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`,
              rpcSubscriptions: `wss://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`
            }
          }
        }
      }}
    >
      {children}
    </MoonKeyProvider>
  );
}

Custom SVM Networks

You can interact with custom SVM-compatible networks by creating a Connection instance with the custom RPC URL:
import { useSendTransaction } from '@moon-key/react-auth/solana';
import { Connection, Transaction } from '@solana/web3.js';

export default function CustomNetworkTransaction() {
  const { sendTransaction } = useSendTransaction();

  const handleTransaction = async () => {
    // Initialize connection with custom RPC
    const connection = new Connection('https://custom-rpc-url.com');

    const transaction = new Transaction().add(
      // Add your instructions here
    );

    const signature = await sendTransaction({
      transaction,
      connection
    });

    console.log('Transaction sent:', signature);
  };

  return <button onClick={handleTransaction}>Send Transaction</button>;
}

Environment-Based Configuration

Configure different RPC endpoints for different environments:
import { MoonKeyProvider } from '@moon-key/react-auth';

const isDevelopment = process.env.NODE_ENV === 'development';

const MAINNET_RPC = process.env.NEXT_PUBLIC_SOLANA_MAINNET_RPC;
const DEVNET_RPC = process.env.NEXT_PUBLIC_SOLANA_DEVNET_RPC;

export default function Providers({ children }) {
  return (
    <MoonKeyProvider
      publishableKey="your-moonkey-publishableKey"
      config={{
        solana: {
          rpcs: {
            'solana:mainnet': {
              rpc: MAINNET_RPC || 'https://api.mainnet-beta.solana.com',
              rpcSubscriptions: MAINNET_RPC?.replace('https', 'wss') || 
                'wss://api.mainnet-beta.solana.com'
            },
            'solana:devnet': {
              rpc: DEVNET_RPC || 'https://api.devnet.solana.com',
              rpcSubscriptions: DEVNET_RPC?.replace('https', 'wss') || 
                'wss://api.devnet.solana.com'
            }
          }
        }
      }}
    >
      {children}
    </MoonKeyProvider>
  );
}
Environment variables (.env.local):
NEXT_PUBLIC_SOLANA_MAINNET_RPC=https://mainnet.helius-rpc.com/?api-key=YOUR-KEY
NEXT_PUBLIC_SOLANA_DEVNET_RPC=https://devnet.helius-rpc.com/?api-key=YOUR-KEY

Working with Different Clusters

Switching Between Clusters

You can work with different clusters by creating separate Connection instances:
import { Connection } from '@solana/web3.js';

const mainnetConnection = new Connection('https://api.mainnet-beta.solana.com');
const devnetConnection = new Connection('https://api.devnet.solana.com');
const testnetConnection = new Connection('https://api.testnet.solana.com');

// Use the appropriate connection for your needs
const balance = await mainnetConnection.getBalance(publicKey);

Detecting Current Cluster

Determine which cluster a connection is using:
import { Connection, clusterApiUrl } from '@solana/web3.js';

function getClusterFromUrl(url: string): string {
  if (url.includes('mainnet')) return 'mainnet-beta';
  if (url.includes('devnet')) return 'devnet';
  if (url.includes('testnet')) return 'testnet';
  return 'custom';
}

const connection = new Connection('https://api.devnet.solana.com');
const cluster = getClusterFromUrl(connection.rpcEndpoint);
console.log('Current cluster:', cluster); // 'devnet'

Common Configurations

Development Setup (Devnet)

import { MoonKeyProvider } from '@moon-key/react-auth';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    solana: {
      rpcs: {
        'solana:devnet': {
          rpc: 'https://api.devnet.solana.com',
          rpcSubscriptions: 'wss://api.devnet.solana.com'
        }
      }
    }
  }}
>
  {children}
</MoonKeyProvider>

Production Setup (Mainnet with Helius)

import { MoonKeyProvider } from '@moon-key/react-auth';

const HELIUS_KEY = process.env.NEXT_PUBLIC_HELIUS_API_KEY;

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    solana: {
      rpcs: {
        'solana:mainnet': {
          rpc: `https://mainnet.helius-rpc.com/?api-key=${HELIUS_KEY}`,
          rpcSubscriptions: `wss://mainnet.helius-rpc.com/?api-key=${HELIUS_KEY}`
        }
      }
    }
  }}
>
  {children}
</MoonKeyProvider>

Multi-Cluster Support

import { MoonKeyProvider } from '@moon-key/react-auth';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    solana: {
      rpcs: {
        'solana:mainnet': {
          rpc: 'https://api.mainnet-beta.solana.com',
          rpcSubscriptions: 'wss://api.mainnet-beta.solana.com'
        },
        'solana:devnet': {
          rpc: 'https://api.devnet.solana.com',
          rpcSubscriptions: 'wss://api.devnet.solana.com'
        }
      }
    }
  }}
>
  {children}
</MoonKeyProvider>

Best Practices

Use Dedicated RPCs for Production

  • Default public RPCs have rate limits unsuitable for production
  • Dedicated providers offer better performance and reliability
  • Set up monitoring and alerts for RPC health
  • Have fallback RPCs configured

Secure Your API Keys

Store RPC API keys securely:
# .env.local (never commit to git)
NEXT_PUBLIC_HELIUS_API_KEY=your-api-key-here
NEXT_PUBLIC_QUICKNODE_ENDPOINT=your-endpoint-here
// Use environment variables
const apiKey = process.env.NEXT_PUBLIC_HELIUS_API_KEY;

Choose the Right Cluster

Use CaseClusterWhy
ProductionMainnet BetaReal transactions with real SOL
DevelopmentDevnetFree test SOL, stable for testing
Load TestingTestnetPerformance testing before mainnet
CI/CDDevnetAutomated testing with test tokens

Monitor RPC Performance

Track key metrics:
  • Request latency
  • Error rates
  • Rate limit usage
  • Websocket connection stability

Use Websockets for Real-Time Data

For real-time updates (account changes, transaction confirmations), use websocket connections:
import { Connection, PublicKey } from '@solana/web3.js';

// Create connection with websocket support
const connection = new Connection(
  'https://mainnet.helius-rpc.com/?api-key=YOUR-KEY',
  {
    wsEndpoint: 'wss://mainnet.helius-rpc.com/?api-key=YOUR-KEY'
  }
);

// Subscribe to account changes
const subscriptionId = connection.onAccountChange(
  publicKey,
  (accountInfo) => {
    console.log('Account updated:', accountInfo);
  }
);

Troubleshooting

RPC Connection Errors

Problem: Cannot connect to Solana RPC. Solutions:
  • Verify RPC URL is correct and accessible
  • Check API key is valid and not expired
  • Ensure rate limits haven’t been exceeded
  • Try fallback RPC endpoints

Transaction Timeouts

Problem: Transactions time out or fail to confirm. Solutions:
  • Use RPC providers with better uptime (Helius, QuickNode)
  • Increase transaction confirmation timeout
  • Implement retry logic with exponential backoff
  • Check Solana network status for congestion

Websocket Disconnections

Problem: Websocket connections drop frequently. Solutions:
  • Implement reconnection logic
  • Use dedicated RPC providers with stable websockets
  • Monitor connection health and reconnect proactively
  • Consider using polling for less time-sensitive data

Rate Limit Errors

Problem: Hitting RPC rate limits. Solutions:
  • Upgrade to paid RPC provider plan
  • Implement request batching
  • Cache responses when possible
  • Use websockets instead of polling

Testing on Different Networks

Getting Test SOL

For development and testing: Devnet:
solana airdrop 2 YOUR_WALLET_ADDRESS --url devnet
Or use the Solana Faucet Testnet:
solana airdrop 2 YOUR_WALLET_ADDRESS --url testnet

Network-Specific Testing

Test your application on different networks:
const networks = ['mainnet', 'devnet', 'testnet'];

networks.forEach(network => {
  test(`Transaction works on ${network}`, async () => {
    const connection = new Connection(getNetworkUrl(network));
    // Your test code here
  });
});