chore: add gmgn and remove entry contract
This commit is contained in:
@@ -22,43 +22,31 @@ const (
|
||||
|
||||
// program ids
|
||||
var (
|
||||
pumpProgramID = solana.MustPublicKeyFromBase58("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
||||
pumpProgramIDString = pumpProgramID.String()
|
||||
pumpProgramID = solana.MustPublicKeyFromBase58("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
||||
// has no sell function with pump and pump.amm program
|
||||
azczProgramID = solana.MustPublicKeyFromBase58("AzcZqCRUQgKEg5FTAgY7JacATABEYCEfMbjXEzspLYFB")
|
||||
azczProgramIDString = azczProgramID.String()
|
||||
azczProgramID = solana.MustPublicKeyFromBase58("AzcZqCRUQgKEg5FTAgY7JacATABEYCEfMbjXEzspLYFB")
|
||||
|
||||
// only buy function with pump program
|
||||
f5tfProgramID = solana.MustPublicKeyFromBase58("F5tfvbLog9VdGUPqBDTT8rgXvTTcq7e5UiGnupL1zvBq")
|
||||
f5tfProgramIDString = f5tfProgramID.String()
|
||||
f5tfProgramID = solana.MustPublicKeyFromBase58("F5tfvbLog9VdGUPqBDTT8rgXvTTcq7e5UiGnupL1zvBq")
|
||||
// only pump.fun function
|
||||
photonProgramID = solana.MustPublicKeyFromBase58("BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW")
|
||||
photonProgramIDString = photonProgramID.String()
|
||||
photonProgramID = solana.MustPublicKeyFromBase58("BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW")
|
||||
|
||||
pumpAmmProgramID = solana.MustPublicKeyFromBase58("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA")
|
||||
pumpAmmProgramIDString = pumpAmmProgramID.String()
|
||||
pumpAmmProgramID = solana.MustPublicKeyFromBase58("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA")
|
||||
|
||||
boboProgramID = solana.MustPublicKeyFromBase58("BobogA5N2KN2GG4XN3E3rNNRw3L8H1QPXp7QLxGrNHGM")
|
||||
boboProgramIDString = boboProgramID.String()
|
||||
boboProgramID = solana.MustPublicKeyFromBase58("BobogA5N2KN2GG4XN3E3rNNRw3L8H1QPXp7QLxGrNHGM")
|
||||
|
||||
qtkvProgramID = solana.MustPublicKeyFromBase58("qtkvapJEvRWWrB7i5K6RaA1kvq5x3qmMKZ98ad71XQ7")
|
||||
qtkvProgramIDString = qtkvProgramID.String()
|
||||
qtkvProgramID = solana.MustPublicKeyFromBase58("qtkvapJEvRWWrB7i5K6RaA1kvq5x3qmMKZ98ad71XQ7")
|
||||
|
||||
// only buy function with pump program
|
||||
fjszProgramID = solana.MustPublicKeyFromBase58("FJsZbftBqRLfF7uqUKpm4s2goDr6xsQ5Q3mN7AFJB6hK")
|
||||
fjszProgramIDString = fjszProgramID.String()
|
||||
fjszProgramID = solana.MustPublicKeyFromBase58("FJsZbftBqRLfF7uqUKpm4s2goDr6xsQ5Q3mN7AFJB6hK")
|
||||
|
||||
flasProgramID = solana.MustPublicKeyFromBase58("FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9")
|
||||
flasProgramIDString = flasProgramID.String()
|
||||
flasProgramID = solana.MustPublicKeyFromBase58("FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9")
|
||||
|
||||
terminalProgramID = solana.MustPublicKeyFromBase58("term9YPb9mzAsABaqN71A4xdbxHmpBNZavpBiQKZzN3")
|
||||
terminalProgramIDString = terminalProgramID.String()
|
||||
terminalProgramID = solana.MustPublicKeyFromBase58("term9YPb9mzAsABaqN71A4xdbxHmpBNZavpBiQKZzN3")
|
||||
|
||||
jupiterV6ProgramID = solana.MustPublicKeyFromBase58("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4")
|
||||
jupiterV6ProgramIDString = jupiterV6ProgramID.String()
|
||||
jupiterV6ProgramID = solana.MustPublicKeyFromBase58("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4")
|
||||
|
||||
gmgnProgramID = solana.MustPublicKeyFromBase58("GMgnVFR8Jb39LoXsEVzb3DvBy3ywCmdmJquHUy1Lrkqb")
|
||||
gmgnProgramIDString = gmgnProgramID.String()
|
||||
gmgnProgramID = solana.MustPublicKeyFromBase58("GMgnVFR8Jb39LoXsEVzb3DvBy3ywCmdmJquHUy1Lrkqb")
|
||||
)
|
||||
|
||||
type AccountNotFoundError struct {
|
||||
@@ -108,6 +96,8 @@ var (
|
||||
terminalBuyTokensIX = []byte{0xa6, 0x54, 0x14, 0x96, 0x9f, 0x77, 0x59, 0xca}
|
||||
terminalSellTokensIX = []byte{0xbe, 0x84, 0xa2, 0x96, 0x93, 0x7c, 0xf8, 0x6b}
|
||||
terminalAmmSellTokensIX = []byte{0x40, 0x64, 0x97, 0xb9, 0x16, 0xfa, 0xec, 0xb1}
|
||||
|
||||
gmgnBuyTokensIX = []byte{0x66, 0x06, 0x3d, 0x12, 0x01, 0xda, 0xeb, 0xea}
|
||||
)
|
||||
|
||||
type compiledInstruction struct {
|
||||
@@ -312,50 +302,53 @@ func ParseTransaction(update *SubscribeUpdateTransaction, loader *AddressTables,
|
||||
switch programID {
|
||||
case pumpProgramID:
|
||||
txRes, err := parsePumpInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "pump", pumpProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "pump")
|
||||
case azczProgramID:
|
||||
txRes, err := parseAzczInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "azcz", azczProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "azcz")
|
||||
case f5tfProgramID:
|
||||
txRes, err := parseF5tfInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "f5tf", f5tfProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "f5tf")
|
||||
case flasProgramID:
|
||||
txRes, err := parseFlasInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "flas", flasProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "flas")
|
||||
case photonProgramID:
|
||||
txRes, err := parsePhotonInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "photon", photonProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "photon")
|
||||
case pumpAmmProgramID:
|
||||
txRes, err := parsePumpAmmInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "pumpamm", pumpAmmProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "pumpamm")
|
||||
case boboProgramID:
|
||||
txRes, err := parseBoboInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "bobo", boboProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "bobo")
|
||||
case qtkvProgramID:
|
||||
txRes, err := parseQtkvInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "qtkv", qtkvProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "qtkv")
|
||||
case fjszProgramID:
|
||||
txRes, err := parseFjszInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "fjsz", fjszProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "fjsz")
|
||||
case terminalProgramID:
|
||||
txRes, err := parseTermInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "terminal", terminalProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "terminal")
|
||||
case jupiterV6ProgramID:
|
||||
txRes, err := parseJupiterV6Instruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "jupiterv6", jupiterV6ProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "jupiterv6")
|
||||
case okxDexRouteV2ProgramID:
|
||||
txRes, err := parseOkxDexRouteV2Instruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "okxdexroutev2", okxDexRouteV2ProgramIDString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "okxdexroutev2")
|
||||
case dflowProgramID:
|
||||
txRes, err := parseDFlowInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "dflow", dflowProgramString)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "dflow")
|
||||
case gmgnProgramID:
|
||||
txRes, err := parseGMGNInstruction(versioned, i)
|
||||
parsed = appendParsed(now, parsed, txRes, err, txHash, "gmgn")
|
||||
}
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
|
||||
func appendParsed(start time.Time, list []*TxSignal, parsed *TxSignal, err error, txHash [64]byte, label string, entryContract string) []*TxSignal {
|
||||
func appendParsed(start time.Time, list []*TxSignal, parsed *TxSignal, err error, txHash [64]byte, label string) []*TxSignal {
|
||||
if err != nil {
|
||||
if !strings.HasPrefix(err.Error(), "account index") {
|
||||
logger.Debug("txparser: failed to parse", "label", label, "instruction", err, "tx_hash", base58.Encode(txHash[:]))
|
||||
@@ -363,7 +356,6 @@ func appendParsed(start time.Time, list []*TxSignal, parsed *TxSignal, err error
|
||||
return list
|
||||
}
|
||||
if parsed != nil {
|
||||
parsed.EntryContract = entryContract
|
||||
parsed.Label = label
|
||||
if !start.IsZero() {
|
||||
parsed.ParseEnd = time.Now()
|
||||
@@ -1007,6 +999,66 @@ func parseFlasBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal, er
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseGMGNInstruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
||||
msg := tx.Message
|
||||
if instructionIndex >= len(msg.Instructions) {
|
||||
return nil, fmt.Errorf("instruction index out of bounds")
|
||||
}
|
||||
|
||||
instruction := msg.Instructions[instructionIndex]
|
||||
if len(instruction.Data) == 0 {
|
||||
return nil, fmt.Errorf("data is empty")
|
||||
}
|
||||
if len(instruction.Data) < 8 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if matchMethod(instruction.Data, gmgnBuyTokensIX) {
|
||||
return parseGMGNBuy(tx, &instruction)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func parseGMGNBuy(tx *versionedTransaction, instruction *compiledInstruction) (*TxSignal, error) {
|
||||
if len(instruction.Accounts) < 8 {
|
||||
return nil, fmt.Errorf("accounts too short")
|
||||
}
|
||||
if len(instruction.Data) < 24 {
|
||||
return nil, fmt.Errorf("data too short for gmgn buy args, len=%d", len(instruction.Data))
|
||||
}
|
||||
|
||||
staticKeys := tx.Message.StaticAccountKeys
|
||||
mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, err := getStaticKey(staticKeys, int(instruction.Accounts[6]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
solAmount := binary.LittleEndian.Uint64(instruction.Data[8:16])
|
||||
tokenAmount := binary.LittleEndian.Uint64(instruction.Data[16:24])
|
||||
|
||||
return &TxSignal{
|
||||
TxHash: tx.Signatures[0].String(),
|
||||
Label: "gmgn",
|
||||
Maker: user.String(),
|
||||
Token0Address: mint.String(),
|
||||
Token1Address: wsolMint,
|
||||
Token0Amount: formatTokenAmount(tokenAmount),
|
||||
Token1Amount: formatSolAmount(solAmount),
|
||||
Program: "Pump",
|
||||
Event: "buy",
|
||||
IsToken2022: false,
|
||||
IsMayhemMode: false,
|
||||
ExactSOL: true,
|
||||
Block: tx.Block,
|
||||
Token0AmountUint64: tokenAmount,
|
||||
Token1AmountUint64: solAmount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parsePhotonInstruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
||||
msg := tx.Message
|
||||
if instructionIndex >= len(msg.Instructions) {
|
||||
|
||||
Reference in New Issue
Block a user