168 lines
3.9 KiB
Go
168 lines
3.9 KiB
Go
|
|
package pump_parser
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"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
|
||
|
|
}
|
||
|
|
|
||
|
|
type platformInfo struct {
|
||
|
|
Platform string
|
||
|
|
PlatformFee decimal.Decimal
|
||
|
|
}
|
||
|
|
|
||
|
|
type mevInfo struct {
|
||
|
|
MevAgent string
|
||
|
|
MevAgentFee decimal.Decimal
|
||
|
|
}
|
||
|
|
|
||
|
|
type Tx struct {
|
||
|
|
Signer solana.PublicKey
|
||
|
|
Err interface{} `json:"err,omitempty"`
|
||
|
|
Swaps []Swap `json:"swaps,omitempty"`
|
||
|
|
Block uint64 `json:"block"`
|
||
|
|
BlockIndex uint64 `json:"index"`
|
||
|
|
TxHash *[64]byte `json:"-"`
|
||
|
|
BlockAt int64 `json:"block_at"`
|
||
|
|
|
||
|
|
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"`
|
||
|
|
|
||
|
|
Token []TokenMeta `gorm:"-"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type TokenMeta struct {
|
||
|
|
Address solana.PublicKey `json:"address"`
|
||
|
|
TokenProgram solana.PublicKey `json:"token_program"`
|
||
|
|
|
||
|
|
Name string
|
||
|
|
Symbol string
|
||
|
|
Decimal uint8
|
||
|
|
Url string
|
||
|
|
|
||
|
|
TotalSupply *decimal.Decimal
|
||
|
|
SignerBalance *decimal.Decimal
|
||
|
|
}
|
||
|
|
|
||
|
|
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
|
||
|
|
}
|
||
|
|
|
||
|
|
func (tx *Tx) CheckPlatform(swap Swap, rawTx *RawTx) (string, decimal.Decimal) {
|
||
|
|
// hasSolProgramRaydiumLaunchLabBonk
|
||
|
|
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))) {
|
||
|
|
fmt.Printf("\n amount: %s, platform: %s, fee: %s \n", swap.QuoteAmount.Div(decimal.New(1, int32(swap.QuoteMintDecimals))), platform, platformFee.String())
|
||
|
|
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
|
||
|
|
}
|