Files
pump-parser/tx.go

198 lines
4.5 KiB
Go
Raw Normal View History

2025-11-20 17:56:45 +08:00
package pump_parser
import (
"github.com/gagliardetto/solana-go"
"github.com/mr-tron/base58"
"github.com/shopspring/decimal"
)
type Swap struct {
Program string
Event string
Pool solana.PublicKey
BaseMint solana.PublicKey
QuoteMint solana.PublicKey
BaseTokenProgram solana.PublicKey
QuoteTokenProgram solana.PublicKey
Creator solana.PublicKey
BaseMintDecimals uint8
QuoteMintDecimals uint8
User solana.PublicKey
BaseAmount decimal.Decimal
QuoteAmount decimal.Decimal
BaseReserve decimal.Decimal
QuoteReserve decimal.Decimal
Mayhem bool
UserBaseBalance decimal.Decimal
UserQuoteBalance decimal.Decimal
EntryContract solana.PublicKey
//For meteora dlmm
StartBinId int32
EndBinId int32
2025-11-20 17:56:45 +08:00
}
type platformInfo struct {
Platform string
PlatformFee decimal.Decimal
}
type mevInfo struct {
MevAgent string
MevAgentFee decimal.Decimal
}
2026-01-05 11:46:54 +08:00
type SolTransfer struct {
From solana.PublicKey
To solana.PublicKey
Amount decimal.Decimal
}
2025-11-20 17:56:45 +08:00
type Tx struct {
2026-01-05 11:46:54 +08:00
rawTx *RawTx
Signer solana.PublicKey
Err interface{} `json:"err,omitempty"`
Swaps []Swap `json:"swaps,omitempty"`
SolTransfer []SolTransfer `json:"sol_transfer,omitempty"`
Block uint64 `json:"block"`
BlockIndex uint64 `json:"index"`
TxHash *[64]byte `json:"-"`
BlockAt int64 `json:"block_at"`
CuFee decimal.Decimal `json:"cu_fee"`
2025-11-20 17:56:45 +08:00
cachedTxHash string
Platform map[string]platformInfo `json:"platform"`
MevAgent map[string]mevInfo ` json:"tx_mev_agent"`
CUPrice decimal.Decimal ` json:"tx_cu_price"`
BeforeSolBalance decimal.Decimal `json:"-"`
AfterSOLBalance decimal.Decimal `json:"after_sol_balance"`
2025-11-21 12:01:44 +08:00
// update tokenInfo
Token map[solana.PublicKey]TokenMeta `gorm:"-"`
// todo pool info ??
}
func (tx *Tx) SetRawTx(t *RawTx) {
tx.rawTx = t
}
func (tx *Tx) GetSignerTokenBalanceAfterTx(tokenProgram, tokenMint solana.PublicKey) decimal.Decimal {
return GetTokenBalanceAfterTx(tx.rawTx, 0, tokenProgram, tokenMint)
2025-11-20 17:56:45 +08:00
}
type TokenMeta struct {
2025-11-21 12:01:44 +08:00
Mint solana.PublicKey `json:"address"`
2025-11-20 17:56:45 +08:00
TokenProgram solana.PublicKey `json:"token_program"`
2025-11-21 12:01:44 +08:00
Decimals uint8 `json:"decimals"`
2025-11-20 17:56:45 +08:00
2025-11-21 12:01:44 +08:00
Name string
Symbol string
Url string
2025-11-20 17:56:45 +08:00
2025-11-21 12:01:44 +08:00
TotalSupply *decimal.Decimal
2025-11-20 17:56:45 +08:00
}
func (tx *Tx) GetTxHash() string {
if tx.cachedTxHash != "" {
return tx.cachedTxHash
}
if tx.TxHash == nil {
return ""
}
tx.cachedTxHash = base58.Encode(tx.TxHash[:])
return tx.cachedTxHash
}
2025-11-21 12:01:44 +08:00
func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
2025-11-20 17:56:45 +08:00
// hasSolProgramRaydiumLaunchLabBonk
2025-11-21 12:01:44 +08:00
rawTx := tx.rawTx
2025-11-20 17:56:45 +08:00
var platform string
var platformFee decimal.Decimal
if len(tx.Platform) == 0 {
return PlatformNone, decimal.Zero
}
for p, info := range tx.Platform {
platform = p
platformFee = info.PlatformFee
break
}
if swap.Event == "buy" && swap.Program == SolProgramRaydiumLaunchLabBonk {
for _, p := range tx.Platform {
switch p.Platform {
case PlatformAxiom:
if !checkBonkAxiomBuy(rawTx) {
platform = PlatformFake
}
case PlatformGMGN:
if !checkBonkGmgnBuy(rawTx) {
platform = PlatformFake
}
}
}
}
if platform != "" &&
platform != PlatformFake {
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))) {
platform = PlatformFake
} 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))) {
platform = PlatformFake
}
}
if platform == "" {
platform = PlatformNone
}
return platform, platformFee
}
func (tx *Tx) CheckMevAgent() (string, decimal.Decimal) {
var mevAgent = MevAgentUnknown
var mevAgentFee = decimal.Zero
for m, info := range tx.MevAgent {
if len(tx.MevAgent) > 1 && info.MevAgent == MevAgentUnknown {
continue
}
mevAgent = m
mevAgentFee = info.MevAgentFee
break
}
if len(tx.MevAgent) == 0 && mevAgent == MevAgentUnknown {
// set the mev agent to none if the platform does not exist
return "", decimal.Zero
}
return mevAgent, mevAgentFee
}
func (s Swap) CheckEntryContract() string {
name, ok := entryContractAddresses[s.EntryContract]
if ok {
return name
}
return EntryContractUnknown
}
2025-12-31 16:53:39 +08:00
func (s Swap) CheckEntryContractV2() string {
name, ok := entryContractAddresses[s.EntryContract]
if ok {
return name
}
return s.EntryContract.String()
}