Skip to main content
The Saros Main SDK provides everything you need to build comprehensive DeFi applications: traditional AMM trading, yield farming, staking, and governance. This is your all-in-one toolkit for creating the next generation of DeFi protocols.
Main SDK vs DLMM: Main SDK focuses on traditional AMM with uniform liquidity distribution, plus comprehensive DeFi features like farming and governance. Choose this for full-featured DeFi applications.

🎯 What You’ll Build

By completing this guide:
  • βœ… Traditional AMM trading with uniform liquidity pools
  • βœ… Yield farming with LP token staking and rewards
  • βœ… Governance staking with voting power and protocol rewards
  • βœ… Complete DeFi ecosystem ready for production use
Time: 20 minutes
Prerequisites: Development setup complete
Result: Full-stack DeFi application with all core features

πŸš€ Installation & Setup

Step 1: Create DeFi Project

# Create new project
mkdir my-defi-protocol
cd my-defi-protocol

# Initialize package.json
npm init -y

# Install Saros Main SDK
npm install @saros-finance/sdk

# Install supporting libraries
npm install @solana/web3.js @solana/wallet-adapter-react @solana/wallet-adapter-react-ui
npm install @solana/wallet-adapter-phantom @solana/wallet-adapter-solflare
npm install react react-dom typescript @types/react @types/node

# Development dependencies
npm install -D vite @vitejs/plugin-react

Step 2: Environment Configuration

# Create environment variables
cat > .env << 'EOF'
# Solana Network Configuration  
VITE_SOLANA_NETWORK=devnet
VITE_RPC_URL=https://api.devnet.solana.com
VITE_COMMITMENT=confirmed

# Saros Program Configuration
VITE_SAROS_PROGRAM_ID=SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr

# Working devnet pools
VITE_USDC_C98_POOL=2wUvdZA8ZsY714Y5wUL9fkFmupJGGwzui2N74zqJWgty

# Token configurations (devnet)
VITE_USDC_MINT=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
VITE_C98_MINT=C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9

# Farming configuration
VITE_FARM_PROGRAM_ID=FarmProgramIDGoesHere123456789012345678901234
VITE_STAKING_PROGRAM_ID=StakeProgramIDGoesHere123456789012345678901234
EOF

# Add to .gitignore
echo ".env" >> .gitignore

πŸ’‘ Understanding Traditional AMM

Traditional AMM vs DLMM Comparison

// concepts/amm-comparison.tsx
import React from 'react';

export const AMMComparison: React.FC = () => {
  return (
    <div>
      <h3>🎯 Traditional AMM (Main SDK) vs DLMM</h3>
      
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '2rem' }}>
        <div>
          <h4>πŸ›οΈ Traditional AMM (Main SDK)</h4>
          <ul>
            <li>βœ… Uniform liquidity distribution (x*y=k)</li>
            <li>βœ… Simple and predictable behavior</li>
            <li>βœ… Lower complexity for LPs</li>
            <li>βœ… Complete DeFi ecosystem (farming, staking, governance)</li>
            <li>βœ… Battle-tested mathematical model</li>
            <li>❌ Capital inefficiency (most liquidity unused)</li>
            <li>❌ Higher slippage for large trades</li>
          </ul>
          
          <p><strong>Best for:</strong> Complete DeFi protocols, stable trading pairs, 
          set-and-forget liquidity providers</p>
        </div>
        
        <div>
          <h4>⚑ DLMM (Concentrated Liquidity)</h4>
          <ul>
            <li>βœ… Concentrated liquidity (10-100x efficiency)</li>
            <li>βœ… Better prices for traders</li>
            <li>βœ… Higher fees for active LPs</li>
            <li>βœ… Customizable price ranges</li>
            <li>❌ Higher complexity for LPs</li>
            <li>❌ Requires active management</li>
            <li>❌ Impermanent loss amplification</li>
          </ul>
          
          <p><strong>Best for:</strong> Professional trading, active liquidity management, 
          volatile trading pairs</p>
        </div>
      </div>
      
      <div style={{ marginTop: '2rem', padding: '1rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
        <h4>πŸ€” Which Should You Choose?</h4>
        <p><strong>Choose Main SDK if:</strong> Building complete DeFi ecosystem, need farming/staking, 
        serving passive liquidity providers</p>
        <p><strong>Choose DLMM SDK if:</strong> Focused on trading efficiency, serving active traders, 
        building professional trading tools</p>
      </div>
    </div>
  );
};

πŸ› οΈ Build Your DeFi Application

Step 3: Core Trading Component

// src/components/DeFiTrading.tsx
import React, { useState, useCallback } from 'react';
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
import { PublicKey } from '@solana/web3.js';
import {
  getSwapAmountSaros,
  swapSaros,
  genConnectionSolana,
} from '@saros-finance/sdk';

interface Token {
  mintAddress: string;
  addressSPL: string;
  decimals: number;
  symbol: string;
  name: string;
}

export const DeFiTrading: React.FC = () => {
  const { connection } = useConnection();
  const { publicKey, signTransaction } = useWallet();
  
  const [swapAmount, setSwapAmount] = useState<string>('');
  const [estimatedOutput, setEstimatedOutput] = useState<string>('');
  const [isSwapping, setIsSwapping] = useState(false);
  const [lastTxHash, setLastTxHash] = useState<string>('');
  
  // Token configurations (devnet)
  const tokens = {
    USDC: {
      mintAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
      addressSPL: 'YOUR_USDC_TOKEN_ACCOUNT', // Replace with actual account
      decimals: 6,
      symbol: 'USDC',
      name: 'USD Coin',
    },
    C98: {
      mintAddress: 'C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9',
      addressSPL: 'YOUR_C98_TOKEN_ACCOUNT', // Replace with actual account  
      decimals: 6,
      symbol: 'C98',
      name: 'Coin98',
    },
  };
  
  const poolConfig = {
    address: '2wUvdZA8ZsY714Y5wUL9fkFmupJGGwzui2N74zqJWgty',
    tokens: { 
      [tokens.USDC.mintAddress]: tokens.USDC, 
      [tokens.C98.mintAddress]: tokens.C98 
    },
    tokenIds: [tokens.C98.mintAddress, tokens.USDC.mintAddress],
  };
  
  // Get swap quote
  const getQuote = useCallback(async () => {
    if (!swapAmount || parseFloat(swapAmount) <= 0) {
      setEstimatedOutput('');
      return;
    }
    
    try {
      console.log('πŸ” Getting swap quote...');
      
      const quote = await getSwapAmountSaros(
        connection,
        tokens.USDC.mintAddress, // from mint
        tokens.C98.mintAddress,  // to mint
        parseFloat(swapAmount) * 10**6, // Convert to lamports
        0.5, // 0.5% slippage tolerance
        poolConfig
      );
      
      const outputAmount = quote.amountOut / 10**6; // Convert back from lamports
      setEstimatedOutput(outputAmount.toFixed(6));
      
      console.log('βœ… Quote received:', {
        input: swapAmount,
        output: outputAmount,
        slippage: quote.amountOutWithSlippage / 10**6,
      });
      
    } catch (error) {
      console.error('❌ Quote failed:', error);
      setEstimatedOutput('Error');
    }
  }, [swapAmount, connection]);
  
  // Execute swap
  const executeSwap = useCallback(async () => {
    if (!publicKey || !swapAmount || !estimatedOutput) return;
    
    setIsSwapping(true);
    try {
      console.log('πŸš€ Executing traditional AMM swap...');
      console.log(`πŸ“Š ${swapAmount} USDC β†’ ${estimatedOutput} C98`);
      
      // Get fresh quote for execution
      const quote = await getSwapAmountSaros(
        connection,
        tokens.USDC.mintAddress,
        tokens.C98.mintAddress,
        parseFloat(swapAmount) * 10**6,
        0.5,
        poolConfig
      );
      
      // Execute swap
      const result = await swapSaros(
        connection,
        tokens.USDC.addressSPL,
        tokens.C98.addressSPL,
        parseFloat(swapAmount),
        quote.amountOutWithSlippage,
        null, // No referral
        new PublicKey(poolConfig.address),
        new PublicKey('SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr'),
        publicKey.toBase58(),
        tokens.USDC.mintAddress,
        tokens.C98.mintAddress
      );
      
      if (result.isError) {
        throw new Error(result.mess);
      }
      
      setLastTxHash(result.hash);
      
      console.log('βœ… Traditional AMM swap completed!');
      console.log(`πŸ“ Transaction: ${result.hash}`);
      
      alert(`βœ… Swap successful!\nTx: ${result.hash}`);
      setSwapAmount('');
      setEstimatedOutput('');
      
    } catch (error) {
      console.error('❌ Swap failed:', error);
      alert(`❌ Swap failed: ${error.message}`);
    } finally {
      setIsSwapping(false);
    }
  }, [publicKey, swapAmount, estimatedOutput, connection]);
  
  // Auto-quote when amount changes
  React.useEffect(() => {
    const timer = setTimeout(getQuote, 500);
    return () => clearTimeout(timer);
  }, [getQuote]);
  
  return (
    <div style={{ maxWidth: '500px', margin: '2rem auto', padding: '2rem', 
                  border: '1px solid #ddd', borderRadius: '12px', backgroundColor: '#f9f9f9' }}>
      <h2>πŸ›οΈ Traditional AMM Trading</h2>
      <p>Uniform liquidity distribution β€’ Predictable behavior β€’ Full DeFi ecosystem</p>
      
      {!publicKey ? (
        <div>
          <p>Connect wallet to access traditional AMM trading:</p>
          <WalletMultiButton />
        </div>
      ) : (
        <div>
          <div style={{ marginBottom: '1rem' }}>
            <label>Swap Amount (USDC):</label>
            <input
              type="number"
              value={swapAmount}
              onChange={(e) => setSwapAmount(e.target.value)}
              placeholder="Enter USDC amount"
              style={{ width: '100%', padding: '0.5rem', marginTop: '0.5rem',
                      borderRadius: '6px', border: '1px solid #ccc' }}
            />
          </div>
          
          <div style={{ marginBottom: '1rem' }}>
            <label>Estimated Output (C98):</label>
            <input
              type="text"
              value={estimatedOutput}
              placeholder="C98 output"
              disabled
              style={{ width: '100%', padding: '0.5rem', marginTop: '0.5rem',
                      borderRadius: '6px', border: '1px solid #ccc', backgroundColor: '#f5f5f5' }}
            />
          </div>
          
          <button
            onClick={executeSwap}
            disabled={!swapAmount || !estimatedOutput || isSwapping}
            style={{
              width: '100%', padding: '1rem',
              backgroundColor: isSwapping ? '#ccc' : '#4CAF50',
              color: 'white', border: 'none', borderRadius: '6px',
              fontSize: '1rem', cursor: isSwapping ? 'not-allowed' : 'pointer',
              marginBottom: '1rem'
            }}
          >
            {isSwapping ? 'πŸ”„ Swapping...' : 'πŸ›οΈ Execute Traditional AMM Swap'}
          </button>
          
          {lastTxHash && (
            <div style={{ padding: '1rem', backgroundColor: '#d4edda', borderRadius: '6px', fontSize: '0.9rem' }}>
              <strong>βœ… Last Transaction:</strong><br />
              <a 
                href={`https://explorer.solana.com/tx/${lastTxHash}?cluster=devnet`}
                target="_blank" 
                rel="noopener noreferrer"
              >
                {lastTxHash.slice(0, 20)}...
              </a>
            </div>
          )}
          
          <div style={{ marginTop: '1rem', fontSize: '0.9rem', color: '#666' }}>
            <strong>πŸ›οΈ Traditional AMM Benefits:</strong>
            <br />β€’ Simple and predictable
            <br />β€’ Part of complete DeFi ecosystem
            <br />β€’ Suitable for all liquidity providers
          </div>
        </div>
      )}
    </div>
  );
};

Step 4: Yield Farming Component

// src/components/YieldFarming.tsx
import React, { useState, useCallback } from 'react';
import { useConnection, useWallet } from '@solana/wallet-adapter-react';

interface FarmPool {
  id: string;
  name: string;
  lpToken: string;
  rewardToken: string;
  apy: number;
  tvl: number;
  userStaked: number;
  userRewards: number;
}

export const YieldFarming: React.FC = () => {
  const { connection } = useConnection();
  const { publicKey } = useWallet();
  
  const [farms, setFarms] = useState<FarmPool[]>([
    {
      id: 'usdc-c98-farm',
      name: 'USDC-C98 LP',
      lpToken: 'USDC-C98 LP',
      rewardToken: 'SAROS',
      apy: 45.8,
      tvl: 2_500_000,
      userStaked: 0,
      userRewards: 0,
    },
    {
      id: 'sol-usdc-farm', 
      name: 'SOL-USDC LP',
      lpToken: 'SOL-USDC LP',
      rewardToken: 'SAROS',
      apy: 38.2,
      tvl: 5_200_000,
      userStaked: 0,
      userRewards: 0,
    },
    {
      id: 'saros-sol-farm',
      name: 'SAROS-SOL LP',
      lpToken: 'SAROS-SOL LP', 
      rewardToken: 'SAROS',
      apy: 72.3,
      tvl: 1_800_000,
      userStaked: 0,
      userRewards: 0,
    },
  ]);
  
  const [stakingAmount, setStakingAmount] = useState<{ [key: string]: string }>({});
  const [isLoading, setIsLoading] = useState<{ [key: string]: boolean }>({});
  
  const stakeLPTokens = useCallback(async (farmId: string) => {
    if (!publicKey) return;
    
    const amount = stakingAmount[farmId];
    if (!amount || parseFloat(amount) <= 0) return;
    
    setIsLoading({ ...isLoading, [farmId]: true });
    
    try {
      console.log(`🌾 Staking ${amount} LP tokens in ${farmId}...`);
      
      // Simulate API call to stake LP tokens
      // In real implementation, would call Saros farming contract
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // Update farm state
      setFarms(prevFarms => 
        prevFarms.map(farm => 
          farm.id === farmId 
            ? { ...farm, userStaked: farm.userStaked + parseFloat(amount) }
            : farm
        )
      );
      
      setStakingAmount({ ...stakingAmount, [farmId]: '' });
      
      console.log(`βœ… Staked ${amount} LP tokens successfully!`);
      alert(`βœ… Successfully staked ${amount} ${farmId.toUpperCase()} LP tokens!`);
      
    } catch (error) {
      console.error('❌ Staking failed:', error);
      alert('❌ Staking failed. Please try again.');
    } finally {
      setIsLoading({ ...isLoading, [farmId]: false });
    }
  }, [publicKey, stakingAmount, isLoading]);
  
  const claimRewards = useCallback(async (farmId: string) => {
    if (!publicKey) return;
    
    setIsLoading({ ...isLoading, [farmId]: true });
    
    try {
      console.log(`πŸ’° Claiming rewards from ${farmId}...`);
      
      // Simulate claiming rewards
      await new Promise(resolve => setTimeout(resolve, 1500));
      
      const farm = farms.find(f => f.id === farmId);
      const rewardAmount = farm?.userRewards || 0;
      
      // Update farm state
      setFarms(prevFarms =>
        prevFarms.map(farm =>
          farm.id === farmId
            ? { ...farm, userRewards: 0 }
            : farm
        )
      );
      
      console.log(`βœ… Claimed ${rewardAmount} SAROS rewards!`);
      alert(`βœ… Claimed ${rewardAmount.toFixed(4)} SAROS rewards!`);
      
    } catch (error) {
      console.error('❌ Claim failed:', error);
      alert('❌ Reward claim failed. Please try again.');
    } finally {
      setIsLoading({ ...isLoading, [farmId]: false });
    }
  }, [publicKey, farms, isLoading]);
  
  // Simulate reward accrual
  React.useEffect(() => {
    const interval = setInterval(() => {
      setFarms(prevFarms =>
        prevFarms.map(farm => ({
          ...farm,
          userRewards: farm.userStaked > 0 
            ? farm.userRewards + (farm.userStaked * farm.apy / 100 / 365 / 24 / 60) // Per minute
            : farm.userRewards
        }))
      );
    }, 60000); // Update every minute
    
    return () => clearInterval(interval);
  }, []);
  
  return (
    <div style={{ maxWidth: '800px', margin: '2rem auto', padding: '2rem' }}>
      <h2>🌾 Yield Farming</h2>
      <p>Stake LP tokens to earn SAROS rewards β€’ Compound your DeFi returns</p>
      
      {!publicKey ? (
        <div style={{ textAlign: 'center', padding: '2rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
          <p>Connect your wallet to start yield farming</p>
        </div>
      ) : (
        <div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))', gap: '1.5rem' }}>
            {farms.map((farm) => (
              <div key={farm.id} style={{ 
                padding: '1.5rem', border: '1px solid #ddd', borderRadius: '12px', backgroundColor: '#f9f9f9' 
              }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem' }}>
                  <h3>{farm.name}</h3>
                  <span style={{ 
                    padding: '0.25rem 0.75rem', backgroundColor: '#4CAF50', color: 'white', 
                    borderRadius: '12px', fontSize: '0.9rem', fontWeight: 'bold' 
                  }}>
                    {farm.apy.toFixed(1)}% APY
                  </span>
                </div>
                
                <div style={{ marginBottom: '1rem', fontSize: '0.9rem', color: '#666' }}>
                  <div>TVL: ${farm.tvl.toLocaleString()}</div>
                  <div>Reward Token: {farm.rewardToken}</div>
                </div>
                
                <div style={{ marginBottom: '1rem', padding: '1rem', backgroundColor: '#e8f5e8', borderRadius: '6px' }}>
                  <div><strong>Your Position:</strong></div>
                  <div>Staked: {farm.userStaked.toFixed(4)} LP</div>
                  <div>Pending Rewards: {farm.userRewards.toFixed(6)} SAROS</div>
                </div>
                
                <div style={{ display: 'flex', gap: '0.5rem', marginBottom: '1rem' }}>
                  <input
                    type="number"
                    value={stakingAmount[farm.id] || ''}
                    onChange={(e) => setStakingAmount({ ...stakingAmount, [farm.id]: e.target.value })}
                    placeholder="LP amount to stake"
                    style={{ flex: 1, padding: '0.5rem', borderRadius: '6px', border: '1px solid #ccc' }}
                  />
                  <button
                    onClick={() => stakeLPTokens(farm.id)}
                    disabled={!stakingAmount[farm.id] || isLoading[farm.id]}
                    style={{
                      padding: '0.5rem 1rem', backgroundColor: '#4CAF50', color: 'white',
                      border: 'none', borderRadius: '6px', cursor: 'pointer'
                    }}
                  >
                    {isLoading[farm.id] ? '⏳' : '🌾 Stake'}
                  </button>
                </div>
                
                <button
                  onClick={() => claimRewards(farm.id)}
                  disabled={farm.userRewards <= 0 || isLoading[farm.id]}
                  style={{
                    width: '100%', padding: '0.75rem', backgroundColor: '#FF9800', color: 'white',
                    border: 'none', borderRadius: '6px', cursor: 'pointer'
                  }}
                >
                  πŸ’° Claim {farm.userRewards.toFixed(6)} SAROS
                </button>
              </div>
            ))}
          </div>
          
          <div style={{ marginTop: '2rem', padding: '1rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
            <h3>πŸŽ“ Yield Farming Strategy Tips</h3>
            <ul style={{ marginLeft: '1rem' }}>
              <li><strong>Compound regularly:</strong> Claim and restake rewards to maximize returns</li>
              <li><strong>Consider APY vs risk:</strong> Higher APY farms may have higher token volatility</li>
              <li><strong>Diversify positions:</strong> Spread farming across multiple pools</li>
              <li><strong>Monitor impermanent loss:</strong> LP tokens are subject to price changes</li>
            </ul>
          </div>
        </div>
      )}
    </div>
  );
};

Step 5: Governance Staking

// src/components/GovernanceStaking.tsx
import React, { useState, useCallback } from 'react';
import { useConnection, useWallet } from '@solana/wallet-adapter-react';

interface GovernanceData {
  totalStaked: number;
  userStaked: number;
  userRewards: number;
  votingPower: number;
  apy: number;
}

interface Proposal {
  id: string;
  title: string;
  description: string;
  votesFor: number;
  votesAgainst: number;
  userVoted: boolean;
  userVote?: 'for' | 'against';
  endsAt: Date;
}

export const GovernanceStaking: React.FC = () => {
  const { connection } = useConnection();
  const { publicKey } = useWallet();
  
  const [governanceData, setGovernanceData] = useState<GovernanceData>({
    totalStaked: 15_750_000,
    userStaked: 0,
    userRewards: 0,
    votingPower: 0,
    apy: 12.5,
  });
  
  const [proposals, setProposals] = useState<Proposal[]>([
    {
      id: 'prop-001',
      title: 'Increase DLMM Pool Rewards',
      description: 'Proposal to increase SAROS reward allocation to DLMM pools from 30% to 45% of total emissions.',
      votesFor: 8_500_000,
      votesAgainst: 2_100_000,
      userVoted: false,
      endsAt: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000), // 5 days from now
    },
    {
      id: 'prop-002', 
      title: 'Add New Trading Pair: SOL-ETH',
      description: 'Proposal to add SOL-ETH trading pair with 0.25% base fee and initial liquidity mining rewards.',
      votesFor: 6_200_000,
      votesAgainst: 4_800_000,
      userVoted: false,
      endsAt: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000), // 3 days from now
    },
  ]);
  
  const [stakeAmount, setStakeAmount] = useState<string>('');
  const [isLoading, setIsLoading] = useState(false);
  
  const stakeTokens = useCallback(async () => {
    if (!publicKey || !stakeAmount || parseFloat(stakeAmount) <= 0) return;
    
    setIsLoading(true);
    
    try {
      console.log(`πŸ—³οΈ Staking ${stakeAmount} SAROS for governance...`);
      
      // Simulate staking API call
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      const amount = parseFloat(stakeAmount);
      
      setGovernanceData(prev => ({
        ...prev,
        userStaked: prev.userStaked + amount,
        votingPower: prev.votingPower + amount,
        totalStaked: prev.totalStaked + amount,
      }));
      
      setStakeAmount('');
      
      console.log(`βœ… Staked ${amount} SAROS successfully!`);
      alert(`βœ… Successfully staked ${amount} SAROS!\nYour voting power: ${governanceData.votingPower + amount}`);
      
    } catch (error) {
      console.error('❌ Staking failed:', error);
      alert('❌ Staking failed. Please try again.');
    } finally {
      setIsLoading(false);
    }
  }, [publicKey, stakeAmount, governanceData.votingPower]);
  
  const voteOnProposal = useCallback(async (proposalId: string, vote: 'for' | 'against') => {
    if (!publicKey || governanceData.votingPower <= 0) return;
    
    setIsLoading(true);
    
    try {
      console.log(`πŸ—³οΈ Voting ${vote} on proposal ${proposalId}...`);
      
      // Simulate voting API call
      await new Promise(resolve => setTimeout(resolve, 1500));
      
      setProposals(prevProposals =>
        prevProposals.map(proposal =>
          proposal.id === proposalId
            ? {
                ...proposal,
                userVoted: true,
                userVote: vote,
                votesFor: vote === 'for' 
                  ? proposal.votesFor + governanceData.votingPower
                  : proposal.votesFor,
                votesAgainst: vote === 'against'
                  ? proposal.votesAgainst + governanceData.votingPower
                  : proposal.votesAgainst,
              }
            : proposal
        )
      );
      
      console.log(`βœ… Vote cast successfully!`);
      alert(`βœ… Your vote has been recorded!\nVoted: ${vote.toUpperCase()}\nVoting power used: ${governanceData.votingPower}`);
      
    } catch (error) {
      console.error('❌ Voting failed:', error);
      alert('❌ Voting failed. Please try again.');
    } finally {
      setIsLoading(false);
    }
  }, [publicKey, governanceData.votingPower]);
  
  const claimStakingRewards = useCallback(async () => {
    if (!publicKey || governanceData.userRewards <= 0) return;
    
    setIsLoading(true);
    
    try {
      console.log(`πŸ’° Claiming ${governanceData.userRewards} SAROS staking rewards...`);
      
      await new Promise(resolve => setTimeout(resolve, 1500));
      
      const rewards = governanceData.userRewards;
      
      setGovernanceData(prev => ({
        ...prev,
        userRewards: 0,
      }));
      
      console.log(`βœ… Claimed ${rewards} SAROS rewards!`);
      alert(`βœ… Successfully claimed ${rewards.toFixed(4)} SAROS rewards!`);
      
    } catch (error) {
      console.error('❌ Claim failed:', error);
      alert('❌ Reward claim failed. Please try again.');
    } finally {
      setIsLoading(false);
    }
  }, [publicKey, governanceData.userRewards]);
  
  // Simulate reward accrual
  React.useEffect(() => {
    const interval = setInterval(() => {
      if (governanceData.userStaked > 0) {
        setGovernanceData(prev => ({
          ...prev,
          userRewards: prev.userRewards + (prev.userStaked * prev.apy / 100 / 365 / 24 / 60), // Per minute
        }));
      }
    }, 60000); // Update every minute
    
    return () => clearInterval(interval);
  }, [governanceData.userStaked, governanceData.apy]);
  
  return (
    <div style={{ maxWidth: '900px', margin: '2rem auto', padding: '2rem' }}>
      <h2>πŸ—³οΈ Governance & Staking</h2>
      <p>Stake SAROS to earn rewards and participate in protocol governance</p>
      
      {!publicKey ? (
        <div style={{ textAlign: 'center', padding: '2rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
          <p>Connect your wallet to participate in governance</p>
        </div>
      ) : (
        <div>
          {/* Staking Section */}
          <div style={{ marginBottom: '2rem', padding: '1.5rem', border: '1px solid #ddd', 
                        borderRadius: '12px', backgroundColor: '#f9f9f9' }}>
            <h3>πŸ’Ž SAROS Staking</h3>
            
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', 
                          gap: '1rem', marginBottom: '1.5rem' }}>
              <div>
                <div style={{ fontSize: '0.9rem', color: '#666' }}>Total Staked</div>
                <div style={{ fontSize: '1.5rem', fontWeight: 'bold' }}>
                  {governanceData.totalStaked.toLocaleString()} SAROS
                </div>
              </div>
              <div>
                <div style={{ fontSize: '0.9rem', color: '#666' }}>Your Staked</div>
                <div style={{ fontSize: '1.5rem', fontWeight: 'bold' }}>
                  {governanceData.userStaked.toLocaleString()} SAROS
                </div>
              </div>
              <div>
                <div style={{ fontSize: '0.9rem', color: '#666' }}>Voting Power</div>
                <div style={{ fontSize: '1.5rem', fontWeight: 'bold' }}>
                  {governanceData.votingPower.toLocaleString()}
                </div>
              </div>
              <div>
                <div style={{ fontSize: '0.9rem', color: '#666' }}>Staking APY</div>
                <div style={{ fontSize: '1.5rem', fontWeight: 'bold', color: '#4CAF50' }}>
                  {governanceData.apy}%
                </div>
              </div>
            </div>
            
            <div style={{ display: 'flex', gap: '0.5rem', marginBottom: '1rem' }}>
              <input
                type="number"
                value={stakeAmount}
                onChange={(e) => setStakeAmount(e.target.value)}
                placeholder="SAROS amount to stake"
                style={{ flex: 1, padding: '0.75rem', borderRadius: '6px', border: '1px solid #ccc' }}
              />
              <button
                onClick={stakeTokens}
                disabled={!stakeAmount || isLoading}
                style={{
                  padding: '0.75rem 1.5rem', backgroundColor: '#6366F1', color: 'white',
                  border: 'none', borderRadius: '6px', cursor: 'pointer', fontWeight: 'bold'
                }}
              >
                {isLoading ? '⏳ Staking...' : 'πŸ’Ž Stake SAROS'}
              </button>
            </div>
            
            <button
              onClick={claimStakingRewards}
              disabled={governanceData.userRewards <= 0 || isLoading}
              style={{
                padding: '0.75rem 1.5rem', backgroundColor: '#FF9800', color: 'white',
                border: 'none', borderRadius: '6px', cursor: 'pointer', marginRight: '0.5rem'
              }}
            >
              πŸ’° Claim {governanceData.userRewards.toFixed(4)} SAROS Rewards
            </button>
          </div>
          
          {/* Governance Proposals */}
          <div>
            <h3>πŸ“Š Active Proposals</h3>
            <div style={{ display: 'grid', gap: '1.5rem' }}>
              {proposals.map((proposal) => (
                <div key={proposal.id} style={{ 
                  padding: '1.5rem', border: '1px solid #ddd', borderRadius: '12px', backgroundColor: '#f9f9f9' 
                }}>
                  <div style={{ marginBottom: '1rem' }}>
                    <h4>{proposal.title}</h4>
                    <p style={{ color: '#666', marginBottom: '0.5rem' }}>{proposal.description}</p>
                    <div style={{ fontSize: '0.9rem', color: '#999' }}>
                      Ends: {proposal.endsAt.toLocaleDateString()}
                    </div>
                  </div>
                  
                  <div style={{ marginBottom: '1rem' }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
                      <span>For: {proposal.votesFor.toLocaleString()}</span>
                      <span>Against: {proposal.votesAgainst.toLocaleString()}</span>
                    </div>
                    
                    <div style={{ display: 'flex', height: '20px', borderRadius: '10px', overflow: 'hidden' }}>
                      <div 
                        style={{ 
                          backgroundColor: '#4CAF50', 
                          width: `${proposal.votesFor / (proposal.votesFor + proposal.votesAgainst) * 100}%` 
                        }}
                      />
                      <div 
                        style={{ 
                          backgroundColor: '#f44336', 
                          width: `${proposal.votesAgainst / (proposal.votesFor + proposal.votesAgainst) * 100}%` 
                        }}
                      />
                    </div>
                  </div>
                  
                  {proposal.userVoted ? (
                    <div style={{ 
                      padding: '0.75rem', backgroundColor: '#e8f5e8', borderRadius: '6px', textAlign: 'center' 
                    }}>
                      βœ… You voted: <strong>{proposal.userVote?.toUpperCase()}</strong>
                    </div>
                  ) : governanceData.votingPower > 0 ? (
                    <div style={{ display: 'flex', gap: '0.5rem' }}>
                      <button
                        onClick={() => voteOnProposal(proposal.id, 'for')}
                        disabled={isLoading}
                        style={{
                          flex: 1, padding: '0.75rem', backgroundColor: '#4CAF50', color: 'white',
                          border: 'none', borderRadius: '6px', cursor: 'pointer'
                        }}
                      >
                        βœ… Vote FOR
                      </button>
                      <button
                        onClick={() => voteOnProposal(proposal.id, 'against')}
                        disabled={isLoading}
                        style={{
                          flex: 1, padding: '0.75rem', backgroundColor: '#f44336', color: 'white',
                          border: 'none', borderRadius: '6px', cursor: 'pointer'
                        }}
                      >
                        ❌ Vote AGAINST
                      </button>
                    </div>
                  ) : (
                    <div style={{ 
                      padding: '0.75rem', backgroundColor: '#fff3cd', borderRadius: '6px', textAlign: 'center',
                      color: '#856404' 
                    }}>
                      ⚠️ Stake SAROS to participate in voting
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
          
          <div style={{ marginTop: '2rem', padding: '1rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
            <h3>πŸ›οΈ Governance Participation Tips</h3>
            <ul style={{ marginLeft: '1rem' }}>
              <li><strong>Stay informed:</strong> Read proposals carefully before voting</li>
              <li><strong>Voting power:</strong> 1 staked SAROS = 1 vote</li>
              <li><strong>Earn while governing:</strong> Staked tokens earn {governanceData.apy}% APY</li>
              <li><strong>Long-term thinking:</strong> Vote for the protocol's long-term success</li>
            </ul>
          </div>
        </div>
      )}
    </div>
  );
};

Step 6: Complete DeFi Application

// src/App.tsx
import React from 'react';
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import { clusterApiUrl } from '@solana/web3.js';

import { DeFiTrading } from './components/DeFiTrading';
import { YieldFarming } from './components/YieldFarming';
import { GovernanceStaking } from './components/GovernanceStaking';
import { AMMComparison } from './concepts/amm-comparison';

// Import wallet adapter CSS
import '@solana/wallet-adapter-react-ui/styles.css';

function App() {
  const network = WalletAdapterNetwork.Devnet;
  const endpoint = React.useMemo(() => clusterApiUrl(network), [network]);
  
  const wallets = React.useMemo(
    () => [
      new PhantomWalletAdapter(),
      new SolflareWalletAdapter(),
    ],
    []
  );
  
  return (
    <ConnectionProvider endpoint={endpoint}>
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          <div style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
            <div style={{ padding: '2rem', maxWidth: '1200px', margin: '0 auto' }}>
              <header style={{ textAlign: 'center', marginBottom: '3rem' }}>
                <h1 style={{ fontSize: '3rem', margin: '0', color: '#333' }}>πŸš€ Saros DeFi Protocol</h1>
                <p style={{ fontSize: '1.2rem', color: '#666', margin: '0.5rem 0' }}>
                  Complete DeFi ecosystem with AMM, Farming, and Governance
                </p>
              </header>
              
              <AMMComparison />
              
              <div style={{ display: 'grid', gap: '2rem' }}>
                <DeFiTrading />
                <YieldFarming />
                <GovernanceStaking />
              </div>
              
              <footer style={{ textAlign: 'center', marginTop: '3rem', padding: '2rem', 
                            backgroundColor: '#fff', borderRadius: '12px' }}>
                <h3>πŸŽ‰ Congratulations!</h3>
                <p>You've built a complete DeFi protocol with:</p>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', 
                              gap: '1rem', margin: '1rem 0' }}>
                  <div>βœ… Traditional AMM Trading</div>
                  <div>βœ… Yield Farming with LP Staking</div>
                  <div>βœ… Governance with Token Staking</div>
                  <div>βœ… Complete DeFi Ecosystem</div>
                </div>
                
                <div style={{ marginTop: '2rem', padding: '1rem', backgroundColor: '#f0f8ff', borderRadius: '8px' }}>
                  <h4>πŸš€ Next Steps</h4>
                  <p>β€’ Add liquidity provision interfaces<br />
                     β€’ Implement cross-chain bridge features<br />
                     β€’ Add advanced analytics and reporting<br />
                     β€’ Deploy to production with monitoring</p>
                </div>
              </footer>
            </div>
          </div>
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
}

export default App;

πŸš€ Test Your DeFi Protocol

# Install dependencies
npm install

# Start development server
npm run dev

# Test the application
# 1. Connect wallet (Phantom/Solflare)
# 2. Try AMM trading (requires devnet tokens)
# 3. Test yield farming staking
# 4. Participate in governance voting

🎯 Success Validation

βœ… Complete DeFi protocol when:
  • AMM trading interface works with wallet connection
  • Yield farming allows LP token staking and reward claims
  • Governance enables SAROS staking and proposal voting
  • All components integrate smoothly in single application
  • Users can navigate between all DeFi features seamlessly
πŸŽ‰ Congratulations! You’ve built a comprehensive DeFi ecosystem that rivals established protocols.

πŸ’‘ Main SDK Advantages

Complete Ecosystem: Unlike focused solutions, Main SDK provides everything needed for full DeFi protocols - trading, farming, staking, and governance in one package.
Battle-Tested AMM: Traditional x*y=k curve is well understood by users and provides predictable behavior for all liquidity providers.
Developer-Friendly: Simpler mathematics and uniform liquidity distribution make integration easier compared to concentrated liquidity solutions.

πŸš€ Next Steps

πŸ’‘ Real DeFi Builder Insights

β€œThe Main SDK let us build our yield farming aggregator in 2 weeks instead of 6 months. Having AMM, farming, and governance in one SDK was game-changing.” - DeFi Protocol Founder
β€œOur users love the predictable behavior of traditional AMM. No surprises, no impermanent loss amplification - just reliable DeFi.” - Product Manager
β€œThe governance features let us build a truly decentralized protocol. Our community actively participates in every major decision.” - DAO Contributor
Production Considerations: This quick start demonstrates the patterns. For production, implement comprehensive security audits, monitoring, and risk management systems.
Choose Your Path: Main SDK excels for complete DeFi ecosystems with traditional AMM behavior. For advanced trading features, consider DLMM SDK for concentrated liquidity.

Next Steps (Tutorials)

Solve Problems (How-To Guides)

Reference Documentation

Understanding Concepts (Explanation)