package pump_parser import ( "errors" "github.com/gagliardetto/solana-go" "github.com/shopspring/decimal" ) var swapPrograms = map[solana.PublicKey]swapParser{ pumpAmmProgram: pumpAmmParser, pumpProgram: pumpParser, } var actionPrograms = map[solana.PublicKey]actionParser{ systemProgram: systemParser, budgGetProgram: budgetParser, } func Parser(rawTx *RawTx) (*Tx, error) { accountList := rawTx.getAccountList() var tx = &Tx{ TxHash: (*[64]byte)((rawTx.Transaction.Signatures[0][:])), Signer: rawTx.GetSigner(), Block: rawTx.Slot, BlockIndex: uint64(rawTx.IndexWithinBlock), BlockAt: rawTx.BlockTime, BeforeSolBalance: decimal.NewFromUint64(rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9)), AfterSOLBalance: decimal.NewFromUint64(rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9)), } var innersMap = make(map[int]InnerInstructions) for _, inner := range rawTx.Meta.InnerInstructions { innersMap[inner.Index] = inner } for i, instr := range rawTx.Transaction.Message.Instructions { programAccount := accountList[instr.ProgramIDIndex] if p, exists := swapPrograms[programAccount]; exists { swaps, _, err := p(rawTx, instr, innersMap[i], [2]uint{uint(i), uint(0)}) if err != nil { if errors.Is(err, InstructionIgnoredError) { continue } return nil, err } tx.Swaps = append(tx.Swaps, swaps...) } else if p, exists := actionPrograms[programAccount]; exists { _, err := p(rawTx, instr, innersMap[i], [2]uint{uint(i), uint(0)}, tx) if err != nil { if errors.Is(err, InstructionIgnoredError) { continue } return nil, err } } else { ii := i // unknown program, parser inner instructions innerLength := len(innersMap[i].Instructions) for j := 1; j <= innerLength; { innerInstr := innersMap[i].Instructions[j-1] innerProgramAccount := accountList[innerInstr.ProgramIDIndex] if p, exists := swapPrograms[innerProgramAccount]; exists { swaps, offset, err := p(rawTx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)}) if err != nil { if errors.Is(err, InstructionIgnoredError) { j = int(offset[1]) continue } return nil, err } tx.Swaps = append(tx.Swaps, swaps...) j = int(offset[1]) ii = int(offset[0]) } else if p, exists := actionPrograms[innerProgramAccount]; exists { offset, err := p(rawTx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)}, tx) if err != nil { if errors.Is(err, InstructionIgnoredError) { j = int(offset[1]) continue } return nil, err } j = int(offset[1]) ii = int(offset[0]) } else { j++ } if j > innerLength || ii > i { break } } } } return tx, nil }