Skip to main content
The Swap Module provides a comprehensive token swapping solution that integrates multiple DEX providers into a unified interface for the Solana blockchain. It automatically finds the best routes and prices across different protocols to maximize trading efficiency.

Core Features

Multi-Provider Support

Integrated support for Jupiter aggregation, Raydium pools, and PumpSwap custom routing

Intelligent Routing

Automatic route optimization to find the best prices and lowest fees across all DEXs

Real-time Pricing

Live price updates, slippage calculations, and fee estimates for informed trading decisions

Advanced Controls

Customizable slippage, provider selection, and transaction parameters for power users

Installation & Setup

1

Import Module

Import the swap components and hooks:
import { 
  SwapScreen,
  useSwapLogic,
  TradeService,
  SelectTokenModal 
} from '@/modules/swap';
2

Wallet Integration

Ensure Embedded Wallets are configured:
import { useWallet } from '@/modules/wallet-providers';
3

DEX Configuration

Configure DEX provider settings (optional):
const swapConfig = {
  defaultProvider: 'jupiter',
  slippageTolerance: 0.5,
  enableCustomPools: true
};

Module Architecture

The swap module is built with a modular, provider-agnostic architecture:
src/modules/swap/
├── components/             # UI components
│   ├── SwapScreen.tsx     # Main swap interface
│   ├── SelectTokenModal.tsx
│   ├── SwapComponents/    # Specialized components
│   │   ├── Shimmer.tsx
│   │   ├── ProviderSelector.tsx
│   │   ├── PumpSwapControls.tsx
│   │   ├── SwapInfo.tsx
│   │   ├── StatusDisplay.tsx
│   │   └── Keypad.tsx
├── hooks/                 # Custom React hooks
│   └── useSwapLogic.ts
├── services/              # DEX integrations
│   ├── TradeService.ts
│   └── JupiterService.ts
└── index.ts              # Public API exports

DEX Providers

Primary DEX Aggregator - Best price discovery across all Solana DEXs
import { JupiterService } from '@/modules/swap';

// Get optimal swap quote
const quote = await JupiterService.getQuote({
  inputMint: 'So11111111111111111111111111111111111111112', // SOL
  outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
  amount: 1000000000, // 1 SOL in lamports
  slippageBps: 50 // 0.5% slippage
});

// Execute swap with Jupiter
const result = await JupiterService.executeSwap({
  quote,
  userPublicKey: wallet.publicKey,
  sendTransaction
});
Features:
  • Route optimization across 20+ DEXs
  • Price impact calculation
  • Multi-hop swaps
  • Minimal slippage
  • Best execution prices

Core Components

SwapScreen - Complete swap interface with all features
import { SwapScreen } from '@/modules/swap';

function TradingInterface() {
  return (
    <SwapScreen
      defaultInputToken="SOL"
      defaultOutputToken="USDC"
      theme="dark"
      showProviderSelector={true}
      enableCustomSlippage={true}
    />
  );
}
Features:
  • Token selection with search
  • Real-time price updates
  • Provider selection interface
  • Slippage controls
  • Transaction status tracking
  • Error handling and recovery

Core Hook: useSwapLogic

The primary hook for swap functionality:
import { useSwapLogic } from '@/modules/swap';
import { useWallet } from '@/modules/wallet-providers';

function CustomSwapImplementation() {
  const { publicKey, connected, sendTransaction } = useWallet();
  const routeParams = useRoute().params || {};
  
  const {
    // Token state
    inputToken,
    outputToken,
    setInputToken,
    setOutputToken,
    
    // Amount and pricing
    inputAmount,
    setInputAmount,
    outputAmount,
    exchangeRate,
    priceImpact,
    
    // Transaction state
    isLoading,
    transactionStatus,
    error,
    
    // Actions
    handleSwap,
    handleTokenSwitch,
    refreshPrices,
    
    // Provider state
    selectedProvider,
    setSelectedProvider,
    availableProviders,
    
    // Advanced options
    slippage,
    setSlippage,
    customPoolAddress,
    setCustomPoolAddress
  } = useSwapLogic(routeParams, publicKey, connected, sendTransaction);

  return (
    <View style={styles.container}>
      <TokenPairSelector 
        inputToken={inputToken}
        outputToken={outputToken}
        onInputTokenChange={setInputToken}
        onOutputTokenChange={setOutputToken}
        onSwitch={handleTokenSwitch}
      />
      
      <AmountInput
        value={inputAmount}
        onChange={setInputAmount}
        token={inputToken}
      />
      
      <SwapDetails
        outputAmount={outputAmount}
        exchangeRate={exchangeRate}
        priceImpact={priceImpact}
        provider={selectedProvider}
      />
      
      <SwapButton
        onPress={handleSwap}
        loading={isLoading}
        disabled={!connected || !inputAmount}
      />
    </View>
  );
}

TradeService Integration

Provider-agnostic service for executing swaps:
basic_swap_execution
object
advanced_swap_options
object
fee_calculation
object

Quick Start Examples

import { SwapScreen } from '@/modules/swap';
import { useWallet } from '@/modules/wallet-providers';

function BasicTradingApp() {
  const { connected } = useWallet();

  if (!connected) {
    return (
      <View style={styles.connectPrompt}>
        <Text style={styles.title}>Connect Wallet to Trade</Text>
        <ConnectWalletButton />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Token Swap</Text>
      <SwapScreen
        defaultInputToken="SOL"
        defaultOutputToken="USDC"
        showProviderSelector={true}
        enableCustomSlippage={true}
        theme="dark"
      />
    </View>
  );
}

Advanced Features

Real-time Price Monitoring

function useRealTimePricing(inputToken, outputToken, amount) {
  const [quote, setQuote] = useState(null);
  const [priceHistory, setPriceHistory] = useState([]);

  useEffect(() => {
    if (!inputToken || !outputToken || !amount) return;

    const fetchQuote = async () => {
      try {
        const newQuote = await TradeService.getQuote(inputToken, outputToken, amount);
        setQuote(newQuote);
        
        // Track price history
        setPriceHistory(prev => [
          ...prev.slice(-29), // Keep last 30 prices
          {
            timestamp: Date.now(),
            rate: newQuote.rate,
            priceImpact: newQuote.priceImpact
          }
        ]);
      } catch (error) {
        console.error('Quote fetch failed:', error);
      }
    };

    // Initial fetch
    fetchQuote();
    
    // Update every 10 seconds
    const interval = setInterval(fetchQuote, 10000);
    return () => clearInterval(interval);
  }, [inputToken, outputToken, amount]);

  return { quote, priceHistory };
}

Slippage Protection

function useSlippageProtection() {
  const [slippageSettings, setSlippageSettings] = useState({
    auto: true,
    custom: 0.5,
    maxImpact: 5.0
  });

  const calculateOptimalSlippage = (priceImpact, volatility) => {
    if (priceImpact < 0.1) return 0.1;
    if (priceImpact < 0.5) return 0.3;
    if (priceImpact < 1.0) return 0.5;
    if (priceImpact < 3.0) return 1.0;
    return Math.min(priceImpact * 1.5, 5.0);
  };

  const validateSlippage = (quote, slippage) => {
    if (quote.priceImpact > slippageSettings.maxImpact) {
      throw new Error(`Price impact (${quote.priceImpact}%) exceeds maximum allowed (${slippageSettings.maxImpact}%)`);
    }
    
    if (slippage < quote.priceImpact) {
      console.warn('Slippage tolerance may be too low for current market conditions');
    }
    
    return true;
  };

  return {
    slippageSettings,
    setSlippageSettings,
    calculateOptimalSlippage,
    validateSlippage
  };
}

Multi-Route Comparison

function useMultiRouteComparison(inputToken, outputToken, amount) {
  const [routes, setRoutes] = useState({});
  const [bestRoute, setBestRoute] = useState(null);

  useEffect(() => {
    if (!inputToken || !outputToken || !amount) return;

    const compareRoutes = async () => {
      try {
        const [jupiterQuote, raydiumQuote, pumpQuote] = await Promise.allSettled([
          TradeService.getQuote(inputToken, outputToken, amount, { provider: 'jupiter' }),
          TradeService.getQuote(inputToken, outputToken, amount, { provider: 'raydium' }),
          TradeService.getQuote(inputToken, outputToken, amount, { provider: 'pumpswap' })
        ]);

        const routeResults = {
          jupiter: jupiterQuote.status === 'fulfilled' ? jupiterQuote.value : null,
          raydium: raydiumQuote.status === 'fulfilled' ? raydiumQuote.value : null,
          pumpswap: pumpQuote.status === 'fulfilled' ? pumpQuote.value : null
        };

        setRoutes(routeResults);

        // Find best route by output amount
        const best = Object.entries(routeResults)
          .filter(([_, quote]) => quote !== null)
          .reduce((best, [provider, quote]) => 
            !best || quote.outputAmount > best.quote.outputAmount 
              ? { provider, quote } 
              : best
          , null);

        setBestRoute(best);
      } catch (error) {
        console.error('Route comparison failed:', error);
      }
    };

    compareRoutes();
  }, [inputToken, outputToken, amount]);

  return { routes, bestRoute };
}

Error Handling & Recovery

common_swap_errors
object
function RobustSwapExecution() {
  const executeSwapWithRetry = async (swapParams, maxRetries = 3) => {
    let lastError;
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        return await TradeService.executeSwap(...swapParams);
      } catch (error) {
        lastError = error;
        console.warn(`Swap attempt ${attempt} failed:`, error.message);
        
        if (attempt === maxRetries) break;
        
        // Handle specific errors
        if (error.message.includes('slippage')) {
          // Increase slippage and retry
          swapParams[5] = { 
            ...swapParams[5], 
            slippageBps: (swapParams[5]?.slippageBps || 50) * 1.5 
          };
        } else if (error.message.includes('network')) {
          // Wait before retry for network issues
          await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
      }
    }
    
    throw lastError;
  };

  return { executeSwapWithRetry };
}

Performance Optimization

Quote Caching: Implement intelligent quote caching to reduce API calls and improve response times.
Rate Limiting: Be mindful of DEX API rate limits when implementing real-time price updates.
function useOptimizedQuoting() {
  const [quoteCache, setQuoteCache] = useState(new Map());
  const [lastQuoteTime, setLastQuoteTime] = useState(0);
  
  const getCachedQuote = (inputToken, outputToken, amount) => {
    const key = `${inputToken}-${outputToken}-${amount}`;
    const cached = quoteCache.get(key);
    
    if (cached && Date.now() - cached.timestamp < 10000) { // 10 second cache
      return cached.quote;
    }
    
    return null;
  };
  
  const fetchQuoteWithCache = async (inputToken, outputToken, amount) => {
    // Check cache first
    const cached = getCachedQuote(inputToken, outputToken, amount);
    if (cached) return cached;
    
    // Rate limiting
    const now = Date.now();
    if (now - lastQuoteTime < 1000) { // 1 second minimum between requests
      await new Promise(resolve => setTimeout(resolve, 1000 - (now - lastQuoteTime)));
    }
    
    const quote = await TradeService.getQuote(inputToken, outputToken, amount);
    
    // Cache result
    const key = `${inputToken}-${outputToken}-${amount}`;
    setQuoteCache(prev => new Map(prev.set(key, {
      quote,
      timestamp: Date.now()
    })));
    
    setLastQuoteTime(Date.now());
    return quote;
  };
  
  return { fetchQuoteWithCache };
}

Integration with Other Modules

Embedded Wallets

Essential for transaction signing and balance checking

Data Module

Token metadata, prices, and portfolio integration

All DEX Modules

Works alongside Pump.fun, Raydium, and Meteora modules

AI Agent Kit

AI can execute swaps through natural language commands

API Reference

For detailed API documentation, see:
The Swap Module provides the foundation for all token trading activities in your Solana app, offering users the best possible prices through intelligent multi-DEX routing while maintaining a simple and intuitive interface.