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 TxIndex int InstrIdx uint8 InnerIdx uint8 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 Cashback bool UserBaseBalance decimal.Decimal UserQuoteBalance decimal.Decimal EntryContract solana.PublicKey MigrateToPool solana.PublicKey MigrateTopProgram solana.PublicKey LpMint solana.PublicKey AfterSOLBalance decimal.Decimal //For meteora dlmm StartBinId int32 EndBinId int32 BinChanges []DlmmBinLiquidityChange ConsumeUnit uint64 } type DlmmBinLiquidityChange struct { BinId int32 AmountX decimal.Decimal AmountY decimal.Decimal BpsToRemove uint16 } type platformInfo struct { Platform string PlatformFee decimal.Decimal } type mevInfo struct { MevAgent string MevAgentFee decimal.Decimal } type SolTransfer struct { From solana.PublicKey To solana.PublicKey Amount decimal.Decimal } type ChainLink struct { Timestamp int64 Price decimal.Decimal } type Tx struct { rawTx *RawTx Vote bool Signer solana.PublicKey Err *TransactionParsedError `json:"err,omitempty"` Swaps []Swap `json:"swaps,omitempty"` SolTransfer []SolTransfer `json:"sol_transfer,omitempty"` Block uint64 `json:"block"` ChainLink ChainLink `json:"chain_link"` BlockIndex uint64 `json:"index"` TxHash *[64]byte `json:"-"` BlockAt int64 `json:"block_at"` CuFee decimal.Decimal `json:"cu_fee"` 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"` // update tokenInfo Token map[solana.PublicKey]TokenMeta `gorm:"-"` ComputeUnitsConsumed uint64 `json:"compute_units_consumed"` CuLimit uint32 `json:"cu_limit"` // todo pool info ?? } func (tx *Tx) GetRawTx() *RawTx { return tx.rawTx } 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) } type TokenMeta struct { Mint solana.PublicKey `json:"address"` TokenProgram solana.PublicKey `json:"token_program"` Decimals uint8 `json:"decimals"` Name string Symbol string Url string TotalSupply *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) (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 } quoteAmount := swap.QuoteAmount if swap.BaseMint.Equals(solana.WrappedSol) { quoteAmount = swap.BaseAmount } if platform != "" && platform != PlatformFake && platformFee.LessThan(quoteAmount.Mul(decimal.NewFromInt(9)).Div(decimal.New(10000, 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 } func (tx *Tx) LoadAfterSOLBalance(swap Swap) decimal.Decimal { if swap.User.Equals(tx.Signer) { return tx.AfterSOLBalance } found := false makerIndex := 0 for i, account := range tx.rawTx.getAccountList() { if account == swap.User { found = true makerIndex = i break } } if found && makerIndex < len(tx.rawTx.Meta.PostBalances) { return decimal.NewFromInt( int64(tx.rawTx.Meta.PostBalances[makerIndex]), ).Div(decimal.NewFromInt(1000000000)) // sol decimals } return decimal.Zero } func (s Swap) CheckEntryContractV2() string { name, ok := entryContractAddresses[s.EntryContract] if ok { return name } return s.EntryContract.String() }