Add bloomrouter pumpfun parse
This commit is contained in:
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
rpcURL = "https://staked.helius-rpc.com?api-key=5adcf1f9-5719-43d1-bf3f-c2d4e1e5f94d"
|
rpcURL = "https://staked.helius-rpc.com?api-key=5adcf1f9-5719-43d1-bf3f-c2d4e1e5f94d"
|
||||||
txSignature = "4rkbkLCUQxc89Aq1BZxU1w4LDQtnCtoUJ6VNHmVec8Kqngr5T89xAXahubLFg8DF6iFGzJ39N8V8n6LFtARDUJT9"
|
txSignature = "4YUQzsQcHxt5jA6qKPVBWCgw8VRuE6bZqAoXeiwptbdLwta3QnDbWHzjwP3mY8hJPPerSf1yGbpdL2SdyWZTJ9e1"
|
||||||
labelFilter = ""
|
labelFilter = ""
|
||||||
enableStats = true
|
enableStats = true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ var (
|
|||||||
|
|
||||||
bonkProgramID = solana.MustPublicKeyFromBase58("BBRouter1cVunVXvkcqeKkZQcBK7ruan37PPm3xzWaXD")
|
bonkProgramID = solana.MustPublicKeyFromBase58("BBRouter1cVunVXvkcqeKkZQcBK7ruan37PPm3xzWaXD")
|
||||||
|
|
||||||
|
bloomRouterProgramID = solana.MustPublicKeyFromBase58("b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1")
|
||||||
|
|
||||||
// For Metaora dlmm
|
// For Metaora dlmm
|
||||||
dlmmProgramID = solana.MustPublicKeyFromBase58("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo")
|
dlmmProgramID = solana.MustPublicKeyFromBase58("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo")
|
||||||
@@ -186,6 +187,12 @@ type photonSwapPumpAmmArgs struct {
|
|||||||
ToAmount uint64
|
ToAmount uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bloomRouterArgs struct {
|
||||||
|
Side uint16
|
||||||
|
SolAmount uint64
|
||||||
|
TokenAmount uint64
|
||||||
|
}
|
||||||
|
|
||||||
type pumpAmmBuyArgs struct {
|
type pumpAmmBuyArgs struct {
|
||||||
Amount uint64
|
Amount uint64
|
||||||
MaxSolCost uint64
|
MaxSolCost uint64
|
||||||
@@ -360,6 +367,9 @@ func ParseTransaction(update *SubscribeUpdateTransaction, loader *AddressTables,
|
|||||||
case bonkProgramID:
|
case bonkProgramID:
|
||||||
txRes, err := parseBonkInstruction(versioned, i)
|
txRes, err := parseBonkInstruction(versioned, i)
|
||||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "bonk")
|
parsed = appendParsed(now, parsed, txRes, err, txHash, "bonk")
|
||||||
|
case bloomRouterProgramID:
|
||||||
|
txRes, err := parseBloomRouterInstruction(versioned, i)
|
||||||
|
parsed = appendParsed(now, parsed, txRes, err, txHash, "bloomrouter")
|
||||||
case dlmmProgramID:
|
case dlmmProgramID:
|
||||||
txRes, err := parseDlmmInstruction(versioned, i)
|
txRes, err := parseDlmmInstruction(versioned, i)
|
||||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "dlmm")
|
parsed = appendParsed(now, parsed, txRes, err, txHash, "dlmm")
|
||||||
@@ -2033,6 +2043,101 @@ func parseBonkBuyAndSell(tx *versionedTransaction, instruction *compiledInstruct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseBloomRouterInstruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
||||||
|
msg := tx.Message
|
||||||
|
if instructionIndex >= len(msg.Instructions) {
|
||||||
|
return nil, fmt.Errorf("instruction index out of bounds")
|
||||||
|
}
|
||||||
|
|
||||||
|
instruction := msg.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 := getStaticKey(msg.StaticAccountKeys, int(instruction.Accounts[0]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
mint solana.PublicKey
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
for _, acctIdx := range instruction.Accounts {
|
||||||
|
key, err := getStaticKey(msg.StaticAccountKeys, 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 &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
|
||||||
|
}
|
||||||
|
|
||||||
func matchMethod(data []byte, methods []byte) bool {
|
func matchMethod(data []byte, methods []byte) bool {
|
||||||
if len(data) < len(methods) {
|
if len(data) < len(methods) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user