Skip to content

Instantly share code, notes, and snippets.

@fipso
Created December 19, 2024 11:37
Show Gist options
  • Save fipso/c9ee31d4a60f3cec87f11d0b69564e26 to your computer and use it in GitHub Desktop.
Save fipso/c9ee31d4a60f3cec87f11d0b69564e26 to your computer and use it in GitHub Desktop.
Decode the LIQUIDITY_STATE_LAYOUT_V4 (Raydium JS SDK) aka. data of the Pool Account
package main
import (
"fmt"
"math/big"
"encoding/binary"
"github.com/gagliardetto/solana-go"
)
type PoolStateV4 struct {
Status uint64
Nonce uint64
MaxOrder uint64
Depth uint64
BaseDecimal uint64
QuoteDecimal uint64
State uint64
ResetFlag uint64
MinSize uint64
VolMaxCutRatio uint64
AmountWaveRatio uint64
BaseLotSize uint64
QuoteLotSize uint64
MinPriceMultiplier uint64
MaxPriceMultiplier uint64
SystemDecimalValue uint64
MinSeparateNumerator uint64
MinSeparateDenominator uint64
TradeFeeNumerator uint64
TradeFeeDenominator uint64
PnlNumerator uint64
PnlDenominator uint64
SwapFeeNumerator uint64
SwapFeeDenominator uint64
BaseNeedTakePnl uint64
QuoteNeedTakePnl uint64
QuoteTotalPnl uint64
BaseTotalPnl uint64
PoolOpenTime uint64
PunishPcAmount uint64
PunishCoinAmount uint64
OrderbookToInitTime uint64
SwapBaseInAmount *big.Int // u128
SwapQuoteOutAmount *big.Int // u128
SwapBase2QuoteFee uint64
SwapQuoteInAmount *big.Int // u128
SwapBaseOutAmount *big.Int // u128
SwapQuote2BaseFee uint64
BaseVault solana.PublicKey
QuoteVault solana.PublicKey
BaseMint solana.PublicKey
QuoteMint solana.PublicKey
LpMint solana.PublicKey
OpenOrders solana.PublicKey
MarketId solana.PublicKey
MarketProgramId solana.PublicKey
TargetOrders solana.PublicKey
WithdrawQueue solana.PublicKey
LpVault solana.PublicKey
Owner solana.PublicKey
LpReserve uint64
Padding [3]uint64
}
func decodePoolStateV4(data []byte) (*PoolStateV4, error) {
if len(data) < 752 {
return nil, fmt.Errorf("data too short: %d bytes", len(data))
}
state := &PoolStateV4{}
offset := 0
// Decode all uint64 fields
state.Status = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.Nonce = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MaxOrder = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.Depth = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.BaseDecimal = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.QuoteDecimal = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.State = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.ResetFlag = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MinSize = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.VolMaxCutRatio = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.AmountWaveRatio = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.BaseLotSize = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.QuoteLotSize = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MinPriceMultiplier = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MaxPriceMultiplier = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.SystemDecimalValue = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MinSeparateNumerator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.MinSeparateDenominator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.TradeFeeNumerator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.TradeFeeDenominator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.PnlNumerator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.PnlDenominator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.SwapFeeNumerator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.SwapFeeDenominator = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.BaseNeedTakePnl = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.QuoteNeedTakePnl = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.QuoteTotalPnl = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.BaseTotalPnl = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.PoolOpenTime = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.PunishPcAmount = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.PunishCoinAmount = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.OrderbookToInitTime = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
// Decode u128 fields (16 bytes each)
state.SwapBaseInAmount = new(big.Int).SetBytes(reverseBytes(data[offset : offset+16]))
offset += 16
state.SwapQuoteOutAmount = new(big.Int).SetBytes(reverseBytes(data[offset : offset+16]))
offset += 16
state.SwapBase2QuoteFee = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
state.SwapQuoteInAmount = new(big.Int).SetBytes(reverseBytes(data[offset : offset+16]))
offset += 16
state.SwapBaseOutAmount = new(big.Int).SetBytes(reverseBytes(data[offset : offset+16]))
offset += 16
state.SwapQuote2BaseFee = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
// Decode PublicKey fields (32 bytes each)
copy(state.BaseVault[:], data[offset:offset+32])
offset += 32
copy(state.QuoteVault[:], data[offset:offset+32])
offset += 32
copy(state.BaseMint[:], data[offset:offset+32])
offset += 32
copy(state.QuoteMint[:], data[offset:offset+32])
offset += 32
copy(state.LpMint[:], data[offset:offset+32])
offset += 32
copy(state.OpenOrders[:], data[offset:offset+32])
offset += 32
copy(state.MarketId[:], data[offset:offset+32])
offset += 32
copy(state.MarketProgramId[:], data[offset:offset+32])
offset += 32
copy(state.TargetOrders[:], data[offset:offset+32])
offset += 32
copy(state.WithdrawQueue[:], data[offset:offset+32])
offset += 32
copy(state.LpVault[:], data[offset:offset+32])
offset += 32
copy(state.Owner[:], data[offset:offset+32])
offset += 32
// Decode final uint64 fields
state.LpReserve = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
// Decode padding
for i := 0; i < 3; i++ {
state.Padding[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
offset += 8
}
return state, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment