package shreder import ( "encoding/binary" "fmt" "strings" "github.com/gagliardetto/solana-go" ) var bloomRouterProgramID = solana.MustPublicKeyFromBase58("b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1") type bloomRouterArgs struct { Side uint16 SolAmount uint64 TokenAmount uint64 } func parseBloomRouterInstruction(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) < 26 { return nil, nil } var ( amount uint64 sol uint64 exactIn bool event string ) args, err := decodeBloomRouterArgs(instruction.Data) if err != nil { return nil, err } switch args.Side { case 0: event = "buy" exactIn = true case 1: event = "sell" default: return nil, nil } if args.SolAmount > ^uint64(0)/100 { return nil, fmt.Errorf("bloomrouter sol amount overflow") } // bloomrouter SOL amount has 2 fewer decimals than lamports. sol = args.SolAmount * 100 amount = args.TokenAmount if len(instruction.Accounts) == 0 { return nil, fmt.Errorf("accounts too short") } maker, err := tx.GetAccount(int(instruction.Accounts[0])) if err != nil { return nil, err } var ( mint solana.PublicKey ok bool ) for _, acctIdx := range instruction.Accounts { key, err := tx.GetAccount(int(acctIdx)) if err != nil { return nil, err } if strings.HasSuffix(key.String(), "pump") { mint = key ok = true break } } if !ok { return nil, nil } return TxSignalBatch{&TxSignal{ TxHash: tx.Signatures[0].String(), Label: "bloomrouter", Maker: maker.String(), Token0Address: mint.String(), Token1Address: wsolMint, Token0Amount: formatTokenAmount(amount), Token1Amount: formatSolAmount(sol), Program: "Pump", Event: event, ExactSOL: exactIn, IsToken2022: false, IsMayhemMode: false, Block: tx.Block, Token0AmountUint64: amount, Token1AmountUint64: sol, }}, nil } func decodeBloomRouterArgs(data []byte) (bloomRouterArgs, error) { if len(data) < 26 { return bloomRouterArgs{}, fmt.Errorf("data too short for bloomrouter args, len=%d", len(data)) } return bloomRouterArgs{ Side: binary.BigEndian.Uint16(data[8:10]), SolAmount: binary.LittleEndian.Uint64(data[10:18]), TokenAmount: binary.LittleEndian.Uint64(data[18:26]), }, nil }