all parser
This commit is contained in:
98
parser.go
98
parser.go
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user