Learn how to add and remove liquidity from pools using the Saros SDK with this comprehensive guide.
This tutorial will guide you through the process of providing liquidity to pools and withdrawing it using the Saros SDK. Liquidity providers earn fees from trades that occur in their pools.
Before starting this tutorial, ensure you have the following:
// Install the required packages
npm install @saros-finance/sdk @solana/web3.js
// Import the necessary modules
import {
getPoolInfo,
depositAllTokenTypes,
withdrawAllTokenTypes,
getTokenMintInfo,
getTokenAccountInfo,
getInfoTokenByMint,
genConnectionSolana,
convertBalanceToWei
} from '@saros-finance/sdk';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
First, we need to establish a connection to the Solana network and configure our wallet.
// Generate a connection to the Solana network
const connection = genConnectionSolana();
// Define your wallet address (in a real app, this would come from a connected wallet)
const accountSol = 'YOUR_WALLET_PUBLIC_KEY';
// Define the payer account object
const payerAccount = { publicKey: new PublicKey(accountSol) };
Define the tokens for your liquidity pool, including their mint addresses and SPL token accounts.
// Configure the tokens for the liquidity pool
// Example: C98-USDC liquidity pool
const USDC_TOKEN = {
id: 'usd-coin',
mintAddress: 'EPjFWdd5AufqSSqeM2qN1zzybapC8G4wEGGkZwyTDt1v',
symbol: 'usdc',
name: 'USD Coin',
decimals: '6',
addressSPL: 'FXRiEosEvHnpc3XZY1NS7an2PB1SunnYW1f5zppYhXb3',
};
const C98_TOKEN = {
id: 'coin98',
mintAddress: 'C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9',
symbol: 'C98',
name: 'Coin98',
decimals: '6',
addressSPL: 'EKCdCBjfQ6t5FBfDC2zvmr27PgfVVZU37C8LUE4UenKb',
};
Set up the pool parameters for liquidity operations. You'll need to know the pool address and token information.
// Configure the pool parameters
const poolParams = {
address: '2wUvdZA8ZsY714Y5wUL9fkFmupJGGwzui2N74zqJWgty',
tokens: {
C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9: {
...C98_TOKEN,
},
EPjFWdd5AufqSSqeM2qN1zzybapC8G4wEGGkZwyTDt1v: {
...USDC_TOKEN,
},
},
tokenIds: [
'C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9',
'EPjFWdd5AufqSSqeM2qN1zzybapC8G4wEGGkZwyTDt1v',
],
};
Retrieve information about the liquidity pool to understand its current state.
// Get information about the liquidity pool
const poolAccountInfo = await getPoolInfo(
connection,
new PublicKey(poolParams.address)
);
console.log('Pool Info:', poolAccountInfo);
Add liquidity to the pool by depositing tokens and receiving LP tokens in return.
// Add liquidity to the pool
const SLIPPAGE = 0.5; // 0.5% slippage tolerance
// Get pool LP token mint information
const newPoolLpMintInfo = await getTokenMintInfo(
connection,
poolAccountInfo.lpTokenMint
);
// Calculate LP token supply
const lpTokenSupply = newPoolLpMintInfo.supply
? newPoolLpMintInfo.supply.toNumber()
: 0;
// Convert token amounts
const convertFromAmount = convertBalanceToWei(1, USDC_TOKEN.decimals);
const newPoolToken0AccountInfo = await getTokenAccountInfo(
connection,
poolAccountInfo.token0Account
);
// Calculate LP token amount to receive
const lpTokenAmount =
(parseFloat(convertFromAmount) * lpTokenSupply) /
newPoolToken0AccountInfo.amount.toNumber();
// Add liquidity to the pool
const result = await depositAllTokenTypes(
connection,
accountSol,
new PublicKey(accountSol),
new PublicKey(C98_TOKEN.addressSPL),
new PublicKey(USDC_TOKEN.addressSPL),
lpTokenAmount,
new PublicKey(poolParams.address),
new PublicKey('SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr'), // Program address
C98_TOKEN.mintAddress,
USDC_TOKEN.mintAddress,
SLIPPAGE
);
// Handle the result
if (result.isError) {
console.log(`Add liquidity failed: ${result.mess}`);
} else {
console.log(`Liquidity added successfully! Transaction hash: ${result.hash}`);
}
depositAllTokenTypes
to add liquidity to the pool.Remove liquidity from the pool by burning LP tokens and receiving the underlying tokens back.
// Remove liquidity from the pool
// Get LP token information
const lpTokenMint = poolAccountInfo.lpTokenMint.toString();
const newPoolToken0AccountInfo = await getTokenAccountInfo(
connection,
poolAccountInfo.token0Account
);
// Calculate LP token amount to redeem
const lpTokenAmount =
(parseFloat(1) * lpTokenSupply) /
newPoolToken0AccountInfo.amount.toNumber();
// Get user's LP token account
const infoLpUser = await getInfoTokenByMint(lpTokenMint, accountSol);
// Remove liquidity from the pool
const result = await withdrawAllTokenTypes(
connection,
accountSol,
infoLpUser.pubkey,
C98_TOKEN.addressSPL,
USDC_TOKEN.addressSPL,
lpTokenAmount,
new PublicKey(poolParams.address),
new PublicKey('SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr'), // Program address
C98_TOKEN.mintAddress,
USDC_TOKEN.mintAddress,
SLIPPAGE
);
// Handle the result
if (result.isError) {
console.log(`Remove liquidity failed: ${result.mess}`);
} else {
console.log(`Liquidity removed successfully! Transaction hash: ${result.hash}`);
}
withdrawAllTokenTypes
to remove liquidity from the pool.