Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 32ba6da171 | |||
| 42631499c9 | |||
| 9a37e57473 | |||
|
|
e981df5f4b | ||
|
|
c20e019b43 | ||
|
|
c7be7cf4fd | ||
|
|
62c313d4a1 |
@@ -22,18 +22,8 @@ var SWQoSFeeAddresses = map[string]string{
|
|||||||
"Ey2JEr8hDkgN8qKJGrLf2yFjRhW7rab99HVxwi5rcvJE": enum.SWQoSAgent0slot,
|
"Ey2JEr8hDkgN8qKJGrLf2yFjRhW7rab99HVxwi5rcvJE": enum.SWQoSAgent0slot,
|
||||||
"4iUgjMT8q2hNZnLuhpqZ1QtiV8deFPy2ajvvjEpKKgsS": enum.SWQoSAgent0slot,
|
"4iUgjMT8q2hNZnLuhpqZ1QtiV8deFPy2ajvvjEpKKgsS": enum.SWQoSAgent0slot,
|
||||||
"3Rz8uD83QsU8wKvZbgWAPvCNDU6Fy8TSZTMcPm3RB6zt": enum.SWQoSAgent0slot,
|
"3Rz8uD83QsU8wKvZbgWAPvCNDU6Fy8TSZTMcPm3RB6zt": enum.SWQoSAgent0slot,
|
||||||
"DiTmWENJsHQdawVUUKnUXkconcpW4Jv52TnMWhkncF6t": enum.SWQoSAgent0slot,
|
|
||||||
"HRyRhQ86t3H4aAtgvHVpUJmw64BDrb61gRiKcdKUXs5c": enum.SWQoSAgent0slot,
|
|
||||||
"7y4whZmw388w1ggjToDLSBLv47drw5SUXcLk6jtmwixd": enum.SWQoSAgent0slot,
|
|
||||||
"J9BMEWFbCBEjtQ1fG5Lo9kouX1HfrKQxeUxetwXrifBw": enum.SWQoSAgent0slot,
|
|
||||||
"8U1JPQh3mVQ4F5jwRdFTBzvNRQaYFQppHQYoH38DJGSQ": enum.SWQoSAgent0slot,
|
|
||||||
"Eb2KpSC8uMt9GmzyAEm5Eb1AAAgTjRaXWFjKyFXHZxF3": enum.SWQoSAgent0slot,
|
|
||||||
"FCjUJZ1qozm1e8romw216qyfQMaaWKxWsuySnumVCCNe": enum.SWQoSAgent0slot,
|
|
||||||
"ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13": enum.SWQoSAgent0slot,
|
|
||||||
"6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK": enum.SWQoSAgent0slot,
|
|
||||||
"Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr": enum.SWQoSAgent0slot,
|
|
||||||
"HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY": enum.SWQoSAgentBlocxRoute,
|
"HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY": enum.SWQoSAgentBlocxRoute,
|
||||||
"HZTmLyC683y74TW3HtGbNX5orxjm2sPuZBEYwwSgAM8v": enum.SWQoSAgentBlocxRoute,
|
"95cfoy472fcQHaw4tPGBTKpn6ZQnfEPfBgDQx6gcRmRg": enum.SWQoSAgentBlocxRoute,
|
||||||
"FogxVNs6Mm2w9rnGL1vkARSwJxvLE8mujTv3LK8RnUhF": enum.SWQoSAgentBlocxRoute,
|
"FogxVNs6Mm2w9rnGL1vkARSwJxvLE8mujTv3LK8RnUhF": enum.SWQoSAgentBlocxRoute,
|
||||||
"3UQUKjhMKaY2S6bjcQD6yHB7utcZt5bfarRCmctpRtUd": enum.SWQoSAgentBlocxRoute,
|
"3UQUKjhMKaY2S6bjcQD6yHB7utcZt5bfarRCmctpRtUd": enum.SWQoSAgentBlocxRoute,
|
||||||
"TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq": enum.SWQoSAgentNozomi,
|
"TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq": enum.SWQoSAgentNozomi,
|
||||||
@@ -77,13 +67,6 @@ var SWQoSFeeAddresses = map[string]string{
|
|||||||
"node1PUber6SFmSQgvf2ECmXsHP5o3boRSGhvJyPMX1": enum.SWQoSAgentNode1,
|
"node1PUber6SFmSQgvf2ECmXsHP5o3boRSGhvJyPMX1": enum.SWQoSAgentNode1,
|
||||||
"node1AyMbeqiVN6eoQzEAwCA6Pk826hrdqdAHR7cdJ3": enum.SWQoSAgentNode1,
|
"node1AyMbeqiVN6eoQzEAwCA6Pk826hrdqdAHR7cdJ3": enum.SWQoSAgentNode1,
|
||||||
"node1YtWCoTwwVYTFLfS19zquRQzYX332hs1HEuRBjC": enum.SWQoSAgentNode1,
|
"node1YtWCoTwwVYTFLfS19zquRQzYX332hs1HEuRBjC": enum.SWQoSAgentNode1,
|
||||||
"node1EoLojAvoUmyDytcvgdXs6GPtY3zpQXPCRVncEA": enum.SWQoSAgentNode1,
|
|
||||||
"node1CVxtFas2Pw5Vcf86Pq89Hqx4jveo1ntY7ARFMK": enum.SWQoSAgentNode1,
|
|
||||||
"node1E3hguapYA18HCpEEkRHQmLNiyv9pdfE9s2zo5X": enum.SWQoSAgentNode1,
|
|
||||||
"node1zrVjcY2XB3Au8qYj5MxjbNfGu3baHaqZMkPM7Z": enum.SWQoSAgentNode1,
|
|
||||||
"node1FdMPnJBN7QTuhzNw3VS823nxFuDTizrrbcEqzp": enum.SWQoSAgentNode1,
|
|
||||||
"node1VwH169UqyJHr5MYCH3EBuwrdvn5KHXAkhEEfav": enum.SWQoSAgentNode1,
|
|
||||||
"node1L7Xat2tSkRNNi6TSuUScMYfj64ovhr2aceJm9g": enum.SWQoSAgentNode1,
|
|
||||||
"FLasHstqx11M8W56zrSEqkCyhMCCpr6ze6Mjdvqope5s": enum.SWQoSAgentFlashBlock,
|
"FLasHstqx11M8W56zrSEqkCyhMCCpr6ze6Mjdvqope5s": enum.SWQoSAgentFlashBlock,
|
||||||
"FLasHXTqrbNvpWFB6grN47HGZfK6pze9HLNTgbukfPSk": enum.SWQoSAgentFlashBlock,
|
"FLasHXTqrbNvpWFB6grN47HGZfK6pze9HLNTgbukfPSk": enum.SWQoSAgentFlashBlock,
|
||||||
"FLashhsorBmM9dLpuq6qATawcpqk1Y2aqaZfkd48iT3W": enum.SWQoSAgentFlashBlock,
|
"FLashhsorBmM9dLpuq6qATawcpqk1Y2aqaZfkd48iT3W": enum.SWQoSAgentFlashBlock,
|
||||||
@@ -108,6 +91,15 @@ var SWQoSFeeAddresses = map[string]string{
|
|||||||
"BnGKHAC386n4Qmv9xtpBVbRaUTKixjBe3oagkPFKtoy6": enum.SWQoSAgentBlockRazor,
|
"BnGKHAC386n4Qmv9xtpBVbRaUTKixjBe3oagkPFKtoy6": enum.SWQoSAgentBlockRazor,
|
||||||
"Dd7K2Fp7AtoN8xCghKDRmyqr5U169t48Tw5fEd3wT9mq": enum.SWQoSAgentBlockRazor,
|
"Dd7K2Fp7AtoN8xCghKDRmyqr5U169t48Tw5fEd3wT9mq": enum.SWQoSAgentBlockRazor,
|
||||||
"AP6qExwrbRgBAVaehg4b5xHENX815sMabtBzUzVB4v8S": enum.SWQoSAgentBlockRazor,
|
"AP6qExwrbRgBAVaehg4b5xHENX815sMabtBzUzVB4v8S": enum.SWQoSAgentBlockRazor,
|
||||||
|
"soyas4s6L8KWZ8rsSk1mF3d1mQScoTGGAgjk98bF8nP": enum.SWQoSAgentSoyas,
|
||||||
|
"soyascXFW5wEEYiwfEmHy2pNwomqzvggJosGVD6TJdY": enum.SWQoSAgentSoyas,
|
||||||
|
"soyasDBdKjADwPz3xk82U3TNPRDKEWJj7wWLajNHZ1L": enum.SWQoSAgentSoyas,
|
||||||
|
"soyasE2abjBAynmHbGWgEwk4ctBy7JMTUCNrMbjcnyH": enum.SWQoSAgentSoyas,
|
||||||
|
"ste11JV3MLMM7x7EJUM2sXcJC1H7F4jBLnP9a9PG8PH": enum.SWQoSAgentStellium,
|
||||||
|
"ste11MWPjXCRfQryCshzi86SGhuXjF4Lv6xMXD2AoSt": enum.SWQoSAgentStellium,
|
||||||
|
"ste11p5x8tJ53H1NbNQsRBg1YNRd4GcVpxtDw8PBpmb": enum.SWQoSAgentStellium,
|
||||||
|
"ste11p7e2KLYou5bwtt35H7BM6uMdo4pvioGjJXKFcN": enum.SWQoSAgentStellium,
|
||||||
|
"ste11TMV68LMi1BguM4RQujtbNCZvf1sjsASpqgAvSX": enum.SWQoSAgentStellium,
|
||||||
"astrazznxsGUhWShqgNtAdfrzP2G83DzcWVJDxwV9bF": enum.SWQoSAgentAstralane,
|
"astrazznxsGUhWShqgNtAdfrzP2G83DzcWVJDxwV9bF": enum.SWQoSAgentAstralane,
|
||||||
"astra4uejePWneqNaJKuFFA8oonqCE1sqF6b45kDMZm": enum.SWQoSAgentAstralane,
|
"astra4uejePWneqNaJKuFFA8oonqCE1sqF6b45kDMZm": enum.SWQoSAgentAstralane,
|
||||||
"astra9xWY93QyfG6yM8zwsKsRodscjQ2uU2HKNL5prk": enum.SWQoSAgentAstralane,
|
"astra9xWY93QyfG6yM8zwsKsRodscjQ2uU2HKNL5prk": enum.SWQoSAgentAstralane,
|
||||||
@@ -116,10 +108,12 @@ var SWQoSFeeAddresses = map[string]string{
|
|||||||
"astraubkDw81n4LuutzSQ8uzHCv4BhPVhfvTcYv8SKC": enum.SWQoSAgentAstralane,
|
"astraubkDw81n4LuutzSQ8uzHCv4BhPVhfvTcYv8SKC": enum.SWQoSAgentAstralane,
|
||||||
"astraZW5GLFefxNPAatceHhYjfA1ciq9gvfEg2S47xk": enum.SWQoSAgentAstralane,
|
"astraZW5GLFefxNPAatceHhYjfA1ciq9gvfEg2S47xk": enum.SWQoSAgentAstralane,
|
||||||
"astrawVNP4xDBKT7rAdxrLYiTSTdqtUr63fSMduivXK": enum.SWQoSAgentAstralane,
|
"astrawVNP4xDBKT7rAdxrLYiTSTdqtUr63fSMduivXK": enum.SWQoSAgentAstralane,
|
||||||
"ste11JV3MLMM7x7EJUM2sXcJC1H7F4jBLnP9a9PG8PH": enum.SWQoSAgentStellium,
|
"FAST3dMFZvESiEipBvLSiXq3QCV51o3xuoHScqRU6cB6": enum.SWQoSAgentFast,
|
||||||
"ste11MWPjXCRfQryCshzi86SGhuXjF4Lv6xMXD2AoSt": enum.SWQoSAgentStellium,
|
"FASTCKnwwY6iL3CknRgg3Zqir7jeagDDhxSnBQQy5a1C": enum.SWQoSAgentFast,
|
||||||
"ste11p5x8tJ53H1NbNQsRBg1YNRd4GcVpxtDw8PBpmb": enum.SWQoSAgentStellium,
|
"FASTHPW6akdGh9PFSdhMTbCuGkCSX7LsUjjnaB2RTQ4v": enum.SWQoSAgentFast,
|
||||||
"ste11p7e2KLYou5bwtt35H7BM6uMdo4pvioGjJXKFcN": enum.SWQoSAgentStellium,
|
"FASTKL1AamNKrwnvbKwo4PU8434BBdqVrTtugM6oDU71": enum.SWQoSAgentFast,
|
||||||
"ste11TMV68LMi1BguM4RQujtbNCZvf1sjsASpqgAvSX": enum.SWQoSAgentStellium,
|
"FASTPB76TxKPMZ7Q29m8v4zJn8gUjbWyvTEQaaxhwN7M": enum.SWQoSAgentFast,
|
||||||
"soyas4s6L8KWZ8rsSk1mF3d1mQScoTGGAgjk98bF8nP": enum.SWQoSAgentSoyas,
|
"FASTYKWXRfAoty7SQCM1mGVrmPUyyNcF4tc3DUkLDAu9": enum.SWQoSAgentFast,
|
||||||
|
"FASTYmSidNfLwdwiQEhCTtzghxEtaipeNSDSwh9xDPs3": enum.SWQoSAgentFast,
|
||||||
|
"FASTs6ctgbsuZegMzUs4DPUYhRSZUPCjgCVnttHbpQAp": enum.SWQoSAgentFast,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ const (
|
|||||||
Scorch
|
Scorch
|
||||||
VaultLiquidUnstake
|
VaultLiquidUnstake
|
||||||
XOrca
|
XOrca
|
||||||
|
Quantum
|
||||||
|
WhaleStreetV2
|
||||||
)
|
)
|
||||||
|
|
||||||
var swapKindNames = [122]string{"Saber", "SaberAddDecimalsDeposit", "SaberAddDecimalsWithdraw", "TokenSwap", "Sencha", "Step", "Cropper",
|
var swapKindNames = [122]string{"Saber", "SaberAddDecimalsDeposit", "SaberAddDecimalsWithdraw", "TokenSwap", "Sencha", "Step", "Cropper",
|
||||||
@@ -333,8 +335,20 @@ func decodeSwap(dec *bin.Decoder) (Swap, error) {
|
|||||||
case RaydiumLaunchlabBuy, RaydiumLaunchlabSell:
|
case RaydiumLaunchlabBuy, RaydiumLaunchlabSell:
|
||||||
return out, skipU64()
|
return out, skipU64()
|
||||||
// -------- Side(u8) payload --------
|
// -------- Side(u8) payload --------
|
||||||
case Serum, Aldrin, AldrinV2, Dradex, Openbook, Phoenix, OpenBookV2, TokenMill, Plasma, TesseraV, Futarchy, WhaleStreet, Manifest:
|
case Serum, Aldrin, AldrinV2, Dradex, Openbook, Phoenix, OpenBookV2, TokenMill, Plasma, TesseraV, Futarchy,
|
||||||
|
WhaleStreet, Manifest, Quantum:
|
||||||
return out, skipU8()
|
return out, skipU8()
|
||||||
|
case WhaleStreetV2:
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := skipU64(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := skipU64(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
// -------- MeteoraDlmmSwapV2: RemainingAccountsInfo --------
|
// -------- MeteoraDlmmSwapV2: RemainingAccountsInfo --------
|
||||||
case MeteoraDlmmSwapV2:
|
case MeteoraDlmmSwapV2:
|
||||||
return out, skipRemaining()
|
return out, skipRemaining()
|
||||||
|
|||||||
257
pkg/shreder/program_maestro.go
Normal file
257
pkg/shreder/program_maestro.go
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
package shreder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gagliardetto/solana-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
maestroProgramId = solana.MustPublicKeyFromBase58("MaestroAAe9ge5HTc64VbBQZ6fP77pwvrhM8i1XWSAx")
|
||||||
|
maestroMultiSwap2Discriminator = [8]byte{132, 9, 212, 45, 39, 113, 215, 54}
|
||||||
|
)
|
||||||
|
|
||||||
|
type MaestroMultiSwap2Route struct {
|
||||||
|
DexID uint8
|
||||||
|
RouteKeyIdx uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaestroMultiSwap2Args is the decoded payload of multi_swap2 instruction.
|
||||||
|
// Payload layout (without 8-byte discriminator):
|
||||||
|
// amount_in(u64), min_amount_out(u64), route0_weight(u16), route_len(u32),
|
||||||
|
// routes(route_len * {dex_id(u8), reserved(u8), route_key_idx(u8)}), route_family(u8), route_flags(u8)
|
||||||
|
type MaestroMultiSwap2Args struct {
|
||||||
|
HasDiscriminator bool
|
||||||
|
AmountIn uint64
|
||||||
|
MinAmountOut uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
RouteLen uint32
|
||||||
|
Routes []MaestroMultiSwap2Route
|
||||||
|
RouteFamily uint8
|
||||||
|
RouteFlags uint8
|
||||||
|
Extra []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeMaestroMultiSwap2Args decodes instruction bytes with or without the 8-byte multi_swap2 discriminator.
|
||||||
|
func decodeMaestroMultiSwap2Args(data []byte) (*MaestroMultiSwap2Args, error) {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil, fmt.Errorf("empty data")
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := data
|
||||||
|
out := &MaestroMultiSwap2Args{}
|
||||||
|
|
||||||
|
if len(data) >= len(maestroMultiSwap2Discriminator) && bytes.Equal(data[:8], maestroMultiSwap2Discriminator[:]) {
|
||||||
|
out.HasDiscriminator = true
|
||||||
|
payload = data[8:]
|
||||||
|
}
|
||||||
|
|
||||||
|
const minPayloadLen = 24 // fixed fields + route_family + route_flags when route_len==0
|
||||||
|
if len(payload) < minPayloadLen {
|
||||||
|
return nil, fmt.Errorf("payload too short: got %d, need at least %d", len(payload), minPayloadLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.AmountIn = binary.LittleEndian.Uint64(payload[0:8])
|
||||||
|
out.MinAmountOut = binary.LittleEndian.Uint64(payload[8:16])
|
||||||
|
out.SlippageBps = binary.LittleEndian.Uint16(payload[16:18])
|
||||||
|
out.RouteLen = binary.LittleEndian.Uint32(payload[18:22])
|
||||||
|
|
||||||
|
needed := uint64(minPayloadLen) + uint64(out.RouteLen)*3
|
||||||
|
if needed > uint64(len(payload)) {
|
||||||
|
return nil, fmt.Errorf("payload too short for routes: got %d, need %d (route_len=%d)", len(payload), needed, out.RouteLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := 22
|
||||||
|
out.Routes = make([]MaestroMultiSwap2Route, 0, out.RouteLen)
|
||||||
|
for i := uint32(0); i < out.RouteLen; i++ {
|
||||||
|
route := MaestroMultiSwap2Route{
|
||||||
|
DexID: payload[offset],
|
||||||
|
RouteKeyIdx: payload[offset+2],
|
||||||
|
}
|
||||||
|
out.Routes = append(out.Routes, route)
|
||||||
|
offset += 3
|
||||||
|
}
|
||||||
|
|
||||||
|
out.RouteFamily = payload[offset]
|
||||||
|
out.RouteFlags = payload[offset+1]
|
||||||
|
offset += 2
|
||||||
|
|
||||||
|
if len(payload) > offset {
|
||||||
|
out.Extra = append([]byte(nil), payload[offset:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// maestroMultiSwap2DexName maps observed dex ids from MultiSwap2 routes.
|
||||||
|
func maestroMultiSwap2DexName(dexID uint8) string {
|
||||||
|
switch dexID {
|
||||||
|
case 0:
|
||||||
|
return "RaydiumV4"
|
||||||
|
case 1:
|
||||||
|
return "MeteoraDLMM"
|
||||||
|
case 3:
|
||||||
|
return "RaydiumLaunchLab"
|
||||||
|
case 4:
|
||||||
|
return "PumpAMM"
|
||||||
|
case 5:
|
||||||
|
return "RaydiumCPMM"
|
||||||
|
case 6:
|
||||||
|
return "MeteoraAmmV2"
|
||||||
|
case 7:
|
||||||
|
return "RaydiumCLMM"
|
||||||
|
case 8:
|
||||||
|
return "OrcaWhirPool"
|
||||||
|
case 9:
|
||||||
|
return "MeteoraPools"
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
return "MeteoraDynamicBondingCurve"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Unknown(%d)", dexID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMaestroInstruction(tx VersionedTransaction, idx int) (TxSignalBatch, error) {
|
||||||
|
if idx >= len(tx.Instructions) {
|
||||||
|
return nil, fmt.Errorf("instruction index out of bounds")
|
||||||
|
}
|
||||||
|
ix := tx.Instructions[idx]
|
||||||
|
if len(ix.Data) < 8 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return parseMaestroInstructionDataAndAccounts(tx, ix.Data, ix.Accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMaestroInstructionDataAndAccounts(tx VersionedTransaction, ixData []byte, ixAccounts []uint8) (TxSignalBatch, error) {
|
||||||
|
args, err := decodeMaestroMultiSwap2Args(ixData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// only decode pump amm
|
||||||
|
if len(args.Routes) != 1 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.Routes[0].DexID != 4 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
event string
|
||||||
|
token0Amount uint64
|
||||||
|
token1Amount uint64
|
||||||
|
|
||||||
|
// pool solana.PublicKey
|
||||||
|
baseMint solana.PublicKey
|
||||||
|
quoteMint solana.PublicKey
|
||||||
|
)
|
||||||
|
|
||||||
|
routeFlag := args.Routes[0].RouteKeyIdx
|
||||||
|
if routeFlag == 101 || routeFlag == 97 {
|
||||||
|
event = "buy"
|
||||||
|
token0Amount = args.MinAmountOut
|
||||||
|
token1Amount = args.AmountIn
|
||||||
|
} else if routeFlag == 65 || routeFlag == 71 {
|
||||||
|
event = "sell"
|
||||||
|
token0Amount = args.AmountIn
|
||||||
|
token1Amount = args.MinAmountOut
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if routeFlag == 101 || routeFlag == 71 {
|
||||||
|
if len(ixAccounts) < 22 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
token2022, err := tx.GetAccount(int(ixAccounts[6]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !token2022.Equals(solana.Token2022ProgramID) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
//pool, err = tx.GetAccount(int(ixAccounts[10]))
|
||||||
|
if event == "buy" {
|
||||||
|
quoteMint, err = tx.GetAccount(int(ixAccounts[9]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
baseMint, err = tx.GetAccount(int(ixAccounts[21]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
baseMint, err = tx.GetAccount(int(ixAccounts[9]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
quoteMint, err = tx.GetAccount(int(ixAccounts[21]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if routeFlag == 97 || routeFlag == 65 {
|
||||||
|
if len(ixAccounts) < 21 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
tokenPro, err := tx.GetAccount(int(ixAccounts[5]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !tokenPro.Equals(solana.TokenProgramID) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
//pool, err = tx.GetAccount(int(ixAccounts[9]))
|
||||||
|
if event == "buy" {
|
||||||
|
quoteMint, err = tx.GetAccount(int(ixAccounts[8]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
baseMint, err = tx.GetAccount(int(ixAccounts[20]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
baseMint, err = tx.GetAccount(int(ixAccounts[8]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
quoteMint, err = tx.GetAccount(int(ixAccounts[20]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !quoteMint.Equals(wrappedSOL) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return TxSignalBatch{
|
||||||
|
&TxSignal{
|
||||||
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Maker: tx.StaticAccountKeys[0].String(),
|
||||||
|
Token0Address: baseMint.String(),
|
||||||
|
Token1Address: wsolMint,
|
||||||
|
Token0Amount: formatTokenAmount(token0Amount),
|
||||||
|
Token1Amount: formatTokenAmount(token1Amount),
|
||||||
|
Event: event,
|
||||||
|
Program: "PumpAMM",
|
||||||
|
IsProcessed: false,
|
||||||
|
IsToken2022: false,
|
||||||
|
IsMayhemMode: false,
|
||||||
|
ExactSOL: event == "buy",
|
||||||
|
Token0AmountUint64: token0Amount,
|
||||||
|
Token1AmountUint64: token1Amount,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ type TxSignal struct {
|
|||||||
CULimit uint32 `json:"cu_limit"`
|
CULimit uint32 `json:"cu_limit"`
|
||||||
SWQoSAgent string `json:"swqos_agent"`
|
SWQoSAgent string `json:"swqos_agent"`
|
||||||
SWQoSTips decimal.Decimal `json:"swqos_tips"`
|
SWQoSTips decimal.Decimal `json:"swqos_tips"`
|
||||||
|
TableCnt int `json:"table_cnt"`
|
||||||
|
|
||||||
ExactSOL bool `json:"exact_in"`
|
ExactSOL bool `json:"exact_in"`
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ var (
|
|||||||
dlmmProgramID: {parseDlmmInstruction, "dlmm"},
|
dlmmProgramID: {parseDlmmInstruction, "dlmm"},
|
||||||
dbotProgramID: {parseDbotInstruction, "dbot"},
|
dbotProgramID: {parseDbotInstruction, "dbot"},
|
||||||
tradewizProgramID: {parseTradewizInstruction, "tradewiz"},
|
tradewizProgramID: {parseTradewizInstruction, "tradewiz"},
|
||||||
|
maestroProgramId: {parseMaestroInstruction, "maestro"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -182,7 +183,8 @@ func ParseTransactionForEntries(ctx context.Context, slot uint64, entriesReader
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseTransactionWithHandler(ctx context.Context, versioned VersionedTransaction, loader *AddressTables, parsed chan<- TxSignal, handlers map[solana.PublicKey]Handler) {
|
func ParseTransactionWithHandler(ctx context.Context, versioned VersionedTransaction, loader *AddressTables, parsed chan<- TxSignal, handlers map[solana.PublicKey]Handler) {
|
||||||
if loader != nil && len(versioned.AddressTableLookups) > 0 {
|
tableCnt := len(versioned.AddressTableLookups)
|
||||||
|
if loader != nil && tableCnt > 0 {
|
||||||
lookupTableOk := true
|
lookupTableOk := true
|
||||||
for _, lookups := range versioned.AddressTableLookups {
|
for _, lookups := range versioned.AddressTableLookups {
|
||||||
lookupTableOk = loader.FillToTx(&versioned, lookups.AccountKey, lookups.WritableIndexes)
|
lookupTableOk = loader.FillToTx(&versioned, lookups.AccountKey, lookups.WritableIndexes)
|
||||||
@@ -214,7 +216,7 @@ func ParseTransactionWithHandler(ctx context.Context, versioned VersionedTransac
|
|||||||
cuPriceUint64 := binary.LittleEndian.Uint64(instruction.Data[1:9])
|
cuPriceUint64 := binary.LittleEndian.Uint64(instruction.Data[1:9])
|
||||||
cuPrice = formatCUPrice(cuPriceUint64)
|
cuPrice = formatCUPrice(cuPriceUint64)
|
||||||
} else if len(instruction.Data) == 5 && instruction.Data[0] == 0x02 {
|
} else if len(instruction.Data) == 5 && instruction.Data[0] == 0x02 {
|
||||||
cuLimit = binary.LittleEndian.Uint32(instruction.Data[1:4])
|
cuLimit = binary.LittleEndian.Uint32(instruction.Data[1:5])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if program.Equals(solana.SystemProgramID) &&
|
if program.Equals(solana.SystemProgramID) &&
|
||||||
@@ -266,6 +268,7 @@ func ParseTransactionWithHandler(ctx context.Context, versioned VersionedTransac
|
|||||||
one.CULimit = cuLimit
|
one.CULimit = cuLimit
|
||||||
one.SWQoSAgent = swqosAgent
|
one.SWQoSAgent = swqosAgent
|
||||||
one.SWQoSTips = swqosTips
|
one.SWQoSTips = swqosTips
|
||||||
|
one.TableCnt = tableCnt
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user