Compare commits

...

3 Commits

Author SHA1 Message Date
cachalots
852ad4b382 cu limit 2026-02-11 17:49:43 +08:00
thloyi
3fdd4c4490 fix parse error 2026-02-11 14:58:12 +08:00
thloyi
40012b531c fix meteora pool entrycontract 2026-02-10 10:32:46 +08:00
11 changed files with 45 additions and 31 deletions

View File

@@ -27,10 +27,11 @@ func budgetParser(tx *Tx, instr Instruction, _ InnerInstructions, offset [2]uint
}
}
func computeUnitLimitParser(offset [2]uint, _ *Tx, decodedData []byte) ([2]uint, error) {
if len(decodedData) < 8 {
func computeUnitLimitParser(offset [2]uint, tx *Tx, decodedData []byte) ([2]uint, error) {
if len(decodedData) < 4 {
return increaseOffset(offset), nil
}
tx.CuLimit = binary.BigEndian.Uint32(decodedData[:4])
return increaseOffset(offset), nil
}

View File

@@ -23,7 +23,7 @@ var ()
func main() {
var slot uint64 = 399060766
var slot uint64 = 399477968
var data = NewBlockData(decimal.NewFromFloat(100.0))
client := rpc.New("https://staked.helius-rpc.com?api-key=5adcf1f9-5719-43d1-bf3f-c2d4e1e5f94d")
var rewards = false

View File

@@ -234,5 +234,6 @@ var transferDiscriminator = uint32(2)
var createAccountWithSeedDiscriminator = uint32(3)
var systemProgram = solana.MustPublicKeyFromBase58("11111111111111111111111111111111")
var momoProgram = solana.MustPublicKeyFromBase58("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr")
var eventDiscriminator = [8]byte{228, 69, 165, 46, 81, 203, 154, 29}

View File

@@ -371,6 +371,7 @@ func metaoraPoolAddLiquidity(tx *Tx, instruction Instruction, innerInstructions
if len(instruction.Accounts) < 14 {
return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length")
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
pool := tx.rawTx.accountList[instruction.Accounts[0]]
lpMint := tx.rawTx.accountList[instruction.Accounts[1]]
@@ -494,8 +495,6 @@ func metaoraPoolAddLiquidity(tx *Tx, instruction Instruction, innerInstructions
return nil, increaseOffset(offset), fmt.Errorf("failed to find deposit instructions")
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var event = "add_liquidity_one_side"
if baseFound && quoteFound {
// both sides
@@ -530,6 +529,7 @@ func metaoraPoolRemoveLiquidity(tx *Tx, instruction Instruction, innerInstructio
if len(instruction.Accounts) < 14 {
return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length")
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
pool := tx.rawTx.accountList[instruction.Accounts[0]]
lpMint := tx.rawTx.accountList[instruction.Accounts[1]]
@@ -700,8 +700,6 @@ func metaoraPoolRemoveLiquidity(tx *Tx, instruction Instruction, innerInstructio
return nil, increaseOffset(offset), fmt.Errorf("failed to find withdraw instructions, baseFound: %v, quoteFound: %v", baseFound, quoteFound)
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var event = "remove_liquidity_one_side"
if baseFound && quoteFound {
event = "remove_liquidity"

View File

@@ -90,7 +90,7 @@ func meteoraDammV2InitializePoolParser(tx *Tx, instruction Instruction, innerIns
var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("meta Bonding Curve initial get inner instructions error: %v, offset, %d, %d", err, offset[0], offset[1])
return nil, increaseOffset(offset), fmt.Errorf("meta damm initial get inner instructions error: %v, offset, %d, %d", err, offset[0], offset[1])
}
var loadedEvent bool
var initializePoolEvent MetaoraDammInitializePoolEvent
@@ -119,6 +119,13 @@ func meteoraDammV2InitializePoolParser(tx *Tx, instruction Instruction, innerIns
}
baseVaultAccountIndex := instruction.Accounts[10]
quoteVaultAccountIndex := instruction.Accounts[11]
if bytes.Equal(instruction.Data[:8], meteoraDammV2InitializePoolWithDynamicConfig[:]) {
baseVaultAccountIndex = instruction.Accounts[11]
quoteVaultAccountIndex = instruction.Accounts[12]
} else if bytes.Equal(instruction.Data[:8], meteoraDammV2InitializeCustomizablePoolDiscriminator[:]) {
baseVaultAccountIndex = instruction.Accounts[9]
quoteVaultAccountIndex = instruction.Accounts[10]
}
baseVaultTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, baseVaultAccountIndex)
if err != nil {

View File

@@ -848,11 +848,11 @@ func orcaWhirPoolSwapV2Parser(tx *Tx, instruction Instruction, innerInstructions
var baseFound, quoteFound bool
var skipOffset = 0
for i, inner := range inners {
if !tx.rawTx.accountList[inner.ProgramIDIndex].Equals(solana.Token2022ProgramID) && !tx.rawTx.accountList[inner.ProgramIDIndex].Equals(solana.TokenProgramID) {
continue
}
from, to, amount, err := parseTokenTransfer(tx.rawTx, inner)
if err != nil {
if i <= 1 { //maybe momo??
continue
}
return nil, increaseOffset(offset), fmt.Errorf("orca whirpool swapv2 parse token transfer error: %v, offset, %d, %d", err, offset[0], offset[1])
}
if !baseFound && (from.Equals(vault0Account) || to.Equals(vault0Account)) {
@@ -1010,11 +1010,11 @@ func orcaWhirPoolTwoHopSwapParser(tx *Tx, instruction Instruction, innerInstruct
{
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, pool2VaultBase)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool1 token0 vault balance after tx: %v", err)
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool2 token0 vault balance after tx: %v", err)
}
quoteTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, pool2VaultQuote)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool1 token1 vault balance after tx: %v", err)
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool2 token1 vault balance after tx: %v", err)
}
userBase := getAccountBalanceAfterTx(tx.rawTx, pool2UserBase)
@@ -1105,8 +1105,8 @@ func orcaWhirPoolTwoHopSwapV2Parser(tx *Tx, instruction Instruction, innerInstru
//pool2UserBase := instruction.Accounts[8]
pool2VaultBase := instruction.Accounts[11]
pool2UserQuote := instruction.Accounts[12]
pool2VaultQuote := instruction.Accounts[13]
pool2VaultQuote := instruction.Accounts[12]
pool2UserQuote := instruction.Accounts[13]
swaps := make([]Swap, 2)
{
@@ -1186,11 +1186,11 @@ func orcaWhirPoolTwoHopSwapV2Parser(tx *Tx, instruction Instruction, innerInstru
{
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, pool2VaultBase)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool1 token0 vault balance after tx: %v", err)
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool2 token0 vault balance after tx: %v", err)
}
quoteTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, pool2VaultQuote)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool1 token1 vault balance after tx: %v", err)
return nil, increaseOffset(offset), fmt.Errorf("failed to get pool2 token1 vault balance after tx: %v", err)
}
userBase := decimal.Zero

View File

@@ -91,6 +91,7 @@ func (tx *Tx) Parser() error {
tx.BlockAt = tx.rawTx.BlockTime
tx.CuFee = decimal.NewFromUint64(tx.rawTx.Meta.Fee)
tx.ComputeUnitsConsumed = tx.rawTx.Meta.ComputeUnitsConsumed
tx.BeforeSolBalance = decimal.NewFromUint64(tx.rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9))
tx.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9))

View File

@@ -146,16 +146,17 @@ func (tb *TokenBalance) ParseAccount() {
}
type Meta struct {
Err interface{} `json:"err"`
Fee uint64 `json:"fee"`
InnerInstructions []InnerInstructions `json:"innerInstructions"`
LoadedAddresses LoadedAddresses `json:"loadedAddresses"`
LogMessages []string `json:"logMessages"`
PostBalances []uint64 `json:"postBalances"`
PostTokenBalances []TokenBalance `json:"postTokenBalances"`
PreBalances []uint64 `json:"preBalances"`
PreTokenBalances []TokenBalance `json:"preTokenBalances"`
Rewards []interface{} `json:"rewards"`
Err interface{} `json:"err"`
Fee uint64 `json:"fee"`
InnerInstructions []InnerInstructions `json:"innerInstructions"`
LoadedAddresses LoadedAddresses `json:"loadedAddresses"`
LogMessages []string `json:"logMessages"`
PostBalances []uint64 `json:"postBalances"`
PostTokenBalances []TokenBalance `json:"postTokenBalances"`
PreBalances []uint64 `json:"preBalances"`
PreTokenBalances []TokenBalance `json:"preTokenBalances"`
Rewards []interface{} `json:"rewards"`
ComputeUnitsConsumed uint64 `json:"computeUnitsConsumed"`
}
type Header struct {
NumReadonlySignedAccounts int `json:"numReadonlySignedAccounts"`
@@ -805,7 +806,7 @@ func ConvertYellowstoneGrpcTransactionToSolanaTransaction(y *pb.SubscribeUpdateT
}
sTx.Meta.Fee = meta.Fee
//sTx.Meta.InnerInstructions = meta.InnerInstructions
sTx.Meta.ComputeUnitsConsumed = *meta.ComputeUnitsConsumed
for _, innerInstr := range meta.InnerInstructions {
var instrs []Instruction
for _, instr := range innerInstr.Instructions {

View File

@@ -54,12 +54,12 @@ func raydiumCPmmCreatePoolParser(tx *Tx, instruction Instruction, innerInstructi
vault1 = instruction.Accounts[12]
}
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, instruction.Accounts[vault0])
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, vault0)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get token0 vault balance after tx: %v", err)
}
quoteTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, instruction.Accounts[vault1])
quoteTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, vault1)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get token1 vault balance after tx: %v", err)
}

View File

@@ -143,7 +143,7 @@ type RaydiumLaunchLabCreateEvent struct {
}
func raydiumLaunchLabInitializeParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 16 {
if len(instruction.Accounts) < 15 {
return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for initialize instruction")
}
user := tx.rawTx.accountList[instruction.Accounts[0]]

5
tx.go
View File

@@ -47,6 +47,8 @@ type Swap struct {
StartBinId int32
EndBinId int32
BinChanges []DlmmBinLiquidityChange
ConsumeUnit uint64
}
type DlmmBinLiquidityChange struct {
@@ -98,6 +100,9 @@ type Tx struct {
// update tokenInfo
Token map[solana.PublicKey]TokenMeta `gorm:"-"`
ComputeUnitsConsumed uint64 `json:"compute_units_consumed"`
CuLimit uint32 `json:"cu_limit"`
// todo pool info ??
}