pump buy_exact_sol_in parsered
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
parser "github.com/thloyi/pump-parser"
|
parser "github.com/thloyi/pump-parser"
|
||||||
example "github.com/thloyi/pump-parser/example"
|
example "github.com/thloyi/pump-parser/example"
|
||||||
"github.com/thloyi/pump-parser/example/geyser"
|
"github.com/thloyi/pump-parser/example/geyser"
|
||||||
@@ -21,7 +22,7 @@ func main() {
|
|||||||
ch := make(chan geyser.SubscriptionMessage, 1)
|
ch := make(chan geyser.SubscriptionMessage, 1)
|
||||||
go geyser.RunLoopWithReConnect(context.Background(), "127.0.0.1:10001", parser.SolProgramPump, ch)
|
go geyser.RunLoopWithReConnect(context.Background(), "127.0.0.1:10001", parser.SolProgramPump, ch)
|
||||||
// var tokenTxs = make(map[string]*types.Tx)
|
// var tokenTxs = make(map[string]*types.Tx)
|
||||||
currentBlock := uint64(0)
|
// currentBlock := uint64(0)
|
||||||
for msg := range ch {
|
for msg := range ch {
|
||||||
if msg.Tx == nil {
|
if msg.Tx == nil {
|
||||||
block := msg.Block
|
block := msg.Block
|
||||||
@@ -42,9 +43,9 @@ func main() {
|
|||||||
//if tx.Program != parser.SolProgramPump {
|
//if tx.Program != parser.SolProgramPump {
|
||||||
// continue
|
// continue
|
||||||
//}
|
//}
|
||||||
if currentBlock == ptx.Block {
|
//if currentBlock == ptx.Block {
|
||||||
continue
|
// continue
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 处理交易
|
// 处理交易
|
||||||
txErr, ok := ptx.Err.(*geyser.TransactionError)
|
txErr, ok := ptx.Err.(*geyser.TransactionError)
|
||||||
@@ -64,11 +65,14 @@ func main() {
|
|||||||
if tx.Program != parser.SolProgramPump {
|
if tx.Program != parser.SolProgramPump {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if tx.Token1Amount.GreaterThanOrEqual(decimal.NewFromFloat(0.1)) || tx.Event != "buy" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
printed = true
|
printed = true
|
||||||
fmt.Printf("t: %s, block: %d, hash: %s, signer: %s, program: %s, event: %s, token1: %s, cuPrice: %s, mevAgent: %s, mevFee: %s, platform: %s, platformFee: %s, entryContract: %s, mayhem: %t\n",
|
fmt.Printf("t: %s, block: %d, hash: %s, signer: %s, program: %s, event: %s, token1: %s, cuPrice: %s, mevAgent: %s, mevFee: %s, platform: %s, platformFee: %s, entryContract: %s, mayhem: %t\n",
|
||||||
time.Now().Format(time.RFC3339Nano),
|
time.Now().Format(time.RFC3339Nano),
|
||||||
tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token1Amount, tx.CUPrice, tx.MevAgent, tx.MevAgentFee, tx.Platform, tx.PlatformFee, tx.EntryContract, tx.Mayhem)
|
tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token1Amount, tx.CUPrice, tx.MevAgent, tx.MevAgentFee, tx.Platform, tx.PlatformFee, tx.EntryContract, tx.Mayhem)
|
||||||
break
|
//break
|
||||||
}
|
}
|
||||||
if !printed {
|
if !printed {
|
||||||
continue
|
continue
|
||||||
@@ -79,7 +83,7 @@ func main() {
|
|||||||
// tx.BeforeSolBalance, tx.AfterSOLBalance, tx.AfterSignerToken0Balance, tx.TokenCreator, tx.Token0Program, tx.Mayhem)
|
// tx.BeforeSolBalance, tx.AfterSOLBalance, tx.AfterSignerToken0Balance, tx.TokenCreator, tx.Token0Program, tx.Mayhem)
|
||||||
|
|
||||||
}
|
}
|
||||||
currentBlock = ptx.Block
|
// currentBlock = ptx.Block
|
||||||
//
|
//
|
||||||
//if tx.Event == "create" {
|
//if tx.Event == "create" {
|
||||||
// if err := pool.Submit(func() {
|
// if err := pool.Submit(func() {
|
||||||
|
|||||||
2
meta.go
2
meta.go
@@ -5,6 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var pumpProgram = solana.MustPublicKeyFromBase58("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
var pumpProgram = solana.MustPublicKeyFromBase58("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
||||||
|
var pumpFeesProgram = solana.MustPublicKeyFromBase58("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ")
|
||||||
var pumpMigrationAccount = solana.MustPublicKeyFromBase58("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg")
|
var pumpMigrationAccount = solana.MustPublicKeyFromBase58("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg")
|
||||||
var mayhemFeeAccounts = []solana.PublicKey{
|
var mayhemFeeAccounts = []solana.PublicKey{
|
||||||
solana.MustPublicKeyFromBase58("GesfTA3X2arioaHp8bbKdjG9vJtskViWACZoYvxp4twS"),
|
solana.MustPublicKeyFromBase58("GesfTA3X2arioaHp8bbKdjG9vJtskViWACZoYvxp4twS"),
|
||||||
@@ -17,6 +18,7 @@ var mayhemFeeAccounts = []solana.PublicKey{
|
|||||||
solana.MustPublicKeyFromBase58("6AUH3WEHucYZyC61hqpqYUWVto5qA5hjHuNQ32GNnNxA"),
|
solana.MustPublicKeyFromBase58("6AUH3WEHucYZyC61hqpqYUWVto5qA5hjHuNQ32GNnNxA"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pumpGetFeesDiscriminator = calculateDiscriminator("global:get_fees")
|
||||||
var pumpBuyDiscriminator = calculateDiscriminator("global:buy")
|
var pumpBuyDiscriminator = calculateDiscriminator("global:buy")
|
||||||
var pumpBuyV2Discriminator = calculateDiscriminator("global:buy_exact_sol_in")
|
var pumpBuyV2Discriminator = calculateDiscriminator("global:buy_exact_sol_in")
|
||||||
var pumpSellDiscriminator = calculateDiscriminator("global:sell")
|
var pumpSellDiscriminator = calculateDiscriminator("global:sell")
|
||||||
|
|||||||
34
pump.go
34
pump.go
@@ -174,6 +174,15 @@ type PumpTradeEvent struct {
|
|||||||
Fee uint64
|
Fee uint64
|
||||||
|
|
||||||
Creator solana.PublicKey
|
Creator solana.PublicKey
|
||||||
|
|
||||||
|
CreatorFeeBasisPoints uint64
|
||||||
|
CreatorFee uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type PumpTradeFeeArg struct {
|
||||||
|
IsPump bool
|
||||||
|
MarketCap [16]byte
|
||||||
|
TradeSize uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompleteEvent struct {
|
type CompleteEvent struct {
|
||||||
@@ -189,8 +198,16 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
var err error
|
var err error
|
||||||
var programIndex = instruction.ProgramIDIndex
|
var programIndex = instruction.ProgramIDIndex
|
||||||
|
|
||||||
|
feeEventProgramIndex := 0
|
||||||
|
for i, b := range result.accountList {
|
||||||
|
if b.Equals(pumpFeesProgram) {
|
||||||
|
feeEventProgramIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
tradeEvent PumpTradeEvent
|
tradeEvent PumpTradeEvent
|
||||||
|
tradeFeeArg PumpTradeFeeArg
|
||||||
completeEvent CompleteEvent
|
completeEvent CompleteEvent
|
||||||
completed bool
|
completed bool
|
||||||
newoffset [2]uint
|
newoffset [2]uint
|
||||||
@@ -203,6 +220,13 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
}
|
}
|
||||||
|
|
||||||
for innerIndex, innerInstr := range inners {
|
for innerIndex, innerInstr := range inners {
|
||||||
|
if innerInstr.ProgramIDIndex == feeEventProgramIndex && bytes.Equal(innerInstr.Data[:8], pumpGetFeesDiscriminator[:]) {
|
||||||
|
err = agbinary.NewBorshDecoder(innerInstr.Data[8:]).Decode(&tradeFeeArg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, increaseOffset(offset), fmt.Errorf("pump get fees event decode error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if innerInstr.ProgramIDIndex == programIndex && bytes.Equal(innerInstr.Data[:8], pumpEventDiscriminator[:]) {
|
if innerInstr.ProgramIDIndex == programIndex && bytes.Equal(innerInstr.Data[:8], pumpEventDiscriminator[:]) {
|
||||||
if bytes.Equal(innerInstr.Data[8:16], pumpTradeEventDiscriminator[8:16]) {
|
if bytes.Equal(innerInstr.Data[8:16], pumpTradeEventDiscriminator[8:16]) {
|
||||||
err = agbinary.NewBorshDecoder(innerInstr.Data[16:]).Decode(&tradeEvent)
|
err = agbinary.NewBorshDecoder(innerInstr.Data[16:]).Decode(&tradeEvent)
|
||||||
@@ -260,6 +284,14 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
Decimals: 6,
|
Decimals: 6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
solAmount := tradeEvent.SolAmount
|
||||||
|
if tradeEvent.IsBuy && bytes.Equal(instruction.Data[:8], pumpBuyV2Discriminator[:]) {
|
||||||
|
fee := tradeEvent.Fee + tradeEvent.CreatorFee
|
||||||
|
solAmount = tradeFeeArg.TradeSize
|
||||||
|
if solAmount > fee {
|
||||||
|
solAmount = solAmount - fee
|
||||||
|
}
|
||||||
|
}
|
||||||
swaps := []Swap{
|
swaps := []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPump,
|
Program: SolProgramPump,
|
||||||
@@ -274,7 +306,7 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
QuoteMintDecimals: 9,
|
QuoteMintDecimals: 9,
|
||||||
User: tradeEvent.User,
|
User: tradeEvent.User,
|
||||||
BaseAmount: decimal.NewFromUint64(tradeEvent.TokenAmount),
|
BaseAmount: decimal.NewFromUint64(tradeEvent.TokenAmount),
|
||||||
QuoteAmount: decimal.NewFromUint64(tradeEvent.SolAmount),
|
QuoteAmount: decimal.NewFromUint64(solAmount),
|
||||||
BaseReserve: decimal.NewFromUint64(tradeEvent.RealTokenReserves),
|
BaseReserve: decimal.NewFromUint64(tradeEvent.RealTokenReserves),
|
||||||
QuoteReserve: decimal.NewFromUint64(tradeEvent.RealSolReserves),
|
QuoteReserve: decimal.NewFromUint64(tradeEvent.RealSolReserves),
|
||||||
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[1]]),
|
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[1]]),
|
||||||
|
|||||||
26
pump_test.go
Normal file
26
pump_test.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package pump_parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
agbinary "github.com/gagliardetto/binary"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTradeEvent(t *testing.T) {
|
||||||
|
hexData := "e445a52e51cb9a1dbddb7fd34ee661ee051d1834b36cc6f04cc5bd998d53ab2a566a0ca2415bcfad5f9ed6941a851d3f84ecb200000000006c267d17170000000190d2c525ef0ea205f4b4abfdb6eaaf37fcb5a1b1dec2e2689448eecab6ba93b6c922246900000000c314f11a0d000000be71bf9e22080200c368cd1e06000000bed9ac52910901004ac2f8d0dd5cbc97e3289c197cb5062a54f3d956b9ce6e5115f96567aa5cb3e65f000000000000002c6a010000000000c9e17c171227a50a5b62e3a4a3f8ff4fafe0bca9c332bdf7f32eedbc4229604d1e000000000000005f72000000000000010000000000000000000000000000000000000000000000000000000000000000100000006275795f65786163745f736f6c5f696e"
|
||||||
|
d, err := hex.DecodeString(hexData)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to decode base64 data: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var tradeEvent PumpTradeEvent
|
||||||
|
|
||||||
|
err = agbinary.NewBorshDecoder(d[16:]).Decode(&tradeEvent)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to deserialize trade event: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Trade Event: %+v", tradeEvent)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -38,4 +38,5 @@ func TestDecodePoolData(t *testing.T) {
|
|||||||
|
|
||||||
func TestAmmBuyEvent(t *testing.T) {
|
func TestAmmBuyEvent(t *testing.T) {
|
||||||
fmt.Println(pumpAmmBuyEventDiscriminator)
|
fmt.Println(pumpAmmBuyEventDiscriminator)
|
||||||
|
fmt.Println(pumpGetFeesDiscriminator)
|
||||||
}
|
}
|
||||||
|
|||||||
3
tx.go
3
tx.go
@@ -1,8 +1,6 @@
|
|||||||
package pump_parser
|
package pump_parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gagliardetto/solana-go"
|
"github.com/gagliardetto/solana-go"
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
@@ -137,7 +135,6 @@ func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
|
|||||||
platform != PlatformFake {
|
platform != PlatformFake {
|
||||||
if (swap.QuoteMint.Equals(wSolMint) || swap.QuoteMint.IsZero()) &&
|
if (swap.QuoteMint.Equals(wSolMint) || swap.QuoteMint.IsZero()) &&
|
||||||
platformFee.LessThan(swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))).Div(decimal.NewFromInt(10000)).Mul(decimal.NewFromInt(9))) {
|
platformFee.LessThan(swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))).Div(decimal.NewFromInt(10000)).Mul(decimal.NewFromInt(9))) {
|
||||||
fmt.Printf("\n amount: %s, platform: %s, fee: %s \n", swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))), platform, platformFee.String())
|
|
||||||
platform = PlatformFake
|
platform = PlatformFake
|
||||||
} else if swap.BaseMint.Equals(wSolMint) &&
|
} else if swap.BaseMint.Equals(wSolMint) &&
|
||||||
platformFee.LessThan(swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))).Div(decimal.NewFromInt(10000)).Mul(decimal.NewFromInt(9))) {
|
platformFee.LessThan(swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))).Div(decimal.NewFromInt(10000)).Mul(decimal.NewFromInt(9))) {
|
||||||
|
|||||||
Reference in New Issue
Block a user