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
Prerequisites: Development setup complete
Result: Full-stack DeFi application with all core features
π Installation & Setup
Step 1: Create DeFi Project
Copy
# 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
Copy
# 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
Copy
// 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
Copy
// 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
Copy
// 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
Copy
// 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
Copy
// 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
Copy
# 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
π‘ 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
Advanced DeFi Features
Cross-chain integration, advanced routing, and institutional features
Liquidity Provision
Complete guide to providing and managing AMM liquidity
DeFi Protocol Development
Build your own DeFi protocols on top of Saros infrastructure
Production Deployment
Security, monitoring, and scaling for production DeFi applications
π‘ 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.
Navigation
Next Steps (Tutorials)
- First DeFi App β - Build complete DeFi protocol
- DeFi Protocols Tutorial β - AMM, farming, and governance
- Advanced Features β - Complex DeFi functionality
Solve Problems (How-To Guides)
- Swaps β - Traditional AMM swap implementation
- Liquidity Management β - AMM liquidity operations
- Yield Farming β - Farming pool integration
- Governance & Staking β - DAO participation
Reference Documentation
- Main SDK Methods β - Complete API method reference
- Main SDK Types β - Complete type definitions
- Main SDK API Overview β - SDK architecture guide
Understanding Concepts (Explanation)
- Choose Your SDK β - Strategic SDK selection guide
- Competitive Analysis β - Saros vs other protocols
- Traditional AMM Explained β - AMM concepts and strategies