239 lines
5.3 KiB
Go
239 lines
5.3 KiB
Go
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
|
|
FeeAmount decimal.Decimal
|
|
LpFeeAmount decimal.Decimal
|
|
FeeSide string
|
|
FeeMint solana.PublicKey
|
|
FeeTokenProgram solana.PublicKey
|
|
FeeMintDecimals uint8
|
|
|
|
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
|
|
ActiveBinId int32
|
|
StartBinId int32
|
|
EndBinId int32
|
|
RemoveBp int32
|
|
PositionAccount solana.PublicKey
|
|
|
|
ConsumeUnit uint64
|
|
}
|
|
|
|
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()
|
|
}
|