I have a problem regarding the calculation of a Raydium pool price. (https://github.com/raydium-io/raydium-sdk)
- Raydium API Request for Liquid Pool V4 SOL/USDC.
import { Connection, PublicKey } from "@solana/web3.js";
import { LIQUIDITY_STATE_LAYOUT_V4 } from "@raydium-io/raydium-sdk";
import { BN } from "bn.js"
const SOL_USDC_POOL_ID = "58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2"; // Your pool ID
async function parsePoolInfo() {
const connection = new Connection("https://api.mainnet-beta.solana.com", "recent");
const info = await connection.getAccountInfo(new PublicKey(SOL_USDC_POOL_ID));
if (!info) return;
// Assuming the structure was successfully decoded
const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode(info.data);
console.log(poolState)
}
parsePoolInfo();
1.1 Console Output of the API call
{
status: <BN: 1>,
nonce: <BN: fe>,
maxOrder: <BN: 7>,
depth: <BN: 3>,
baseDecimal: <BN: 9>,
quoteDecimal: <BN: 6>,
state: <BN: 1>,
resetFlag: <BN: 1>,
minSize: <BN: f4240>,
volMaxCutRatio: <BN: 1f4>,
amountWaveRatio: <BN: 0>,
baseLotSize: <BN: f4240>,
quoteLotSize: <BN: f4240>,
minPriceMultiplier: <BN: 1>,
maxPriceMultiplier: <BN: 3b9aca00>,
systemDecimalValue: <BN: 3b9aca00>,
minSeparateNumerator: <BN: 5>,
minSeparateDenominator: <BN: 2710>,
tradeFeeNumerator: <BN: 19>,
tradeFeeDenominator: <BN: 2710>,
pnlNumerator: <BN: c>,
pnlDenominator: <BN: 64>,
swapFeeNumerator: <BN: 19>,
swapFeeDenominator: <BN: 2710>,
baseNeedTakePnl: <BN: 15c0b6d20>,
quoteNeedTakePnl: <BN: 3f148c03>,
quoteTotalPnl: <BN: cc322d0c31>,
baseTotalPnl: <BN: 20f2cc8a6d10>,
poolOpenTime: <BN: 0>,
punishPcAmount: <BN: 0>,
punishCoinAmount: <BN: 0>,
orderbookToInitTime: <BN: 0>,
swapBaseInAmount: <BN: 198ae479152985>,
swapQuoteOutAmount: <BN: daf1151a5f2b>,
swapBase2QuoteFee: <BN: 92b08e7d17>,
swapQuoteInAmount: <BN: e533d56efeeb>,
swapBaseOutAmount: <BN: 1a4bba4d1f08f5>,
swapQuote2BaseFee: <BN: 1058e429cf81>,
baseVault: PublicKey [PublicKey(DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz)] {
_bn: <BN: b870e12dd379891561d2e9fa8f26431834eb736f2f24fc2a2a4dff1fd5dca4df>
},
quoteVault: PublicKey [PublicKey(HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz)] {
_bn: <BN: f2cbb9b760eddb185706303063ad33d7b57296ea02d4e0335e31ceafa4cc42dd>
},
baseMint: PublicKey [PublicKey(So11111111111111111111111111111111111111112)] {
_bn: <BN: 69b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001>
},
quoteMint: PublicKey [PublicKey(EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v)] {
_bn: <BN: c6fa7af3bedbad3a3d65f36aabc97431b1bbe4c2d2f6e0e47ca60203452f5d61>
},
lpMint: PublicKey [PublicKey(8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NLGnaTUapubyvu)] {
_bn: <BN: 6c4f93d858e88ffafea08c43674497e8e6a932c0c83148262a1ae3ccc7829ec6>
},
openOrders: PublicKey [PublicKey(HmiHHzq4Fym9e1D4qzLS6LDDM3tNsCTBPDWHTLZ763jY)] {
_bn: <BN: f92f390ff9609e8ad437bb8e4c1f1aa43ac05d24308cca77de8512c5509292d3>
},
marketId: PublicKey [PublicKey(8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6)] {
_bn: <BN: 6ac4c3cefa9f19bf54c8dc0f5e4d1ceee5327d26482b29d2b13cbaa43447218d>
},
marketProgramId: PublicKey [PublicKey(srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX)] {
_bn: <BN: d0751a8282da61305fe299c37b998e58471db1135037310f8be1045a60af6ee>
},
targetOrders: PublicKey [PublicKey(CZza3Ej4Mc58MnxWA385itCC9jCo3L1D7zc3LKy1bZMR)] {
_bn: <BN: abe43c7c1e21eaa6f97c8bd355e21bd1279674756c1c8e106c6e712ba116d970>
},
withdrawQueue: PublicKey [PublicKey(11111111111111111111111111111111)] {
_bn: <BN: 0>
},
lpVault: PublicKey [PublicKey(11111111111111111111111111111111)] {
_bn: <BN: 0>
},
owner: PublicKey [PublicKey(GThUX1Atko4tqhN2NaiTazWSeFWMuiUvfFnyJyUghFMJ)] {
_bn: <BN: e5b62b65cb3bbda6f56888e66fee8e64dc5560199c0f88b11fe273bd059e8aa1>
},
lpReserve: <BN: 41e692e5f338>,
padding: [ <BN: 700dc7>, <BN: 0>, <BN: 0> ]
}
- Decode API DATA BigNumbers into decimals.
console.log("Status:", poolState.status.toNumber());
console.log("Nonce:", poolState.nonce.toNumber());
console.log("Max Order:", poolState.maxOrder.toNumber());
console.log("Depth:", poolState.depth.toNumber());
console.log("Base Decimal:", poolState.baseDecimal.toNumber());
console.log("Quote Decimal:", poolState.quoteDecimal.toNumber());
console.log("State:", poolState.state.toNumber());
console.log("Reset Flag:", poolState.resetFlag.toNumber());
console.log("Min Size:", poolState.minSize.toNumber());
console.log("Vol Max Cut Ratio:", poolState.volMaxCutRatio.toNumber());
console.log("Amount Wave Ratio:", poolState.amountWaveRatio.toNumber());
console.log("Base Lot Size:", poolState.baseLotSize.toNumber());
console.log("Quote Lot Size:", poolState.quoteLotSize.toNumber());
console.log("Min Price Multiplier:", poolState.minPriceMultiplier.toNumber());
console.log("Max Price Multiplier:", poolState.maxPriceMultiplier.toNumber());
console.log("System Decimal Value:", poolState.systemDecimalValue.toNumber());
console.log("Min Separate Numerator:", poolState.minSeparateNumerator.toNumber());
console.log("Min Separate Denominator:", poolState.minSeparateDenominator.toNumber());
console.log("Trade Fee Numerator:", poolState.tradeFeeNumerator.toNumber());
console.log("Trade Fee Denominator:", poolState.tradeFeeDenominator.toNumber());
console.log("PnL Numerator:", poolState.pnlNumerator.toNumber());
console.log("PnL Denominator:", poolState.pnlDenominator.toNumber());
console.log("Swap Fee Numerator:", poolState.swapFeeNumerator.toNumber());
console.log("Swap Fee Denominator:", poolState.swapFeeDenominator.toNumber());
console.log("Base Need Take PnL:", poolState.baseNeedTakePnl.toNumber());
console.log("Quote Need Take PnL:", poolState.quoteNeedTakePnl.toNumber());
console.log("Quote Total PnL:", poolState.quoteTotalPnl.toNumber());
console.log("Base Total PnL:", poolState.baseTotalPnl.toNumber());
console.log("Pool Open Time:", poolState.poolOpenTime.toNumber());
console.log("Punish Pc Amount:", poolState.punishPcAmount.toNumber());
console.log("Punish Coin Amount:", poolState.punishCoinAmount.toNumber());
console.log("Orderbook To Init Time:", poolState.orderbookToInitTime.toNumber());
console.log("Swap Base In Amount:", poolState.swapBaseInAmount.toNumber());
console.log("Swap Quote Out Amount:", poolState.swapQuoteOutAmount.toNumber());
console.log("Swap Base2Quote Fee:", poolState.swapBase2QuoteFee.toNumber());
console.log("Swap Quote In Amount:", poolState.swapQuoteInAmount.toNumber());
console.log("Swap Base Out Amount:", poolState.swapBaseOutAmount.toNumber());
console.log("Swap Quote2Base Fee:", poolState.swapQuote2BaseFee.toNumber());
// For PublicKey fields, you can directly log them as they are:
console.log("Base Vault:", poolState.baseVault.toString());
console.log("Quote Vault:", poolState.quoteVault.toString());
console.log("Base Mint:", poolState.baseMint.toString());
console.log("Quote Mint:", poolState.quoteMint.toString());
console.log("LP Mint:", poolState.lpMint.toString());
console.log("Open Orders:", poolState.openOrders.toString());
console.log("Market ID:", poolState.marketId.toString());
console.log("Market Program ID:", poolState.marketProgramId.toString());
console.log("Target Orders:", poolState.targetOrders.toString());
console.log("Withdraw Queue:", poolState.withdrawQueue.toString());
console.log("LP Vault:", poolState.lpVault.toString());
console.log("Owner:", poolState.owner.toString());
console.log("LP Reserve:", poolState.lpReserve.toNumber());
2.2 Console Output decoded BigNumbers in decimals
Status: 1
Nonce: 254
Max Order: 7
Depth: 3
Base Decimal: 9
Quote Decimal: 6
State: 1
Reset Flag: 1
Min Size: 1000000
Vol Max Cut Ratio: 500
Amount Wave Ratio: 0
Base Lot Size: 1000000
Quote Lot Size: 1000000
Min Price Multiplier: 1
Max Price Multiplier: 1000000000
System Decimal Value: 1000000000
Min Separate Numerator: 5
Min Separate Denominator: 10000
Trade Fee Numerator: 25
Trade Fee Denominator: 10000
PnL Numerator: 12
PnL Denominator: 100
Swap Fee Numerator: 25
Swap Fee Denominator: 10000
Base Need Take PnL: 5839220000
Quote Need Take PnL: 1058311171
Quote Total PnL: 877015141425
Base Total PnL: 36227185798416
Pool Open Time: 0
Punish Pc Amount: 0
Punish Coin Amount: 0
Orderbook To Init Time: 0
Swap Base In Amount: 7189588306372997
Swap Quote Out Amount: 240728976023339
Swap Base2Quote Fee: 630027353367
Swap Quote In Amount: 252010786914027
Swap Base Out Amount: 7401612924356853
Swap Quote2Base Fee: 17973971111809
Base Vault: DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz
Quote Vault: HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz
Base Mint: So11111111111111111111111111111111111111112
Quote Mint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
LP Mint: 8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NLGnaTUapubyvu
Open Orders: HmiHHzq4Fym9e1D4qzLS6LDDM3tNsCTBPDWHTLZ763jY
Market ID: 8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6
Market Program ID: srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX
Target Orders: CZza3Ej4Mc58MnxWA385itCC9jCo3L1D7zc3LKy1bZMR
Withdraw Queue: 11111111111111111111111111111111
LP Vault: 11111111111111111111111111111111
Owner: GThUX1Atko4tqhN2NaiTazWSeFWMuiUvfFnyJyUghFMJ
LP Reserve: 72458562827064
Here is where I struggle
3. Calculation of the Price of one SOL. ( 1 SOL / (X) USDC )
**//ATTEMP NUMBER 1:**
// Just for clarification where I got these values!
// from decoded data: Swap Quote Out Amount: 240728976023339, Swap Base Out Amount: 7401612924356853
function calculatePricePerSOLInUSDC(): string {
return (Number(BigInt("252010786914027")) / Math.pow(10, 6) / (Number(BigInt("7401612924356853")) / Math.pow(10, 9))).toFixed(6);
}
console.log(`Price per 1 SOL in USDC: ${calculatePricePerSOLInUSDC()}`);
**//ATTEMPT 2**
//Standard calculation of quote amount / base amount
// Got values of these two "VAULTS"
//Base Vault: DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz
//Quote Vault: HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz
// at the current timestamp the values are:
//23,177.61 SOL
//5,700,097.46 USDC
5700097.46 / 23177.61 = 245,931
3.1 Output of Calculation (which obviously can´t be right)
**ATTEMPT 1* Price per 1 SOL in USDC: 34.048091
**ATTEMPT 2* Price per 1 SOl in USDC: 245,931
If any additional information is needed please feel free to leave a comment!