all parser

This commit is contained in:
thloyi
2026-02-09 14:46:19 +08:00
parent 5da088ce13
commit 9ece4aebb9
22 changed files with 6720 additions and 174 deletions

View File

@@ -3,6 +3,7 @@ package pump_parser
import (
"errors"
"log"
"slices"
"github.com/gagliardetto/solana-go"
"github.com/shopspring/decimal"
@@ -21,6 +22,20 @@ type parserConfig struct {
enableMeteoraDlmm bool
}
func EnableAllParsers() {
programs := cloneSwapPrograms(defaultSwapPrograms)
programs[meteoraDlmmProgram] = metaoradlmmParser
programs[metaoraPoolProgramID] = metaoraPoolParser
programs[metaoraBcProgramID] = metaoraBcParser
programs[meteoraDammV2Program] = metaoraDammParser
programs[orcaProgramID] = orcaWhirPoolParser
programs[raydiumV4Program] = raydiumV4Parser
programs[raydiumClmmProgramID] = raydiumClmmParser
programs[raydiumCPmmProgramID] = raydiumCPmmParser
programs[raydiumLaunchLabProgramID] = raydiumLaunchLabParser
swapPrograms = programs
}
func InitParser(opts ...ParserOption) {
cfg := parserConfig{}
for _, opt := range opts {
@@ -85,7 +100,12 @@ func (tx *Tx) Parser() error {
for _, inner := range tx.rawTx.Meta.InnerInstructions {
innersMap[inner.Index] = inner
}
txIndex := 0
for i, instr := range tx.rawTx.Transaction.Message.Instructions {
txIndex += 1
if i > 0 {
txIndex += len(innersMap[i-1].Instructions)
}
programAccount := accountList[instr.ProgramIDIndex]
if p, exists := swapPrograms[programAccount]; exists {
swaps, _, err := p(tx, instr, innersMap[i], [2]uint{uint(i), uint(0)})
@@ -95,7 +115,20 @@ func (tx *Tx) Parser() error {
}
return err
}
tx.Swaps = append(tx.Swaps, swaps...)
for k, swap := range swaps {
swap.TxIndex = txIndex + k
if !swap.User.IsOnCurve() {
swap.AfterSOLBalance = tx.AfterSOLBalance
swap.User = tx.rawTx.accountList[0]
} else {
userIdx := slices.Index(tx.rawTx.accountList, swap.User)
if userIdx >= 0 {
swap.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[userIdx]).Div(decimal.NewFromInt(1e9))
}
}
tx.Swaps = append(tx.Swaps, swap)
}
} else if p, exists := actionPrograms[programAccount]; exists {
_, err := p(tx, instr, innersMap[i], [2]uint{uint(i), uint(0)})
if err != nil {
@@ -125,7 +158,24 @@ func (tx *Tx) Parser() error {
}
return err
}
tx.Swaps = append(tx.Swaps, swaps...)
for k, swap := range swaps {
swap.TxIndex = txIndex + k + j
// identify okxDexRoutersV2 and okxAggregatorV2 is user
//if !swap.User.IsOnCurve() && (swap.EntryContract.Equals(okxDexRoutersV2) || swap.EntryContract.Equals(okxAggregatorV2)) {
// swap.User = tx.rawTx.accountList[0]
//}
if !swap.User.IsOnCurve() {
swap.AfterSOLBalance = tx.AfterSOLBalance
swap.User = tx.rawTx.accountList[0]
} else {
userIdx := slices.Index(tx.rawTx.accountList, swap.User)
if userIdx >= 0 {
swap.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[userIdx]).Div(decimal.NewFromInt(1e9))
}
}
tx.Swaps = append(tx.Swaps, swap)
}
// tx.Swaps = append(tx.Swaps, swaps...)
j = int(offset[1])
ii = int(offset[0])
} else if p, exists := actionPrograms[innerProgramAccount]; exists {
@@ -148,10 +198,54 @@ func (tx *Tx) Parser() error {
}
}
}
// update swaps same program+pair with last reserve balance
if len(tx.Swaps) > 1 {
pairKey := func(s Swap) solana.PublicKey {
// Match pair selection used by downstream consumers.
if s.Program == SolProgramPump {
return s.BaseMint
}
return s.Pool
}
lastReserve := make(map[solana.PublicKey]reserveSnapshot, len(tx.Swaps))
for _, swap := range tx.Swaps {
lastReserve[pairKey(swap)] = reserveSnapshot{
baseMint: swap.BaseMint,
quoteMint: swap.QuoteMint,
baseReserve: swap.BaseReserve,
quoteReserve: swap.QuoteReserve,
}
}
for i := range tx.Swaps {
key := pairKey(tx.Swaps[i])
if v, ok := lastReserve[key]; ok {
if tx.Swaps[i].BaseMint == v.baseMint && tx.Swaps[i].QuoteMint == v.quoteMint {
tx.Swaps[i].BaseReserve = v.baseReserve
tx.Swaps[i].QuoteReserve = v.quoteReserve
} else if tx.Swaps[i].BaseMint == v.quoteMint && tx.Swaps[i].QuoteMint == v.baseMint {
tx.Swaps[i].BaseReserve = v.quoteReserve
tx.Swaps[i].QuoteReserve = v.baseReserve
}
//else {
// tx.Swaps[i].BaseReserve = v.baseReserve
// tx.Swaps[i].QuoteReserve = v.quoteReserve
//}
}
}
}
return nil
}
type reserveSnapshot struct {
baseMint solana.PublicKey
quoteMint solana.PublicKey
baseReserve decimal.Decimal
quoteReserve decimal.Decimal
}
func cloneSwapPrograms(src map[solana.PublicKey]swapParser) map[solana.PublicKey]swapParser {
dst := make(map[solana.PublicKey]swapParser, len(src))
for k, v := range src {