package shreder import ( "encoding/binary" "fmt" "github.com/gagliardetto/solana-go" ) var bonkProgramID = solana.MustPublicKeyFromBase58("BBRouter1cVunVXvkcqeKkZQcBK7ruan37PPm3xzWaXD") var ( bonkBuyAndSellTokensIX = []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a} ) func parseBonkInstruction(tx VersionedTransaction, instructionIndex int) (TxSignalBatch, error) { if instructionIndex >= len(tx.Instructions) { return nil, fmt.Errorf("instruction index out of bounds") } instruction := tx.Instructions[instructionIndex] if len(instruction.Data) == 0 { return nil, fmt.Errorf("data is empty") } var ( err error txSignal *TxSignal ) if matchMethod(instruction.Data, bonkBuyAndSellTokensIX) { txSignal, err = parseBonkBuyAndSell(tx, instruction) } if txSignal != nil { return TxSignalBatch{txSignal}, err } return nil, err } func parseBonkBuyAndSell(tx VersionedTransaction, instruction Instructions) (*TxSignal, error) { if len(instruction.Accounts) < 8 { return nil, fmt.Errorf("accounts too short") } programId, err := tx.GetAccount(int(instruction.Accounts[7])) if err != nil { return nil, err } if programId != pumpProgramID { return nil, nil } user, err := tx.GetAccount(int(instruction.Accounts[0])) if err != nil { return nil, err } flagAccount, err := tx.GetAccount(int(instruction.Accounts[4])) if err != nil { return nil, err } amount1 := binary.LittleEndian.Uint64(instruction.Data[17:25]) amount2 := binary.LittleEndian.Uint64(instruction.Data[25:33]) if user == flagAccount { mint, err := tx.GetAccount(int(instruction.Accounts[6])) if err != nil { return nil, err } return &TxSignal{ TxHash: tx.Signatures[0].String(), Label: "bonk", Maker: user.String(), Token0Address: mint.String(), Token1Address: wsolMint, Token0Amount: formatTokenAmount(amount2), Token1Amount: formatSolAmount(amount1), Program: "Pump", Event: "buy", IsToken2022: false, IsMayhemMode: false, ExactSOL: true, Block: tx.Block, Token0AmountUint64: amount2, Token1AmountUint64: amount1, }, nil } else { mint, err := tx.GetAccount(int(instruction.Accounts[5])) if err != nil { return nil, err } return &TxSignal{ TxHash: tx.Signatures[0].String(), Label: "bonk", Maker: user.String(), Token0Address: mint.String(), Token1Address: wsolMint, Token0Amount: formatTokenAmount(amount1), Token1Amount: formatSolAmount(amount2), Program: "Pump", Event: "sell", IsToken2022: false, IsMayhemMode: false, ExactSOL: false, Block: tx.Block, Token0AmountUint64: amount1, Token1AmountUint64: amount2, }, nil } }