Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e68907e9c7 | ||
|
|
8128a325a9 | ||
|
|
dd76b04b19 | ||
| 91b70e23d6 | |||
|
|
dbfaa39432 | ||
|
|
78d323efd5 | ||
|
|
d22347ce8d | ||
|
|
9898554bf8 | ||
|
|
b44c7372d5 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/.idea
|
||||||
54
consts.go
54
consts.go
@@ -4,6 +4,13 @@ import "github.com/gagliardetto/solana-go"
|
|||||||
|
|
||||||
var platformFeeAddresses = map[solana.PublicKey]string{
|
var platformFeeAddresses = map[solana.PublicKey]string{
|
||||||
solana.MustPublicKeyFromBase58("BB5dnY55FXS1e1NXqZDwCzgdYJdMCj3B92PU6Q5Fb6DT"): PlatformGMGN,
|
solana.MustPublicKeyFromBase58("BB5dnY55FXS1e1NXqZDwCzgdYJdMCj3B92PU6Q5Fb6DT"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("7sHXjs1j7sDJGVSMSPjD1b4v3FD6uRSvRWfhRdfv5BiA"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("ByRRgnZenY6W2sddo1VJzX9o4sMU4gPDUkcmgrpGBxRy"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("DXfkEGoo6WFsdL7x6gLZ7r6Hw2S6HrtrAQVPWYx2A1s9"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("3t9EKmRiAUcQUYzTZpNojzeGP1KBAVEEbDNmy6wECQpK"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("DymeoWc5WLNiQBaoLuxrxDnDRvLgGZ1QGsEoCAM7Jsrx"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("dBhdrmwBkRa66XxBuAK4WZeZnsZ6bHeHCCLXa3a8bTJ"): PlatformGMGN,
|
||||||
|
solana.MustPublicKeyFromBase58("6TxjC5wJzuuZgTtnTMipwwULEbMPx5JPW3QwWkdTGnrn"): PlatformGMGN,
|
||||||
solana.MustPublicKeyFromBase58("AVUCZyuT35YSuj4RH7fwiyPu82Djn2Hfg7y2ND2XcnZH"): PlatformPhoton,
|
solana.MustPublicKeyFromBase58("AVUCZyuT35YSuj4RH7fwiyPu82Djn2Hfg7y2ND2XcnZH"): PlatformPhoton,
|
||||||
solana.MustPublicKeyFromBase58("7LCZckF6XXGQ1hDY6HFXBKWAtiUgL9QY5vj1C4Bn1Qjj"): PlatformAxiom,
|
solana.MustPublicKeyFromBase58("7LCZckF6XXGQ1hDY6HFXBKWAtiUgL9QY5vj1C4Bn1Qjj"): PlatformAxiom,
|
||||||
solana.MustPublicKeyFromBase58("4V65jvcDG9DSQioUVqVPiUcUY9v6sb6HKtMnsxSKEz5S"): PlatformAxiom,
|
solana.MustPublicKeyFromBase58("4V65jvcDG9DSQioUVqVPiUcUY9v6sb6HKtMnsxSKEz5S"): PlatformAxiom,
|
||||||
@@ -40,6 +47,7 @@ var platformFeeAddresses = map[solana.PublicKey]string{
|
|||||||
solana.MustPublicKeyFromBase58("5wkyL2FLEcyUUgc3UeGntHTAfWfzDrVuxMnaMm7792Gk"): PlatformMoonshotMoney,
|
solana.MustPublicKeyFromBase58("5wkyL2FLEcyUUgc3UeGntHTAfWfzDrVuxMnaMm7792Gk"): PlatformMoonshotMoney,
|
||||||
solana.MustPublicKeyFromBase58("MaestroUL88UBnZr3wfoN7hqmNWFi3ZYCGqZoJJHE36"): PlatformMaestro,
|
solana.MustPublicKeyFromBase58("MaestroUL88UBnZr3wfoN7hqmNWFi3ZYCGqZoJJHE36"): PlatformMaestro,
|
||||||
solana.MustPublicKeyFromBase58("ZG98FUCjb8mJ824Gbs6RsgVmr1FhXb2oNiJHa2dwmPd"): PlatformBonkBot,
|
solana.MustPublicKeyFromBase58("ZG98FUCjb8mJ824Gbs6RsgVmr1FhXb2oNiJHa2dwmPd"): PlatformBonkBot,
|
||||||
|
solana.MustPublicKeyFromBase58("J5XGHmzrRmnYWbmw45DbYkdZAU2bwERFZ11qCDXPvFB5"): PlatformPadre,
|
||||||
}
|
}
|
||||||
|
|
||||||
var mevAgentFeeAddresses = map[solana.PublicKey]string{
|
var mevAgentFeeAddresses = map[solana.PublicKey]string{
|
||||||
@@ -72,6 +80,15 @@ var mevAgentFeeAddresses = map[solana.PublicKey]string{
|
|||||||
solana.MustPublicKeyFromBase58("ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13"): MevAgent0slot,
|
solana.MustPublicKeyFromBase58("ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13"): MevAgent0slot,
|
||||||
solana.MustPublicKeyFromBase58("6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK"): MevAgent0slot,
|
solana.MustPublicKeyFromBase58("6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK"): MevAgent0slot,
|
||||||
solana.MustPublicKeyFromBase58("Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr"): MevAgent0slot,
|
solana.MustPublicKeyFromBase58("Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axm2JQY1FKEktAwgXWqjGYkkWsWPfwKzgbnGVt5kiP4"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axm3PjbgwVrF6rnY2xLRMmWmLdDQGKfUYTEDtZ1haz7"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmD4LFJopAcbRKCKsrrmovCZZzmKQCMEfs5qEXj8dG"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmFmfqQwZGEUZeF3i3MqbRCDiGPfshtbdoBjk41k88"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmMdWvgEnN3NFrxMfTqUURzj9NLhZL2DkHkWCdgiFV"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmQTWU68qZ4fuG7zzkCXCBmxxeHVZrNrLkgxEFCbRv"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmWxBPqgRmcBN2cV12quqaQzsk16SazVXq8397KFKu"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmYVq9b1ABYqtyizMtyfJppPTPxZGXPLctB3hV6W5b"): MevAgent0slot,
|
||||||
|
solana.MustPublicKeyFromBase58("axmhpocX3hU7nT7KtsLBzNBR1Ur3HtU22Q5P313FREY"): MevAgent0slot,
|
||||||
solana.MustPublicKeyFromBase58("HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY"): MevAgentBlocxRoute,
|
solana.MustPublicKeyFromBase58("HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY"): MevAgentBlocxRoute,
|
||||||
solana.MustPublicKeyFromBase58("7ks326H4LbMVaUC8nW5FpC5EoAf5eK5pf4Dsx4HDQLpq"): MevAgentBlocxRoute,
|
solana.MustPublicKeyFromBase58("7ks326H4LbMVaUC8nW5FpC5EoAf5eK5pf4Dsx4HDQLpq"): MevAgentBlocxRoute,
|
||||||
solana.MustPublicKeyFromBase58("95cfoy472fcQHaw4tPGBTKpn6ZQnfEPfBgDQx6gcRmRg"): MevAgentBlocxRoute,
|
solana.MustPublicKeyFromBase58("95cfoy472fcQHaw4tPGBTKpn6ZQnfEPfBgDQx6gcRmRg"): MevAgentBlocxRoute,
|
||||||
@@ -144,6 +161,33 @@ var mevAgentFeeAddresses = map[solana.PublicKey]string{
|
|||||||
solana.MustPublicKeyFromBase58("BnGKHAC386n4Qmv9xtpBVbRaUTKixjBe3oagkPFKtoy6"): MevAgentBlockRazor,
|
solana.MustPublicKeyFromBase58("BnGKHAC386n4Qmv9xtpBVbRaUTKixjBe3oagkPFKtoy6"): MevAgentBlockRazor,
|
||||||
solana.MustPublicKeyFromBase58("Dd7K2Fp7AtoN8xCghKDRmyqr5U169t48Tw5fEd3wT9mq"): MevAgentBlockRazor,
|
solana.MustPublicKeyFromBase58("Dd7K2Fp7AtoN8xCghKDRmyqr5U169t48Tw5fEd3wT9mq"): MevAgentBlockRazor,
|
||||||
solana.MustPublicKeyFromBase58("AP6qExwrbRgBAVaehg4b5xHENX815sMabtBzUzVB4v8S"): MevAgentBlockRazor,
|
solana.MustPublicKeyFromBase58("AP6qExwrbRgBAVaehg4b5xHENX815sMabtBzUzVB4v8S"): MevAgentBlockRazor,
|
||||||
|
solana.MustPublicKeyFromBase58("soyas4s6L8KWZ8rsSk1mF3d1mQScoTGGAgjk98bF8nP"): MevAgentSoyas,
|
||||||
|
solana.MustPublicKeyFromBase58("soyascXFW5wEEYiwfEmHy2pNwomqzvggJosGVD6TJdY"): MevAgentSoyas,
|
||||||
|
solana.MustPublicKeyFromBase58("soyasDBdKjADwPz3xk82U3TNPRDKEWJj7wWLajNHZ1L"): MevAgentSoyas,
|
||||||
|
solana.MustPublicKeyFromBase58("soyasE2abjBAynmHbGWgEwk4ctBy7JMTUCNrMbjcnyH"): MevAgentSoyas,
|
||||||
|
solana.MustPublicKeyFromBase58("ste11JV3MLMM7x7EJUM2sXcJC1H7F4jBLnP9a9PG8PH"): MevAgentStellium,
|
||||||
|
solana.MustPublicKeyFromBase58("ste11MWPjXCRfQryCshzi86SGhuXjF4Lv6xMXD2AoSt"): MevAgentStellium,
|
||||||
|
solana.MustPublicKeyFromBase58("ste11p5x8tJ53H1NbNQsRBg1YNRd4GcVpxtDw8PBpmb"): MevAgentStellium,
|
||||||
|
solana.MustPublicKeyFromBase58("ste11p7e2KLYou5bwtt35H7BM6uMdo4pvioGjJXKFcN"): MevAgentStellium,
|
||||||
|
solana.MustPublicKeyFromBase58("ste11TMV68LMi1BguM4RQujtbNCZvf1sjsASpqgAvSX"): MevAgentStellium,
|
||||||
|
solana.MustPublicKeyFromBase58("astra4uejePWneqNaJKuFFA8oonqCE1sqF6b45kDMZm"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("astra9xWY93QyfG6yM8zwsKsRodscjQ2uU2HKNL5prk"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("astraRVUuTHjpwEVvNBeQEgwYx9w9CFyfxjYoobCZhL"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("astrazznxsGUhWShqgNtAdfrzP2G83DzcWVJDxwV9bF"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("ASde6y8pBCU1aityWHRpqT7pEAcEonjCgFUMeh5egRes"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("ASUv6G8Cj6zt71UAqD1aVtDC3CRn6FFddqF17ZiegrES"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("ASY4mvCtrACKFK8Jiuvqcu8fad9gGTzvfm5zp4megRes"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("astraEJ2fEj8Xmy6KLG7B3VfbKfsHXhHrNdCQx7iGJK"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1ooMsWjc4SUVVuLyCu1ig2RdomQnHKgMzBMfmSo3DK"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1ooMZfUJmAvppzc5cr7eYG8Cenig4FbQGBytr4DGCh"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("b1ooMDLjzz4QqecNsJ8bBXzJTzfAPDCP3CxijTS2K93"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("b1oomst2baE3FqxFPHaA9JwhXgFG9HdTLmbNKDen1kK"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("b1ooMngj7WbNPMZpWpnYRjxQ96RcDZ9ZFpRfjw1g7tg"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1oomgV9SAeiUc7GMEg9WhqkZJGccJuHAnh15DbezcN"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("b1oom3jaRNoyJzvSdSVbvSbth5uB4rRYtbjHXT5c1eW"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1ooMauwuJPhHsXqt3uj7B92CAFG8kaD1Q2iGEmGYnx"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1ooMdjcY7zemxDWiH8jVZPxEMdHnE5AraWPHdHQoPj"): MevAgentAstralane,
|
||||||
|
solana.MustPublicKeyFromBase58("B1ooMKzu6siJzQutP6a6oLiY3fpzgQnBZsAjxuAm9qo"): MevAgentAstralane,
|
||||||
}
|
}
|
||||||
|
|
||||||
var entryContractAddresses = map[solana.PublicKey]string{
|
var entryContractAddresses = map[solana.PublicKey]string{
|
||||||
@@ -177,4 +221,14 @@ var entryContractAddresses = map[solana.PublicKey]string{
|
|||||||
solana.MustPublicKeyFromBase58("NoVA1TmDUqksaj2hB1nayFkPysjJbFiU76dT4qPw2wm"): EntryContractNovaBotsProgram,
|
solana.MustPublicKeyFromBase58("NoVA1TmDUqksaj2hB1nayFkPysjJbFiU76dT4qPw2wm"): EntryContractNovaBotsProgram,
|
||||||
solana.MustPublicKeyFromBase58("E6YoRP3adE5XYneSseLee15wJshDxCsmyD2WtLvAmfLi"): EntryContractTaggedSearcher,
|
solana.MustPublicKeyFromBase58("E6YoRP3adE5XYneSseLee15wJshDxCsmyD2WtLvAmfLi"): EntryContractTaggedSearcher,
|
||||||
solana.MustPublicKeyFromBase58("MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e"): EntryContractMayhem,
|
solana.MustPublicKeyFromBase58("MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e"): EntryContractMayhem,
|
||||||
|
solana.MustPublicKeyFromBase58("proVF4pMXVaYqmy4NjniPh4pqKNfMmsihgd4wdkCX3u"): EntryContractOKXDexRouterV2,
|
||||||
|
solana.MustPublicKeyFromBase58("term9YPb9mzAsABaqN71A4xdbxHmpBNZavpBiQKZzN3"): EntryContractTerm,
|
||||||
|
solana.MustPublicKeyFromBase58("DF1ow4tspfHX9JwWJsAb9epbkA8hmpSEAtxXy1V27QBH"): EntryContractDFlow,
|
||||||
|
solana.MustPublicKeyFromBase58("MaestroAAe9ge5HTc64VbBQZ6fP77pwvrhM8i1XWSAx"): EntryContractMaestroBot,
|
||||||
|
solana.MustPublicKeyFromBase58("BBRouter1cVunVXvkcqeKkZQcBK7ruan37PPm3xzWaXD"): EntryContractBonkBot,
|
||||||
|
solana.MustPublicKeyFromBase58("B3111yJCeHBcA1bizdJjUFPALfhAfSRnAbJzGUtnt56A"): EntryContractBinanceWallet,
|
||||||
|
solana.MustPublicKeyFromBase58("FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9"): EntryContractAxiom,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var okxDexRoutersV2 = solana.MustPublicKeyFromBase58("proVF4pMXVaYqmy4NjniPh4pqKNfMmsihgd4wdkCX3u")
|
||||||
|
var okxAggregatorV2 = solana.MustPublicKeyFromBase58("6m2CDdhRgxpH4WjvdzxAYbGxwdGUz5MziiL5jek2kBma")
|
||||||
|
|||||||
10
enum.go
10
enum.go
@@ -11,6 +11,9 @@ const (
|
|||||||
MevAgentFlashBlock = "flashBlock"
|
MevAgentFlashBlock = "flashBlock"
|
||||||
MevAgentUnknown = "unknown"
|
MevAgentUnknown = "unknown"
|
||||||
MevAgentBlockRazor = "blockrazor"
|
MevAgentBlockRazor = "blockrazor"
|
||||||
|
MevAgentSoyas = "soyas"
|
||||||
|
MevAgentStellium = "stellium"
|
||||||
|
MevAgentAstralane = "astralane"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -38,10 +41,16 @@ const (
|
|||||||
EntryContractNumeraire = "numeraire"
|
EntryContractNumeraire = "numeraire"
|
||||||
EntryContractBloomRouter = "bloomRouter"
|
EntryContractBloomRouter = "bloomRouter"
|
||||||
EntryContractOKXAggregatorV2 = "oKXAggregatorV2"
|
EntryContractOKXAggregatorV2 = "oKXAggregatorV2"
|
||||||
|
EntryContractOKXDexRouterV2 = "oKXDExRouterV2"
|
||||||
EntryContractFluxbeamDEX = "fluxbeamDEX"
|
EntryContractFluxbeamDEX = "fluxbeamDEX"
|
||||||
EntryContractNovaBotsProgram = "novaBotsProgram"
|
EntryContractNovaBotsProgram = "novaBotsProgram"
|
||||||
EntryContractTaggedSearcher = "taggedSearcher"
|
EntryContractTaggedSearcher = "taggedSearcher"
|
||||||
|
EntryContractDFlow = "dflow"
|
||||||
|
EntryContractMaestroBot = "maestroBot"
|
||||||
|
EntryContractBonkBot = "bonkBot"
|
||||||
|
EntryContractBinanceWallet = "binanceWallet"
|
||||||
EntryContractMayhem = "pumpMayhem"
|
EntryContractMayhem = "pumpMayhem"
|
||||||
|
EntryContractTerm = "term"
|
||||||
EntryContractUnknown = "unknown"
|
EntryContractUnknown = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,6 +70,7 @@ const (
|
|||||||
PlatformMoonshotMoney = "moonshot.money"
|
PlatformMoonshotMoney = "moonshot.money"
|
||||||
PlatformMaestro = "maestro"
|
PlatformMaestro = "maestro"
|
||||||
PlatformBonkBot = "bonkbot"
|
PlatformBonkBot = "bonkbot"
|
||||||
|
PlatformPadre = "padre"
|
||||||
|
|
||||||
// used to flag transactions impersonating platform users
|
// used to flag transactions impersonating platform users
|
||||||
PlatformFake = "fake"
|
PlatformFake = "fake"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package geyser
|
package pump_parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
protoc:
|
|
||||||
protoc \
|
|
||||||
--go_out=./proto \
|
|
||||||
--go_opt=paths=source_relative \
|
|
||||||
--go-grpc_out=./proto \
|
|
||||||
--go-grpc_opt=paths=source_relative \
|
|
||||||
--proto_path ./proto/ ./proto/*.proto
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto";
|
|
||||||
import public "solana-storage.proto";
|
|
||||||
|
|
||||||
option go_package = "github.com/rpcpool/yellowstone-grpc/examples/golang/proto";
|
|
||||||
|
|
||||||
package geyser;
|
|
||||||
|
|
||||||
service Geyser {
|
|
||||||
rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}
|
|
||||||
rpc Ping(PingRequest) returns (PongResponse) {}
|
|
||||||
rpc GetLatestBlockhash(GetLatestBlockhashRequest) returns (GetLatestBlockhashResponse) {}
|
|
||||||
rpc GetBlockHeight(GetBlockHeightRequest) returns (GetBlockHeightResponse) {}
|
|
||||||
rpc GetSlot(GetSlotRequest) returns (GetSlotResponse) {}
|
|
||||||
rpc IsBlockhashValid(IsBlockhashValidRequest) returns (IsBlockhashValidResponse) {}
|
|
||||||
rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CommitmentLevel {
|
|
||||||
PROCESSED = 0;
|
|
||||||
CONFIRMED = 1;
|
|
||||||
FINALIZED = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SlotStatus {
|
|
||||||
SLOT_PROCESSED = 0;
|
|
||||||
SLOT_CONFIRMED = 1;
|
|
||||||
SLOT_FINALIZED = 2;
|
|
||||||
SLOT_FIRST_SHRED_RECEIVED = 3;
|
|
||||||
SLOT_COMPLETED = 4;
|
|
||||||
SLOT_CREATED_BANK = 5;
|
|
||||||
SLOT_DEAD = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequest {
|
|
||||||
map<string, SubscribeRequestFilterAccounts> accounts = 1;
|
|
||||||
map<string, SubscribeRequestFilterSlots> slots = 2;
|
|
||||||
map<string, SubscribeRequestFilterTransactions> transactions = 3;
|
|
||||||
map<string, SubscribeRequestFilterTransactions> transactions_status = 10;
|
|
||||||
map<string, SubscribeRequestFilterBlocks> blocks = 4;
|
|
||||||
map<string, SubscribeRequestFilterBlocksMeta> blocks_meta = 5;
|
|
||||||
map<string, SubscribeRequestFilterEntry> entry = 8;
|
|
||||||
optional CommitmentLevel commitment = 6;
|
|
||||||
repeated SubscribeRequestAccountsDataSlice accounts_data_slice = 7;
|
|
||||||
optional SubscribeRequestPing ping = 9;
|
|
||||||
optional uint64 from_slot = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterAccounts {
|
|
||||||
repeated string account = 2;
|
|
||||||
repeated string owner = 3;
|
|
||||||
repeated SubscribeRequestFilterAccountsFilter filters = 4;
|
|
||||||
optional bool nonempty_txn_signature = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterAccountsFilter {
|
|
||||||
oneof filter {
|
|
||||||
SubscribeRequestFilterAccountsFilterMemcmp memcmp = 1;
|
|
||||||
uint64 datasize = 2;
|
|
||||||
bool token_account_state = 3;
|
|
||||||
SubscribeRequestFilterAccountsFilterLamports lamports = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterAccountsFilterMemcmp {
|
|
||||||
uint64 offset = 1;
|
|
||||||
oneof data {
|
|
||||||
bytes bytes = 2;
|
|
||||||
string base58 = 3;
|
|
||||||
string base64 = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterAccountsFilterLamports {
|
|
||||||
oneof cmp {
|
|
||||||
uint64 eq = 1;
|
|
||||||
uint64 ne = 2;
|
|
||||||
uint64 lt = 3;
|
|
||||||
uint64 gt = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterSlots {
|
|
||||||
optional bool filter_by_commitment = 1;
|
|
||||||
optional bool interslot_updates = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterTransactions {
|
|
||||||
optional bool vote = 1;
|
|
||||||
optional bool failed = 2;
|
|
||||||
optional string signature = 5;
|
|
||||||
repeated string account_include = 3;
|
|
||||||
repeated string account_exclude = 4;
|
|
||||||
repeated string account_required = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterBlocks {
|
|
||||||
repeated string account_include = 1;
|
|
||||||
optional bool include_transactions = 2;
|
|
||||||
optional bool include_accounts = 3;
|
|
||||||
optional bool include_entries = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterBlocksMeta {}
|
|
||||||
|
|
||||||
message SubscribeRequestFilterEntry {}
|
|
||||||
|
|
||||||
message SubscribeRequestAccountsDataSlice {
|
|
||||||
uint64 offset = 1;
|
|
||||||
uint64 length = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeRequestPing {
|
|
||||||
int32 id = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdate {
|
|
||||||
repeated string filters = 1;
|
|
||||||
oneof update_oneof {
|
|
||||||
SubscribeUpdateAccount account = 2;
|
|
||||||
SubscribeUpdateSlot slot = 3;
|
|
||||||
SubscribeUpdateTransaction transaction = 4;
|
|
||||||
SubscribeUpdateTransactionStatus transaction_status = 10;
|
|
||||||
SubscribeUpdateBlock block = 5;
|
|
||||||
SubscribeUpdatePing ping = 6;
|
|
||||||
SubscribeUpdatePong pong = 9;
|
|
||||||
SubscribeUpdateBlockMeta block_meta = 7;
|
|
||||||
SubscribeUpdateEntry entry = 8;
|
|
||||||
}
|
|
||||||
google.protobuf.Timestamp created_at = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateAccount {
|
|
||||||
SubscribeUpdateAccountInfo account = 1;
|
|
||||||
uint64 slot = 2;
|
|
||||||
bool is_startup = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateAccountInfo {
|
|
||||||
bytes pubkey = 1;
|
|
||||||
uint64 lamports = 2;
|
|
||||||
bytes owner = 3;
|
|
||||||
bool executable = 4;
|
|
||||||
uint64 rent_epoch = 5;
|
|
||||||
bytes data = 6;
|
|
||||||
uint64 write_version = 7;
|
|
||||||
optional bytes txn_signature = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateSlot {
|
|
||||||
uint64 slot = 1;
|
|
||||||
optional uint64 parent = 2;
|
|
||||||
SlotStatus status = 3;
|
|
||||||
optional string dead_error = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateTransaction {
|
|
||||||
SubscribeUpdateTransactionInfo transaction = 1;
|
|
||||||
uint64 slot = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateTransactionInfo {
|
|
||||||
bytes signature = 1;
|
|
||||||
bool is_vote = 2;
|
|
||||||
solana.storage.ConfirmedBlock.Transaction transaction = 3;
|
|
||||||
solana.storage.ConfirmedBlock.TransactionStatusMeta meta = 4;
|
|
||||||
uint64 index = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateTransactionStatus {
|
|
||||||
uint64 slot = 1;
|
|
||||||
bytes signature = 2;
|
|
||||||
bool is_vote = 3;
|
|
||||||
uint64 index = 4;
|
|
||||||
solana.storage.ConfirmedBlock.TransactionError err = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateBlock {
|
|
||||||
uint64 slot = 1;
|
|
||||||
string blockhash = 2;
|
|
||||||
solana.storage.ConfirmedBlock.Rewards rewards = 3;
|
|
||||||
solana.storage.ConfirmedBlock.UnixTimestamp block_time = 4;
|
|
||||||
solana.storage.ConfirmedBlock.BlockHeight block_height = 5;
|
|
||||||
uint64 parent_slot = 7;
|
|
||||||
string parent_blockhash = 8;
|
|
||||||
uint64 executed_transaction_count = 9;
|
|
||||||
repeated SubscribeUpdateTransactionInfo transactions = 6;
|
|
||||||
uint64 updated_account_count = 10;
|
|
||||||
repeated SubscribeUpdateAccountInfo accounts = 11;
|
|
||||||
uint64 entries_count = 12;
|
|
||||||
repeated SubscribeUpdateEntry entries = 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateBlockMeta {
|
|
||||||
uint64 slot = 1;
|
|
||||||
string blockhash = 2;
|
|
||||||
solana.storage.ConfirmedBlock.Rewards rewards = 3;
|
|
||||||
solana.storage.ConfirmedBlock.UnixTimestamp block_time = 4;
|
|
||||||
solana.storage.ConfirmedBlock.BlockHeight block_height = 5;
|
|
||||||
uint64 parent_slot = 6;
|
|
||||||
string parent_blockhash = 7;
|
|
||||||
uint64 executed_transaction_count = 8;
|
|
||||||
uint64 entries_count = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdateEntry {
|
|
||||||
uint64 slot = 1;
|
|
||||||
uint64 index = 2;
|
|
||||||
uint64 num_hashes = 3;
|
|
||||||
bytes hash = 4;
|
|
||||||
uint64 executed_transaction_count = 5;
|
|
||||||
uint64 starting_transaction_index = 6; // added in v1.18, for solana 1.17 value is always 0
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubscribeUpdatePing {}
|
|
||||||
|
|
||||||
message SubscribeUpdatePong {
|
|
||||||
int32 id = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// non-streaming methods
|
|
||||||
|
|
||||||
message PingRequest {
|
|
||||||
int32 count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PongResponse {
|
|
||||||
int32 count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetLatestBlockhashRequest {
|
|
||||||
optional CommitmentLevel commitment = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetLatestBlockhashResponse {
|
|
||||||
uint64 slot = 1;
|
|
||||||
string blockhash = 2;
|
|
||||||
uint64 last_valid_block_height = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetBlockHeightRequest {
|
|
||||||
optional CommitmentLevel commitment = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetBlockHeightResponse {
|
|
||||||
uint64 block_height = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetSlotRequest {
|
|
||||||
optional CommitmentLevel commitment = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetSlotResponse {
|
|
||||||
uint64 slot = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetVersionRequest {}
|
|
||||||
|
|
||||||
message GetVersionResponse {
|
|
||||||
string version = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message IsBlockhashValidRequest {
|
|
||||||
string blockhash = 1;
|
|
||||||
optional CommitmentLevel commitment = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message IsBlockhashValidResponse {
|
|
||||||
uint64 slot = 1;
|
|
||||||
bool valid = 2;
|
|
||||||
}
|
|
||||||
@@ -1,344 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.5.1
|
|
||||||
// - protoc v5.29.3
|
|
||||||
// source: geyser.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.64.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion9
|
|
||||||
|
|
||||||
const (
|
|
||||||
Geyser_Subscribe_FullMethodName = "/geyser.Geyser/Subscribe"
|
|
||||||
Geyser_Ping_FullMethodName = "/geyser.Geyser/Ping"
|
|
||||||
Geyser_GetLatestBlockhash_FullMethodName = "/geyser.Geyser/GetLatestBlockhash"
|
|
||||||
Geyser_GetBlockHeight_FullMethodName = "/geyser.Geyser/GetBlockHeight"
|
|
||||||
Geyser_GetSlot_FullMethodName = "/geyser.Geyser/GetSlot"
|
|
||||||
Geyser_IsBlockhashValid_FullMethodName = "/geyser.Geyser/IsBlockhashValid"
|
|
||||||
Geyser_GetVersion_FullMethodName = "/geyser.Geyser/GetVersion"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GeyserClient is the client API for Geyser service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type GeyserClient interface {
|
|
||||||
Subscribe(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SubscribeRequest, SubscribeUpdate], error)
|
|
||||||
Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error)
|
|
||||||
GetLatestBlockhash(ctx context.Context, in *GetLatestBlockhashRequest, opts ...grpc.CallOption) (*GetLatestBlockhashResponse, error)
|
|
||||||
GetBlockHeight(ctx context.Context, in *GetBlockHeightRequest, opts ...grpc.CallOption) (*GetBlockHeightResponse, error)
|
|
||||||
GetSlot(ctx context.Context, in *GetSlotRequest, opts ...grpc.CallOption) (*GetSlotResponse, error)
|
|
||||||
IsBlockhashValid(ctx context.Context, in *IsBlockhashValidRequest, opts ...grpc.CallOption) (*IsBlockhashValidResponse, error)
|
|
||||||
GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type geyserClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGeyserClient(cc grpc.ClientConnInterface) GeyserClient {
|
|
||||||
return &geyserClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) Subscribe(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SubscribeRequest, SubscribeUpdate], error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
stream, err := c.cc.NewStream(ctx, &Geyser_ServiceDesc.Streams[0], Geyser_Subscribe_FullMethodName, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
x := &grpc.GenericClientStream[SubscribeRequest, SubscribeUpdate]{ClientStream: stream}
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
|
||||||
type Geyser_SubscribeClient = grpc.BidiStreamingClient[SubscribeRequest, SubscribeUpdate]
|
|
||||||
|
|
||||||
func (c *geyserClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(PongResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_Ping_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) GetLatestBlockhash(ctx context.Context, in *GetLatestBlockhashRequest, opts ...grpc.CallOption) (*GetLatestBlockhashResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetLatestBlockhashResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_GetLatestBlockhash_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) GetBlockHeight(ctx context.Context, in *GetBlockHeightRequest, opts ...grpc.CallOption) (*GetBlockHeightResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetBlockHeightResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_GetBlockHeight_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) GetSlot(ctx context.Context, in *GetSlotRequest, opts ...grpc.CallOption) (*GetSlotResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetSlotResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_GetSlot_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) IsBlockhashValid(ctx context.Context, in *IsBlockhashValidRequest, opts ...grpc.CallOption) (*IsBlockhashValidResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(IsBlockhashValidResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_IsBlockhashValid_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *geyserClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetVersionResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Geyser_GetVersion_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GeyserServer is the server API for Geyser service.
|
|
||||||
// All implementations must embed UnimplementedGeyserServer
|
|
||||||
// for forward compatibility.
|
|
||||||
type GeyserServer interface {
|
|
||||||
Subscribe(grpc.BidiStreamingServer[SubscribeRequest, SubscribeUpdate]) error
|
|
||||||
Ping(context.Context, *PingRequest) (*PongResponse, error)
|
|
||||||
GetLatestBlockhash(context.Context, *GetLatestBlockhashRequest) (*GetLatestBlockhashResponse, error)
|
|
||||||
GetBlockHeight(context.Context, *GetBlockHeightRequest) (*GetBlockHeightResponse, error)
|
|
||||||
GetSlot(context.Context, *GetSlotRequest) (*GetSlotResponse, error)
|
|
||||||
IsBlockhashValid(context.Context, *IsBlockhashValidRequest) (*IsBlockhashValidResponse, error)
|
|
||||||
GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error)
|
|
||||||
mustEmbedUnimplementedGeyserServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedGeyserServer must be embedded to have
|
|
||||||
// forward compatible implementations.
|
|
||||||
//
|
|
||||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
|
||||||
// pointer dereference when methods are called.
|
|
||||||
type UnimplementedGeyserServer struct{}
|
|
||||||
|
|
||||||
func (UnimplementedGeyserServer) Subscribe(grpc.BidiStreamingServer[SubscribeRequest, SubscribeUpdate]) error {
|
|
||||||
return status.Errorf(codes.Unimplemented, "method Subscribe not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) Ping(context.Context, *PingRequest) (*PongResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) GetLatestBlockhash(context.Context, *GetLatestBlockhashRequest) (*GetLatestBlockhashResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlockhash not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) GetBlockHeight(context.Context, *GetBlockHeightRequest) (*GetBlockHeightResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetBlockHeight not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) GetSlot(context.Context, *GetSlotRequest) (*GetSlotResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetSlot not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) IsBlockhashValid(context.Context, *IsBlockhashValidRequest) (*IsBlockhashValidResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method IsBlockhashValid not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedGeyserServer) mustEmbedUnimplementedGeyserServer() {}
|
|
||||||
func (UnimplementedGeyserServer) testEmbeddedByValue() {}
|
|
||||||
|
|
||||||
// UnsafeGeyserServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to GeyserServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeGeyserServer interface {
|
|
||||||
mustEmbedUnimplementedGeyserServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterGeyserServer(s grpc.ServiceRegistrar, srv GeyserServer) {
|
|
||||||
// If the following call pancis, it indicates UnimplementedGeyserServer was
|
|
||||||
// embedded by pointer and is nil. This will cause panics if an
|
|
||||||
// unimplemented method is ever invoked, so we test this at initialization
|
|
||||||
// time to prevent it from happening at runtime later due to I/O.
|
|
||||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
|
||||||
t.testEmbeddedByValue()
|
|
||||||
}
|
|
||||||
s.RegisterService(&Geyser_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error {
|
|
||||||
return srv.(GeyserServer).Subscribe(&grpc.GenericServerStream[SubscribeRequest, SubscribeUpdate]{ServerStream: stream})
|
|
||||||
}
|
|
||||||
|
|
||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
|
||||||
type Geyser_SubscribeServer = grpc.BidiStreamingServer[SubscribeRequest, SubscribeUpdate]
|
|
||||||
|
|
||||||
func _Geyser_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(PingRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).Ping(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_Ping_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).Ping(ctx, req.(*PingRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_GetLatestBlockhash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetLatestBlockhashRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).GetLatestBlockhash(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_GetLatestBlockhash_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).GetLatestBlockhash(ctx, req.(*GetLatestBlockhashRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_GetBlockHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetBlockHeightRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).GetBlockHeight(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_GetBlockHeight_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).GetBlockHeight(ctx, req.(*GetBlockHeightRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_GetSlot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetSlotRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).GetSlot(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_GetSlot_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).GetSlot(ctx, req.(*GetSlotRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_IsBlockhashValid_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(IsBlockhashValidRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).IsBlockhashValid(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_IsBlockhashValid_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).IsBlockhashValid(ctx, req.(*IsBlockhashValidRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Geyser_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetVersionRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(GeyserServer).GetVersion(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Geyser_GetVersion_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(GeyserServer).GetVersion(ctx, req.(*GetVersionRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Geyser_ServiceDesc is the grpc.ServiceDesc for Geyser service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var Geyser_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "geyser.Geyser",
|
|
||||||
HandlerType: (*GeyserServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "Ping",
|
|
||||||
Handler: _Geyser_Ping_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetLatestBlockhash",
|
|
||||||
Handler: _Geyser_GetLatestBlockhash_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetBlockHeight",
|
|
||||||
Handler: _Geyser_GetBlockHeight_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetSlot",
|
|
||||||
Handler: _Geyser_GetSlot_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "IsBlockhashValid",
|
|
||||||
Handler: _Geyser_IsBlockhashValid_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetVersion",
|
|
||||||
Handler: _Geyser_GetVersion_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{
|
|
||||||
{
|
|
||||||
StreamName: "Subscribe",
|
|
||||||
Handler: _Geyser_Subscribe_Handler,
|
|
||||||
ServerStreams: true,
|
|
||||||
ClientStreams: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Metadata: "geyser.proto",
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package solana.storage.ConfirmedBlock;
|
|
||||||
|
|
||||||
option go_package = "github.com/rpcpool/yellowstone-grpc/examples/golang/proto";
|
|
||||||
|
|
||||||
message ConfirmedBlock {
|
|
||||||
string previous_blockhash = 1;
|
|
||||||
string blockhash = 2;
|
|
||||||
uint64 parent_slot = 3;
|
|
||||||
repeated ConfirmedTransaction transactions = 4;
|
|
||||||
repeated Reward rewards = 5;
|
|
||||||
UnixTimestamp block_time = 6;
|
|
||||||
BlockHeight block_height = 7;
|
|
||||||
NumPartitions num_partitions = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ConfirmedTransaction {
|
|
||||||
Transaction transaction = 1;
|
|
||||||
TransactionStatusMeta meta = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Transaction {
|
|
||||||
repeated bytes signatures = 1;
|
|
||||||
Message message = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Message {
|
|
||||||
MessageHeader header = 1;
|
|
||||||
repeated bytes account_keys = 2;
|
|
||||||
bytes recent_blockhash = 3;
|
|
||||||
repeated CompiledInstruction instructions = 4;
|
|
||||||
bool versioned = 5;
|
|
||||||
repeated MessageAddressTableLookup address_table_lookups = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message MessageHeader {
|
|
||||||
uint32 num_required_signatures = 1;
|
|
||||||
uint32 num_readonly_signed_accounts = 2;
|
|
||||||
uint32 num_readonly_unsigned_accounts = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message MessageAddressTableLookup {
|
|
||||||
bytes account_key = 1;
|
|
||||||
bytes writable_indexes = 2;
|
|
||||||
bytes readonly_indexes = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TransactionStatusMeta {
|
|
||||||
TransactionError err = 1;
|
|
||||||
uint64 fee = 2;
|
|
||||||
repeated uint64 pre_balances = 3;
|
|
||||||
repeated uint64 post_balances = 4;
|
|
||||||
repeated InnerInstructions inner_instructions = 5;
|
|
||||||
bool inner_instructions_none = 10;
|
|
||||||
repeated string log_messages = 6;
|
|
||||||
bool log_messages_none = 11;
|
|
||||||
repeated TokenBalance pre_token_balances = 7;
|
|
||||||
repeated TokenBalance post_token_balances = 8;
|
|
||||||
repeated Reward rewards = 9;
|
|
||||||
repeated bytes loaded_writable_addresses = 12;
|
|
||||||
repeated bytes loaded_readonly_addresses = 13;
|
|
||||||
ReturnData return_data = 14;
|
|
||||||
bool return_data_none = 15;
|
|
||||||
|
|
||||||
// Sum of compute units consumed by all instructions.
|
|
||||||
// Available since Solana v1.10.35 / v1.11.6.
|
|
||||||
// Set to `None` for txs executed on earlier versions.
|
|
||||||
optional uint64 compute_units_consumed = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TransactionError {
|
|
||||||
bytes err = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InnerInstructions {
|
|
||||||
uint32 index = 1;
|
|
||||||
repeated InnerInstruction instructions = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InnerInstruction {
|
|
||||||
uint32 program_id_index = 1;
|
|
||||||
bytes accounts = 2;
|
|
||||||
bytes data = 3;
|
|
||||||
|
|
||||||
// Invocation stack height of an inner instruction.
|
|
||||||
// Available since Solana v1.14.6
|
|
||||||
// Set to `None` for txs executed on earlier versions.
|
|
||||||
optional uint32 stack_height = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CompiledInstruction {
|
|
||||||
uint32 program_id_index = 1;
|
|
||||||
bytes accounts = 2;
|
|
||||||
bytes data = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TokenBalance {
|
|
||||||
uint32 account_index = 1;
|
|
||||||
string mint = 2;
|
|
||||||
UiTokenAmount ui_token_amount = 3;
|
|
||||||
string owner = 4;
|
|
||||||
string program_id = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UiTokenAmount {
|
|
||||||
double ui_amount = 1;
|
|
||||||
uint32 decimals = 2;
|
|
||||||
string amount = 3;
|
|
||||||
string ui_amount_string = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ReturnData {
|
|
||||||
bytes program_id = 1;
|
|
||||||
bytes data = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum RewardType {
|
|
||||||
Unspecified = 0;
|
|
||||||
Fee = 1;
|
|
||||||
Rent = 2;
|
|
||||||
Staking = 3;
|
|
||||||
Voting = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Reward {
|
|
||||||
string pubkey = 1;
|
|
||||||
int64 lamports = 2;
|
|
||||||
uint64 post_balance = 3;
|
|
||||||
RewardType reward_type = 4;
|
|
||||||
string commission = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Rewards {
|
|
||||||
repeated Reward rewards = 1;
|
|
||||||
NumPartitions num_partitions = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UnixTimestamp {
|
|
||||||
int64 timestamp = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BlockHeight {
|
|
||||||
uint64 block_height = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message NumPartitions {
|
|
||||||
uint64 num_partitions = 1;
|
|
||||||
}
|
|
||||||
38
go.mod
38
go.mod
@@ -8,21 +8,22 @@ require (
|
|||||||
github.com/jackc/pgtype v1.14.4
|
github.com/jackc/pgtype v1.14.4
|
||||||
github.com/mr-tron/base58 v1.2.0
|
github.com/mr-tron/base58 v1.2.0
|
||||||
github.com/shopspring/decimal v1.4.0
|
github.com/shopspring/decimal v1.4.0
|
||||||
google.golang.org/grpc v1.77.0
|
go.onsig.ai/onsig/yellowstone-proto v1.0.0
|
||||||
google.golang.org/protobuf v1.36.10
|
google.golang.org/grpc v1.78.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.0.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
||||||
|
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||||
github.com/blendle/zapdriver v1.3.1 // indirect
|
github.com/blendle/zapdriver v1.3.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fatih/color v1.9.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/gagliardetto/treeout v0.1.4 // indirect
|
github.com/gagliardetto/treeout v0.1.4 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/jackc/pgio v1.0.0 // indirect
|
github.com/jackc/pgio v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.13.6 // indirect
|
github.com/klauspost/compress v1.18.2 // indirect
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
@@ -30,17 +31,18 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect
|
github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect
|
||||||
github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845 // indirect
|
github.com/streamingfast/logging v0.0.0-20251216203033-fdad0a00f1ca // indirect
|
||||||
go.mongodb.org/mongo-driver v1.12.2 // indirect
|
go.mongodb.org/mongo-driver v1.17.6 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/ratelimit v0.2.0 // indirect
|
go.uber.org/ratelimit v0.3.1 // indirect
|
||||||
go.uber.org/zap v1.21.0 // indirect
|
go.uber.org/zap v1.27.1 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
golang.org/x/crypto v0.46.0 // indirect
|
||||||
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect
|
golang.org/x/net v0.48.0 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
golang.org/x/term v0.36.0 // indirect
|
golang.org/x/term v0.38.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.32.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||||
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
41
go.sum
41
go.sum
@@ -1,5 +1,7 @@
|
|||||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI=
|
github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI=
|
||||||
github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE=
|
github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
@@ -8,6 +10,8 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9or
|
|||||||
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
|
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||||
|
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE=
|
github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE=
|
||||||
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
|
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
@@ -19,6 +23,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg=
|
github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg=
|
||||||
github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c=
|
github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c=
|
||||||
github.com/gagliardetto/solana-go v1.14.0 h1:3WfAi70jOOjAJ0deFMjdhFYlLXATF4tOQXsDNWJtOLw=
|
github.com/gagliardetto/solana-go v1.14.0 h1:3WfAi70jOOjAJ0deFMjdhFYlLXATF4tOQXsDNWJtOLw=
|
||||||
@@ -99,6 +105,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
|
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
||||||
|
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
@@ -159,6 +167,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
|||||||
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU=
|
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU=
|
||||||
github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845 h1:VMA0pZ3MI8BErRA3kh8dKJThP5d0Xh5vZVk5yFIgH/A=
|
github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845 h1:VMA0pZ3MI8BErRA3kh8dKJThP5d0Xh5vZVk5yFIgH/A=
|
||||||
github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845/go.mod h1:BtDq81Tyc7H8up5aXNi/I95nPmG3C0PLEqGWY/iWQ2E=
|
github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845/go.mod h1:BtDq81Tyc7H8up5aXNi/I95nPmG3C0PLEqGWY/iWQ2E=
|
||||||
|
github.com/streamingfast/logging v0.0.0-20251216203033-fdad0a00f1ca h1:D9r6WXATiqumhUTqSysurIi3N50z4orVBW+TEMp50Q4=
|
||||||
|
github.com/streamingfast/logging v0.0.0-20251216203033-fdad0a00f1ca/go.mod h1:fJ5nP7ZSMB4MQQ6RM7cF+LiSQ43b5cVletcSUNL8z2M=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
@@ -185,6 +195,10 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
|||||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
go.mongodb.org/mongo-driver v1.12.2 h1:gbWY1bJkkmUB9jjZzcdhOL8O85N9H+Vvsf2yFN0RDws=
|
go.mongodb.org/mongo-driver v1.12.2 h1:gbWY1bJkkmUB9jjZzcdhOL8O85N9H+Vvsf2yFN0RDws=
|
||||||
go.mongodb.org/mongo-driver v1.12.2/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
go.mongodb.org/mongo-driver v1.12.2/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||||
|
go.onsig.ai/onsig/yellowstone-proto v1.0.0 h1:+XBNIoyl3HoQGBhgWCf8Ma3zNoUHKorFV8tR+HnE4Lw=
|
||||||
|
go.onsig.ai/onsig/yellowstone-proto v1.0.0/go.mod h1:e5dlYkNpgNHtiXFwPmPDZRf4PrCsgNaSoA8iG4rfiKA=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
@@ -203,21 +217,30 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
|||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||||
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA=
|
go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA=
|
||||||
go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg=
|
go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg=
|
||||||
|
go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0=
|
||||||
|
go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
|
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
|
||||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||||
|
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||||
|
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@@ -234,6 +257,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
|
|||||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||||
|
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||||
|
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
@@ -253,6 +278,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo=
|
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo=
|
||||||
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||||
|
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||||
|
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -280,6 +307,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||||
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -288,6 +317,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||||
|
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||||
|
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@@ -300,8 +331,12 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||||
|
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
@@ -325,10 +360,16 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
|||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
|
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
|
||||||
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
|
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
|
||||||
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
parser "github.com/thloyi/pump-parser"
|
parser "github.com/thloyi/pump-parser"
|
||||||
example "github.com/thloyi/pump-parser/example"
|
example "github.com/thloyi/pump-parser/internal/example"
|
||||||
"github.com/thloyi/pump-parser/example/geyser"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -19,8 +17,8 @@ func main() {
|
|||||||
//xt := tracker.NewTwitterTracker(nil) // Initialize Twitter tracker if needed
|
//xt := tracker.NewTwitterTracker(nil) // Initialize Twitter tracker if needed
|
||||||
// laserstream-mainnet-slc.helius-rpc.com:80
|
// laserstream-mainnet-slc.helius-rpc.com:80
|
||||||
|
|
||||||
ch := make(chan geyser.SubscriptionMessage, 1)
|
ch := make(chan example.SubscriptionMessage, 1)
|
||||||
go geyser.RunLoopWithReConnect(context.Background(), "127.0.0.1:10001", parser.SolProgramPump, ch)
|
go example.RunLoopWithReConnect(context.Background(), "127.0.0.1:10001", parser.SolProgramPump, ch)
|
||||||
// var tokenTxs = make(map[string]*types.Tx)
|
// var tokenTxs = make(map[string]*types.Tx)
|
||||||
// currentBlock := uint64(0)
|
// currentBlock := uint64(0)
|
||||||
for msg := range ch {
|
for msg := range ch {
|
||||||
@@ -40,15 +38,12 @@ func main() {
|
|||||||
//if tx.Token0Address != "HRHLDjqFBhNeyTXUuZQE9gTy5z2112qeQBS9U79NHyyp" {
|
//if tx.Token0Address != "HRHLDjqFBhNeyTXUuZQE9gTy5z2112qeQBS9U79NHyyp" {
|
||||||
// continue
|
// continue
|
||||||
//}
|
//}
|
||||||
//if tx.Program != parser.SolProgramPump {
|
|
||||||
// continue
|
|
||||||
//}
|
|
||||||
//if currentBlock == ptx.Block {
|
//if currentBlock == ptx.Block {
|
||||||
// continue
|
// continue
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// 处理交易
|
// 处理交易
|
||||||
txErr, ok := ptx.Err.(*geyser.TransactionError)
|
txErr, ok := ptx.Err.(*parser.TransactionError)
|
||||||
var customerErrCode uint32
|
var customerErrCode uint32
|
||||||
var instructorErrIndex uint8
|
var instructorErrIndex uint8
|
||||||
if ok {
|
if ok {
|
||||||
@@ -60,23 +55,26 @@ func main() {
|
|||||||
fmt.Printf("tx is empty, block: %d, tx %s \n", ptx.Block, ptx.GetTxHash())
|
fmt.Printf("tx is empty, block: %d, tx %s \n", ptx.Block, ptx.GetTxHash())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
printed := false
|
// printed := false
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if tx.Program != parser.SolProgramPump {
|
if tx.Program != parser.SolProgramPumpAMM {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if tx.Token1Amount.GreaterThanOrEqual(decimal.NewFromFloat(0.1)) || tx.Event != "buy" {
|
if tx.EntryContract == "" || tx.EntryContract == parser.SolProgramPumpAMM || tx.EntryContract == parser.EntryContractOKXDexRouterV2 || tx.EntryContract == "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
printed = true
|
//if tx.Token1Amount.GreaterThanOrEqual(decimal.NewFromFloat(0.1)) || tx.Event != "buy" {
|
||||||
fmt.Printf("t: %s, block: %d, hash: %s, signer: %s, program: %s, event: %s, token1: %s, cuPrice: %s, mevAgent: %s, mevFee: %s, platform: %s, platformFee: %s, entryContract: %s, mayhem: %t\n",
|
// continue
|
||||||
|
//}
|
||||||
|
// printed = true
|
||||||
|
fmt.Printf("t: %s, block: %d, hash: %s, maker: %s, program: %s, event: %s, token0: %s, entryContract: %s, token balance: %s, EntryContract: %s\n",
|
||||||
time.Now().Format(time.RFC3339Nano),
|
time.Now().Format(time.RFC3339Nano),
|
||||||
tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token1Amount, tx.CUPrice, tx.MevAgent, tx.MevAgentFee, tx.Platform, tx.PlatformFee, tx.EntryContract, tx.Mayhem)
|
tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token0Amount, tx.EntryContract, tx.AfterSignerToken0Balance, tx.EntryContract)
|
||||||
//break
|
//break
|
||||||
}
|
}
|
||||||
if !printed {
|
//if !printed {
|
||||||
continue
|
// continue
|
||||||
}
|
//}
|
||||||
//fmt.Printf("t: %s, block: %d, hash: %s, signer: %s, program: %s, event: %s, token0: %s, token1: %s, signer before sol :%s, after sol: %s, after token: %s, tokencreator: %s, tokenprogram: %s, mayhem: %t\n",
|
//fmt.Printf("t: %s, block: %d, hash: %s, signer: %s, program: %s, event: %s, token0: %s, token1: %s, signer before sol :%s, after sol: %s, after token: %s, tokencreator: %s, tokenprogram: %s, mayhem: %t\n",
|
||||||
// time.Now().Format(time.RFC3339Nano),
|
// time.Now().Format(time.RFC3339Nano),
|
||||||
// tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token0Amount.String(), tx.Token1Amount.String(),
|
// tx.Block, tx.GetTxHash(), tx.Maker, tx.Program, tx.Event, tx.Token0Amount.String(), tx.Token1Amount.String(),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package geyser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/thloyi/pump-parser"
|
"github.com/thloyi/pump-parser"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package geyser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -70,9 +70,9 @@ func FromTx(tx *parser.Tx) []*Tx {
|
|||||||
for i, s := range tx.Swaps {
|
for i, s := range tx.Swaps {
|
||||||
var newTx *Tx
|
var newTx *Tx
|
||||||
platform, platformFee := tx.CheckPlatform(s)
|
platform, platformFee := tx.CheckPlatform(s)
|
||||||
token0Program := s.BaseTokenProgram
|
//token0Program := s.BaseTokenProgram
|
||||||
token0Address := s.BaseMint
|
//token0Address := s.BaseMint
|
||||||
token0Decimals := s.BaseMintDecimals
|
//token0Decimals := s.BaseMintDecimals
|
||||||
if s.Program == "Pump" {
|
if s.Program == "Pump" {
|
||||||
quoteMint := s.QuoteMint
|
quoteMint := s.QuoteMint
|
||||||
// 有些数据里 quote 会给 SystemProgram,统一转成 WSOL
|
// 有些数据里 quote 会给 SystemProgram,统一转成 WSOL
|
||||||
@@ -130,9 +130,9 @@ func FromTx(tx *parser.Tx) []*Tx {
|
|||||||
} else if s.Event == "sell" {
|
} else if s.Event == "sell" {
|
||||||
eventName = "buy"
|
eventName = "buy"
|
||||||
}
|
}
|
||||||
token0Program = s.QuoteTokenProgram
|
//token0Program = s.QuoteTokenProgram
|
||||||
token0Address = s.QuoteMint
|
//token0Address = s.QuoteMint
|
||||||
token0Decimals = s.QuoteMintDecimals
|
//token0Decimals = s.QuoteMintDecimals
|
||||||
newTx = &Tx{
|
newTx = &Tx{
|
||||||
Err: nil,
|
Err: nil,
|
||||||
//BondingCurve: s.Pool.String(),
|
//BondingCurve: s.Pool.String(),
|
||||||
@@ -225,10 +225,11 @@ func FromTx(tx *parser.Tx) []*Tx {
|
|||||||
if newTx == nil {
|
if newTx == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if newTx.Maker == "HV1KXxWFaSeriyFvXyx48FqG9BoFbfinB8njCJonqP7K" && newTx.EntryContract == "oKXAggregatorV2" {
|
|
||||||
newTx.Maker = tx.Signer.String()
|
//if (newTx.Maker == "HV1KXxWFaSeriyFvXyx48FqG9BoFbfinB8njCJonqP7K" && newTx.EntryContract == "oKXAggregatorV2") || (newTx.Maker == "ARu4n5mFdZogZAravu7CcizaojWnS6oqka37gdLT5SZn" && newTx.EntryContract == "oKXDExRouterV2") {
|
||||||
newTx.AfterSignerToken0Balance = tx.GetSignerTokenBalanceAfterTx(token0Program, token0Address).Div(decimal.New(1, int32(token0Decimals)))
|
// newTx.Maker = tx.Signer.String()
|
||||||
}
|
// newTx.AfterSignerToken0Balance = tx.GetSignerTokenBalanceAfterTx(token0Program, token0Address).Div(decimal.New(1, int32(token0Decimals)))
|
||||||
|
//}
|
||||||
|
|
||||||
txs = append(txs, newTx)
|
txs = append(txs, newTx)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package geyser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
solana2 "github.com/gagliardetto/solana-go"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
@@ -17,7 +16,7 @@ import (
|
|||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
types "github.com/thloyi/pump-parser"
|
types "github.com/thloyi/pump-parser"
|
||||||
pb "github.com/thloyi/pump-parser/example/geyser/proto"
|
pb "go.onsig.ai/onsig/yellowstone-proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
@@ -63,6 +62,9 @@ func NewClientWithPumpSwap(endpoint string, ch chan SubscriptionMessage) *Client
|
|||||||
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA", //Pump AMM
|
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA", //Pump AMM
|
||||||
"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P", //Pump
|
"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P", //Pump
|
||||||
}
|
}
|
||||||
|
subscription.Transactions["transactions_sub"].AccountRequired = []string{
|
||||||
|
"ARu4n5mFdZogZAravu7CcizaojWnS6oqka37gdLT5SZn",
|
||||||
|
}
|
||||||
subscription.BlocksMeta = make(map[string]*pb.SubscribeRequestFilterBlocksMeta)
|
subscription.BlocksMeta = make(map[string]*pb.SubscribeRequestFilterBlocksMeta)
|
||||||
subscription.BlocksMeta["block_meta"] = &pb.SubscribeRequestFilterBlocksMeta{}
|
subscription.BlocksMeta["block_meta"] = &pb.SubscribeRequestFilterBlocksMeta{}
|
||||||
|
|
||||||
@@ -242,7 +244,7 @@ func (c *Client) grpcSubscribe(ctx context.Context, conn *grpc.ClientConn) error
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rawTx, err := ConvertYellowstoneGrpcTransactionToSolanaTransaction(txn, resp.GetCreatedAt().Seconds)
|
rawTx, err := types.ConvertYellowstoneGrpcTransactionToSolanaTransaction(txn, resp.GetCreatedAt().Seconds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to convert transaction: %v", err)
|
log.Printf("Failed to convert transaction: %v", err)
|
||||||
continue
|
continue
|
||||||
@@ -290,236 +292,3 @@ func (c *Client) sendBlock(blockMeta *pb.SubscribeUpdateBlockMeta) {
|
|||||||
}
|
}
|
||||||
c.firstMessage = false
|
c.firstMessage = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertYellowstoneGrpcTransactionToSolanaTransaction(y *pb.SubscribeUpdateTransaction, created int64) (*types.RawTx, error) {
|
|
||||||
sTx := &types.RawTx{
|
|
||||||
BlockTime: created,
|
|
||||||
Slot: y.Slot,
|
|
||||||
IndexWithinBlock: int64(y.Transaction.Index),
|
|
||||||
Meta: types.Meta{
|
|
||||||
Err: nil,
|
|
||||||
Fee: 0,
|
|
||||||
InnerInstructions: nil,
|
|
||||||
LoadedAddresses: types.LoadedAddresses{},
|
|
||||||
LogMessages: nil,
|
|
||||||
PostBalances: nil,
|
|
||||||
PostTokenBalances: nil,
|
|
||||||
PreBalances: nil,
|
|
||||||
PreTokenBalances: nil,
|
|
||||||
Rewards: nil,
|
|
||||||
},
|
|
||||||
//Transaction: types.Transaction{
|
|
||||||
// Message: types.Message{
|
|
||||||
// AccountKeys: nil,
|
|
||||||
// AddressTableLookups: nil,
|
|
||||||
// Header: types.Header{},
|
|
||||||
// Instructions: nil,
|
|
||||||
// RecentBlockHash: "",
|
|
||||||
// },
|
|
||||||
// Signatures: nil,
|
|
||||||
//},
|
|
||||||
//Version: nil,
|
|
||||||
}
|
|
||||||
meta := y.Transaction.GetMeta()
|
|
||||||
yTx := y.Transaction.Transaction
|
|
||||||
|
|
||||||
if meta.Err != nil && len(meta.Err.GetErr()) > 0 {
|
|
||||||
// If the transaction has an error, we set the error in the Meta
|
|
||||||
transError, err := DecodeTransactionError(meta.Err.GetErr())
|
|
||||||
if err != nil {
|
|
||||||
sTx.Meta.Err = err
|
|
||||||
} else {
|
|
||||||
sTx.Meta.Err = transError
|
|
||||||
}
|
|
||||||
// sTx.Meta.Err = meta.Err.GetErr()
|
|
||||||
}
|
|
||||||
sTx.Meta.Fee = meta.Fee
|
|
||||||
//sTx.Meta.InnerInstructions = meta.InnerInstructions
|
|
||||||
|
|
||||||
for _, innerInstr := range meta.InnerInstructions {
|
|
||||||
var instrs []types.Instruction
|
|
||||||
for _, instr := range innerInstr.Instructions {
|
|
||||||
instrs = append(instrs, types.Instruction{
|
|
||||||
ProgramIDIndex: int(instr.ProgramIdIndex),
|
|
||||||
Accounts: func() []int {
|
|
||||||
var out []int
|
|
||||||
for i := range instr.Accounts {
|
|
||||||
out = append(out, int(instr.Accounts[i]))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}(),
|
|
||||||
Data: instr.Data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sTx.Meta.InnerInstructions = append(sTx.Meta.InnerInstructions, types.InnerInstructions{
|
|
||||||
Index: int(innerInstr.Index),
|
|
||||||
Instructions: instrs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sTx.Meta.LogMessages = meta.LogMessages
|
|
||||||
sTx.Meta.PostBalances = meta.PostBalances
|
|
||||||
sTx.Meta.PostTokenBalances = grpcTokenBalance(meta.PostTokenBalances)
|
|
||||||
sTx.Meta.PreBalances = meta.PreBalances
|
|
||||||
sTx.Meta.PreTokenBalances = grpcTokenBalance(meta.PreTokenBalances)
|
|
||||||
sTx.Meta.Rewards = nil
|
|
||||||
sTx.Meta.LoadedAddresses.Readonly = byteSlicesToKeySlices(meta.LoadedReadonlyAddresses)
|
|
||||||
sTx.Meta.LoadedAddresses.Writable = byteSlicesToKeySlices(meta.LoadedWritableAddresses)
|
|
||||||
|
|
||||||
// copy signatures
|
|
||||||
for i := range yTx.Signatures {
|
|
||||||
sTx.Transaction.Signatures = append(sTx.Transaction.Signatures, solana2.SignatureFromBytes(yTx.Signatures[i]))
|
|
||||||
}
|
|
||||||
// copy message
|
|
||||||
sTx.Transaction.Message = types.Message{
|
|
||||||
RecentBlockHash: solana2.HashFromBytes(yTx.Message.RecentBlockhash).String(),
|
|
||||||
}
|
|
||||||
// copy message.AccountKeys
|
|
||||||
//stopAt := len(yTx.Message.AccountKeys) - sTx.Message.NumLookups()
|
|
||||||
stopAt := len(yTx.Message.AccountKeys)
|
|
||||||
for accIndex, acc := range yTx.Message.AccountKeys {
|
|
||||||
sTx.Transaction.Message.AccountKeys = append(sTx.Transaction.Message.AccountKeys, solana2.PublicKeyFromBytes(acc))
|
|
||||||
if accIndex == stopAt-1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// copy message.Header
|
|
||||||
sTx.Transaction.Message.Header = types.Header{
|
|
||||||
NumRequiredSignatures: int(yTx.Message.Header.NumRequiredSignatures),
|
|
||||||
NumReadonlySignedAccounts: int(yTx.Message.Header.NumReadonlySignedAccounts),
|
|
||||||
NumReadonlyUnsignedAccounts: int(yTx.Message.Header.NumReadonlyUnsignedAccounts),
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy message.versioned
|
|
||||||
if yTx.Message.Versioned {
|
|
||||||
sTx.Version = solana2.MessageVersionV0
|
|
||||||
} else {
|
|
||||||
sTx.Version = solana2.MessageVersionLegacy
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy address table lookups
|
|
||||||
{
|
|
||||||
tables := map[solana2.PublicKey]solana2.PublicKeySlice{}
|
|
||||||
writable := byteSlicesToKeySlices(meta.LoadedWritableAddresses)
|
|
||||||
readonly := byteSlicesToKeySlices(meta.LoadedReadonlyAddresses)
|
|
||||||
for _, addr := range yTx.Message.AddressTableLookups {
|
|
||||||
sTx.Transaction.Message.AddressTableLookups = append(sTx.Transaction.Message.AddressTableLookups, solana2.MessageAddressTableLookup{
|
|
||||||
AccountKey: solana2.PublicKeyFromBytes(addr.AccountKey),
|
|
||||||
WritableIndexes: addr.WritableIndexes,
|
|
||||||
ReadonlyIndexes: addr.ReadonlyIndexes,
|
|
||||||
})
|
|
||||||
numTakeWritable := len(addr.WritableIndexes)
|
|
||||||
numTakeReadonly := len(addr.ReadonlyIndexes)
|
|
||||||
tableKey := solana2.PublicKeyFromBytes(addr.AccountKey)
|
|
||||||
{
|
|
||||||
// now need to rebuild the address table taking into account the indexes, and put the keys into the tables
|
|
||||||
maxIndex := 0
|
|
||||||
for _, indexB := range addr.WritableIndexes {
|
|
||||||
index := int(indexB)
|
|
||||||
if index > maxIndex {
|
|
||||||
maxIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, indexB := range addr.ReadonlyIndexes {
|
|
||||||
index := int(indexB)
|
|
||||||
if index > maxIndex {
|
|
||||||
maxIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tables[tableKey] = make([]solana2.PublicKey, maxIndex+1)
|
|
||||||
}
|
|
||||||
if numTakeWritable > 0 {
|
|
||||||
writableForTable := writable[:numTakeWritable]
|
|
||||||
for i, indexB := range addr.WritableIndexes {
|
|
||||||
index := int(indexB)
|
|
||||||
tables[tableKey][index] = writableForTable[i]
|
|
||||||
}
|
|
||||||
writable = writable[numTakeWritable:]
|
|
||||||
}
|
|
||||||
if numTakeReadonly > 0 {
|
|
||||||
readableForTable := readonly[:numTakeReadonly]
|
|
||||||
for i, indexB := range addr.ReadonlyIndexes {
|
|
||||||
index := int(indexB)
|
|
||||||
tables[tableKey][index] = readableForTable[i]
|
|
||||||
}
|
|
||||||
readonly = readonly[numTakeReadonly:]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy instructions
|
|
||||||
for _, instr := range yTx.Message.Instructions {
|
|
||||||
sTx.Transaction.Message.Instructions = append(sTx.Transaction.Message.Instructions, types.Instruction{
|
|
||||||
ProgramIDIndex: int(instr.ProgramIdIndex),
|
|
||||||
Accounts: func() []int {
|
|
||||||
var out []int
|
|
||||||
for i := range instr.Accounts {
|
|
||||||
out = append(out, int(instr.Accounts[i]))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}(),
|
|
||||||
Data: instr.Data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve the lookups
|
|
||||||
//{
|
|
||||||
// if sTx.Transaction.Message.IsVersioned() {
|
|
||||||
// // only versioned transactions have address table lookups
|
|
||||||
// err := sTx.Transaction.Message.ResolveLookups()
|
|
||||||
// if err != nil {
|
|
||||||
// return sTx, fmt.Errorf("failed to resolve lookups: %w", err)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
return sTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func byteSlicesToKeySlices(keys [][]byte) []solana2.PublicKey {
|
|
||||||
var out []solana2.PublicKey
|
|
||||||
for _, key := range keys {
|
|
||||||
var k solana2.PublicKey
|
|
||||||
copy(k[:], key)
|
|
||||||
out = append(out, k)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func grpcTokenBalance(src []*pb.TokenBalance) []types.TokenBalance {
|
|
||||||
out := make([]types.TokenBalance, len(src))
|
|
||||||
for i, tb := range src {
|
|
||||||
var (
|
|
||||||
mintAccount solana2.PublicKey
|
|
||||||
ownerAccount solana2.PublicKey
|
|
||||||
programIDAccount solana2.PublicKey
|
|
||||||
)
|
|
||||||
|
|
||||||
if tb.Mint != "" {
|
|
||||||
mintAccount, _ = solana2.PublicKeyFromBase58(tb.Mint)
|
|
||||||
}
|
|
||||||
if tb.Owner != "" {
|
|
||||||
ownerAccount, _ = solana2.PublicKeyFromBase58(tb.Owner)
|
|
||||||
}
|
|
||||||
if tb.ProgramId != "" {
|
|
||||||
programIDAccount, _ = solana2.PublicKeyFromBase58(tb.ProgramId)
|
|
||||||
}
|
|
||||||
|
|
||||||
out[i] = types.TokenBalance{
|
|
||||||
AccountIndex: int(tb.AccountIndex),
|
|
||||||
MintAccount: mintAccount,
|
|
||||||
OwnerAccount: &ownerAccount,
|
|
||||||
ProgramIDAccount: programIDAccount,
|
|
||||||
Mint: tb.Mint,
|
|
||||||
Owner: tb.Owner,
|
|
||||||
ProgramID: tb.ProgramId,
|
|
||||||
UITokenAmount: types.UITokenAmount{
|
|
||||||
Amount: tb.UiTokenAmount.Amount,
|
|
||||||
Decimals: uint64(tb.UiTokenAmount.Decimals),
|
|
||||||
UIAmount: tb.UiTokenAmount.UiAmount,
|
|
||||||
UIAmountString: tb.UiTokenAmount.UiAmountString,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
4
meta.go
4
meta.go
@@ -40,7 +40,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pumpAmmBuyDiscriminator = calculateDiscriminator("global:buy")
|
pumpAmmBuyDiscriminator = calculateDiscriminator("global:buy")
|
||||||
|
pumpAmmBuyV2Discriminator = calculateDiscriminator("global:buy_exact_quote_in")
|
||||||
|
|
||||||
pumpAmmSellDiscriminator = calculateDiscriminator("global:sell")
|
pumpAmmSellDiscriminator = calculateDiscriminator("global:sell")
|
||||||
pumpAmmCreateDiscriminator = calculateDiscriminator("global:create_pool")
|
pumpAmmCreateDiscriminator = calculateDiscriminator("global:create_pool")
|
||||||
pumpAmmWithdrawDiscriminator = calculateDiscriminator("global:withdraw")
|
pumpAmmWithdrawDiscriminator = calculateDiscriminator("global:withdraw")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pump_parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/gagliardetto/solana-go"
|
"github.com/gagliardetto/solana-go"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
@@ -39,6 +40,7 @@ func (tx *Tx) Parser() error {
|
|||||||
tx.Block = tx.rawTx.Slot
|
tx.Block = tx.rawTx.Slot
|
||||||
tx.BlockIndex = uint64(tx.rawTx.IndexWithinBlock)
|
tx.BlockIndex = uint64(tx.rawTx.IndexWithinBlock)
|
||||||
tx.BlockAt = tx.rawTx.BlockTime
|
tx.BlockAt = tx.rawTx.BlockTime
|
||||||
|
tx.CuFee = decimal.NewFromUint64(tx.rawTx.Meta.Fee)
|
||||||
|
|
||||||
tx.BeforeSolBalance = decimal.NewFromUint64(tx.rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9))
|
tx.BeforeSolBalance = decimal.NewFromUint64(tx.rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9))
|
||||||
tx.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9))
|
tx.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9))
|
||||||
@@ -73,6 +75,10 @@ func (tx *Tx) Parser() error {
|
|||||||
// unknown program, parser inner instructions
|
// unknown program, parser inner instructions
|
||||||
innerLength := len(innersMap[i].Instructions)
|
innerLength := len(innersMap[i].Instructions)
|
||||||
for j := 1; j <= innerLength; {
|
for j := 1; j <= innerLength; {
|
||||||
|
if j <= 0 || j > innerLength {
|
||||||
|
log.Printf("inner instruction index is out if range, block: %d, tx: %s, outerIndex: %d, innerIndex: %d", tx.Block, tx.GetTxHash(), ii, j)
|
||||||
|
break
|
||||||
|
}
|
||||||
innerInstr := innersMap[i].Instructions[j-1]
|
innerInstr := innersMap[i].Instructions[j-1]
|
||||||
innerProgramAccount := accountList[innerInstr.ProgramIDIndex]
|
innerProgramAccount := accountList[innerInstr.ProgramIDIndex]
|
||||||
|
|
||||||
|
|||||||
35
pump.go
35
pump.go
@@ -218,6 +218,13 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, increaseOffset(offset), fmt.Errorf("pump create get inner instructions error: %v,offset, %d, %d", err, offset[0], offset[1])
|
return nil, increaseOffset(offset), fmt.Errorf("pump create get inner instructions error: %v,offset, %d, %d", err, offset[0], offset[1])
|
||||||
}
|
}
|
||||||
|
if instruction.StackHeight != nil && *instruction.StackHeight > 2 {
|
||||||
|
for _, innerInstr := range innerInstructions.Instructions {
|
||||||
|
if innerInstr.StackHeight != nil && *innerInstr.StackHeight == *instruction.StackHeight-1 {
|
||||||
|
entryContract = result.accountList[innerInstr.ProgramIDIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for innerIndex, innerInstr := range inners {
|
for innerIndex, innerInstr := range inners {
|
||||||
if innerInstr.ProgramIDIndex == feeEventProgramIndex && bytes.Equal(innerInstr.Data[:8], pumpGetFeesDiscriminator[:]) {
|
if innerInstr.ProgramIDIndex == feeEventProgramIndex && bytes.Equal(innerInstr.Data[:8], pumpGetFeesDiscriminator[:]) {
|
||||||
@@ -262,11 +269,6 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset = [2]uint{newoffset[0], newoffset[1]}
|
offset = [2]uint{newoffset[0], newoffset[1]}
|
||||||
ataUserIdx := instruction.Accounts[5]
|
|
||||||
userIndex := instruction.Accounts[6]
|
|
||||||
|
|
||||||
userBase := getAccountBalanceAfterTx(result, ataUserIdx)
|
|
||||||
userQuote, _ := GetSolAfterTx(result, userIndex)
|
|
||||||
|
|
||||||
event := ""
|
event := ""
|
||||||
baseTokenProgram := solana.TokenProgramID
|
baseTokenProgram := solana.TokenProgramID
|
||||||
@@ -284,6 +286,24 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
Decimals: 6,
|
Decimals: 6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var user = tradeEvent.User
|
||||||
|
|
||||||
|
ataUserIdx := instruction.Accounts[5]
|
||||||
|
userIndex := instruction.Accounts[6]
|
||||||
|
if !tradeEvent.User.IsOnCurve() && (entryContract.Equals(okxDexRoutersV2) || entryContract.Equals(okxAggregatorV2)) {
|
||||||
|
userBaseAmount, ataIndex := tokenBalanceChange(result, 0, baseTokenProgram, tradeEvent.Mint)
|
||||||
|
//&& userBaseAmount.BigInt().Uint64() == tradeEvent.TokenAmount
|
||||||
|
if !userBaseAmount.IsZero() {
|
||||||
|
user = result.accountList[0]
|
||||||
|
userIndex = 0
|
||||||
|
ataUserIdx = ataIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userBase := getAccountBalanceAfterTx(result, ataUserIdx)
|
||||||
|
userQuote, _ := GetSolAfterTx(result, userIndex)
|
||||||
|
|
||||||
solAmount := tradeEvent.SolAmount
|
solAmount := tradeEvent.SolAmount
|
||||||
if tradeEvent.IsBuy && bytes.Equal(instruction.Data[:8], pumpBuyV2Discriminator[:]) {
|
if tradeEvent.IsBuy && bytes.Equal(instruction.Data[:8], pumpBuyV2Discriminator[:]) {
|
||||||
fee := tradeEvent.Fee + tradeEvent.CreatorFee
|
fee := tradeEvent.Fee + tradeEvent.CreatorFee
|
||||||
@@ -304,7 +324,7 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
Creator: tradeEvent.Creator,
|
Creator: tradeEvent.Creator,
|
||||||
BaseMintDecimals: 6,
|
BaseMintDecimals: 6,
|
||||||
QuoteMintDecimals: 9,
|
QuoteMintDecimals: 9,
|
||||||
User: tradeEvent.User,
|
User: user,
|
||||||
BaseAmount: decimal.NewFromUint64(tradeEvent.TokenAmount),
|
BaseAmount: decimal.NewFromUint64(tradeEvent.TokenAmount),
|
||||||
QuoteAmount: decimal.NewFromUint64(solAmount),
|
QuoteAmount: decimal.NewFromUint64(solAmount),
|
||||||
BaseReserve: decimal.NewFromUint64(tradeEvent.RealTokenReserves),
|
BaseReserve: decimal.NewFromUint64(tradeEvent.RealTokenReserves),
|
||||||
@@ -327,13 +347,14 @@ func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerIns
|
|||||||
Creator: tradeEvent.Creator,
|
Creator: tradeEvent.Creator,
|
||||||
BaseMintDecimals: 6,
|
BaseMintDecimals: 6,
|
||||||
QuoteMintDecimals: 9,
|
QuoteMintDecimals: 9,
|
||||||
User: tradeEvent.User,
|
User: user,
|
||||||
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[1]]),
|
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[1]]),
|
||||||
UserBaseBalance: userBase,
|
UserBaseBalance: userBase,
|
||||||
UserQuoteBalance: decimal.NewFromUint64(userQuote),
|
UserQuoteBalance: decimal.NewFromUint64(userQuote),
|
||||||
EntryContract: entryContract,
|
EntryContract: entryContract,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return swaps, offset, nil
|
return swaps, offset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
75
pumpamm.go
75
pumpamm.go
@@ -149,7 +149,7 @@ func pumpAmmParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
|
|||||||
switch discriminator {
|
switch discriminator {
|
||||||
case pumpAmmCreateDiscriminator:
|
case pumpAmmCreateDiscriminator:
|
||||||
return ammCreatePoolParser(tx, instruction, innerInstructions, offset)
|
return ammCreatePoolParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmBuyDiscriminator:
|
case pumpAmmBuyDiscriminator, pumpAmmBuyV2Discriminator:
|
||||||
return ammBuyParser(tx, instruction, innerInstructions, offset)
|
return ammBuyParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmSellDiscriminator:
|
case pumpAmmSellDiscriminator:
|
||||||
return ammSellParser(tx, instruction, innerInstructions, offset)
|
return ammSellParser(tx, instruction, innerInstructions, offset)
|
||||||
@@ -245,6 +245,14 @@ func ammBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstru
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, increaseOffset(offset), fmt.Errorf("pumpamm create get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen)
|
return nil, increaseOffset(offset), fmt.Errorf("pumpamm create get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen)
|
||||||
}
|
}
|
||||||
|
if instruction.StackHeight != nil && *instruction.StackHeight > 2 {
|
||||||
|
for _, innerInstr := range innerInstructions.Instructions {
|
||||||
|
if innerInstr.StackHeight != nil && *innerInstr.StackHeight == *instruction.StackHeight-1 {
|
||||||
|
entryContract = result.accountList[innerInstr.ProgramIDIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var event ammBuyEvent
|
var event ammBuyEvent
|
||||||
for innerIndex, innerInstr := range inners {
|
for innerIndex, innerInstr := range inners {
|
||||||
if innerInstr.ProgramIDIndex == instruction.ProgramIDIndex &&
|
if innerInstr.ProgramIDIndex == instruction.ProgramIDIndex &&
|
||||||
@@ -298,6 +306,28 @@ func ammBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstru
|
|||||||
TokenProgram: quoteTokenProgram,
|
TokenProgram: quoteTokenProgram,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var eventUser = event.User
|
||||||
|
|
||||||
|
baseMintAtaUserIdx := instruction.Accounts[5]
|
||||||
|
userIndex := instruction.Accounts[1]
|
||||||
|
if !event.User.IsOnCurve() && (entryContract.Equals(okxDexRoutersV2) || entryContract.Equals(okxAggregatorV2)) {
|
||||||
|
userBaseAmount, ataIndex := tokenBalanceChange(result, 0, baseTokenProgram, baseMint)
|
||||||
|
// && userBaseAmount.BigInt().Uint64() == event.BaseAmountOut
|
||||||
|
if !userBaseAmount.IsZero() {
|
||||||
|
eventUser = result.accountList[0]
|
||||||
|
userIndex = 0
|
||||||
|
baseMintAtaUserIdx = ataIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userBase := getAccountBalanceAfterTx(result, baseMintAtaUserIdx)
|
||||||
|
userQuote := GetTokenBalanceAfterTx(result, userIndex, quoteTokenProgram, quoteMint)
|
||||||
|
|
||||||
|
if quoteMint.Equals(wSolMint) {
|
||||||
|
userBalance, _ := GetSolAfterTx(result, userIndex)
|
||||||
|
userQuote = userQuote.Add(decimal.NewFromUint64(userBalance))
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
@@ -310,14 +340,14 @@ func ammBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstru
|
|||||||
Creator: event.CoinCreator,
|
Creator: event.CoinCreator,
|
||||||
BaseMintDecimals: baseMintDecimals,
|
BaseMintDecimals: baseMintDecimals,
|
||||||
QuoteMintDecimals: quoteMintDecimals,
|
QuoteMintDecimals: quoteMintDecimals,
|
||||||
User: event.User,
|
User: eventUser,
|
||||||
BaseAmount: decimal.NewFromUint64(event.BaseAmountOut),
|
BaseAmount: decimal.NewFromUint64(event.BaseAmountOut),
|
||||||
QuoteAmount: decimal.NewFromUint64(event.UserQuoteAmountIn),
|
QuoteAmount: decimal.NewFromUint64(event.UserQuoteAmountIn),
|
||||||
BaseReserve: decimal.NewFromUint64(event.PoolBaseTokenReserve - event.BaseAmountOut),
|
BaseReserve: decimal.NewFromUint64(event.PoolBaseTokenReserve - event.BaseAmountOut),
|
||||||
QuoteReserve: decimal.NewFromUint64(event.PoolQuoteTokenReserve + event.QuoteAmountIn),
|
QuoteReserve: decimal.NewFromUint64(event.PoolQuoteTokenReserve + event.QuoteAmountIn),
|
||||||
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[9]]),
|
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[9]]),
|
||||||
UserBaseBalance: decimal.NewFromUint64(event.UserBaseTokenReserve + event.BaseAmountOut),
|
UserBaseBalance: userBase,
|
||||||
UserQuoteBalance: decimal.NewFromUint64(event.UserQuoteTokenReserve - event.UserQuoteAmountIn),
|
UserQuoteBalance: userQuote,
|
||||||
EntryContract: entryContract,
|
EntryContract: entryContract,
|
||||||
},
|
},
|
||||||
}, offset, nil
|
}, offset, nil
|
||||||
@@ -332,6 +362,15 @@ func ammSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, increaseOffset(offset), fmt.Errorf("pumpamm sell get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen)
|
return nil, increaseOffset(offset), fmt.Errorf("pumpamm sell get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if instruction.StackHeight != nil && *instruction.StackHeight > 2 {
|
||||||
|
for _, innerInstr := range innerInstructions.Instructions {
|
||||||
|
if innerInstr.StackHeight != nil && *innerInstr.StackHeight == *instruction.StackHeight-1 {
|
||||||
|
entryContract = result.accountList[innerInstr.ProgramIDIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var event ammSellEvent
|
var event ammSellEvent
|
||||||
for innerIndex, innerInstr := range inners {
|
for innerIndex, innerInstr := range inners {
|
||||||
if innerInstr.ProgramIDIndex == instruction.ProgramIDIndex &&
|
if innerInstr.ProgramIDIndex == instruction.ProgramIDIndex &&
|
||||||
@@ -385,6 +424,28 @@ func ammSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
|
|||||||
TokenProgram: quoteTokenProgram,
|
TokenProgram: quoteTokenProgram,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var eventUser = event.User
|
||||||
|
|
||||||
|
baseMintAtaUserIdx := instruction.Accounts[5]
|
||||||
|
userIndex := instruction.Accounts[1]
|
||||||
|
if !event.User.IsOnCurve() && (entryContract.Equals(okxDexRoutersV2) || entryContract.Equals(okxAggregatorV2)) {
|
||||||
|
userBaseAmount, ataIndex := tokenBalanceChange(result, 0, baseTokenProgram, baseMint)
|
||||||
|
// && userBaseAmount.BigInt().Uint64() == event.BaseAmountIn
|
||||||
|
if !userBaseAmount.IsZero() {
|
||||||
|
eventUser = result.accountList[0]
|
||||||
|
userIndex = 0
|
||||||
|
baseMintAtaUserIdx = ataIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userBase := getAccountBalanceAfterTx(result, baseMintAtaUserIdx)
|
||||||
|
userQuote := GetTokenBalanceAfterTx(result, userIndex, quoteTokenProgram, quoteMint)
|
||||||
|
|
||||||
|
if quoteMint.Equals(wSolMint) {
|
||||||
|
userBalance, _ := GetSolAfterTx(result, userIndex)
|
||||||
|
userQuote = userQuote.Add(decimal.NewFromUint64(userBalance))
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
@@ -397,14 +458,14 @@ func ammSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
|
|||||||
Creator: event.CoinCreator,
|
Creator: event.CoinCreator,
|
||||||
BaseMintDecimals: baseMintDecimals,
|
BaseMintDecimals: baseMintDecimals,
|
||||||
QuoteMintDecimals: quoteMintDecimals,
|
QuoteMintDecimals: quoteMintDecimals,
|
||||||
User: event.User,
|
User: eventUser,
|
||||||
BaseAmount: decimal.NewFromUint64(event.BaseAmountIn),
|
BaseAmount: decimal.NewFromUint64(event.BaseAmountIn),
|
||||||
QuoteAmount: decimal.NewFromUint64(event.UserQuoteAmountOut),
|
QuoteAmount: decimal.NewFromUint64(event.UserQuoteAmountOut),
|
||||||
BaseReserve: decimal.NewFromUint64(event.PoolBaseTokenReserves + event.BaseAmountIn),
|
BaseReserve: decimal.NewFromUint64(event.PoolBaseTokenReserves + event.BaseAmountIn),
|
||||||
QuoteReserve: decimal.NewFromUint64(event.PoolQuoteTokenReserves - event.QuoteAmountOut),
|
QuoteReserve: decimal.NewFromUint64(event.PoolQuoteTokenReserves - event.QuoteAmountOut),
|
||||||
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[9]]),
|
Mayhem: isMayhemPump(result.accountList[instruction.Accounts[9]]),
|
||||||
UserBaseBalance: decimal.NewFromUint64(event.UserBaseTokenReserves - event.BaseAmountIn),
|
UserBaseBalance: userBase,
|
||||||
UserQuoteBalance: decimal.NewFromUint64(event.UserQuoteTokenReserves + event.UserQuoteAmountOut),
|
UserQuoteBalance: userQuote,
|
||||||
EntryContract: entryContract,
|
EntryContract: entryContract,
|
||||||
},
|
},
|
||||||
}, offset, nil
|
}, offset, nil
|
||||||
|
|||||||
483
rawtx.go
483
rawtx.go
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/gagliardetto/solana-go/rpc"
|
"github.com/gagliardetto/solana-go/rpc"
|
||||||
"github.com/jackc/pgtype"
|
"github.com/jackc/pgtype"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
pb "go.onsig.ai/onsig/yellowstone-proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (tx *RawTx) getAccountList() []solana.PublicKey {
|
func (tx *RawTx) getAccountList() []solana.PublicKey {
|
||||||
@@ -292,6 +293,198 @@ func InstructionsFromRpc(instructions []solana.CompiledInstruction) []Instructio
|
|||||||
return instrs
|
return instrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FromRpcTransactionWithMeta(tx rpc.TransactionWithMeta, blockTime *uint64, slot uint64, index int64) (*RawTx, error) {
|
||||||
|
created := int64(0)
|
||||||
|
if blockTime != nil {
|
||||||
|
created = int64(*blockTime)
|
||||||
|
}
|
||||||
|
sTx := &RawTx{
|
||||||
|
BlockTime: created,
|
||||||
|
Slot: slot,
|
||||||
|
IndexWithinBlock: index,
|
||||||
|
Meta: Meta{
|
||||||
|
Err: nil,
|
||||||
|
Fee: 0,
|
||||||
|
InnerInstructions: nil,
|
||||||
|
LoadedAddresses: LoadedAddresses{},
|
||||||
|
LogMessages: nil,
|
||||||
|
PostBalances: nil,
|
||||||
|
PostTokenBalances: nil,
|
||||||
|
PreBalances: nil,
|
||||||
|
PreTokenBalances: nil,
|
||||||
|
Rewards: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
meta := tx.Meta
|
||||||
|
yTx, _ := tx.GetTransaction()
|
||||||
|
|
||||||
|
if meta.Err != nil {
|
||||||
|
e, _ := json.Marshal(meta.Err)
|
||||||
|
sTx.Meta.Err = string(e)
|
||||||
|
}
|
||||||
|
sTx.Meta.Fee = meta.Fee
|
||||||
|
//sTx.Meta.InnerInstructions = meta.InnerInstructions
|
||||||
|
|
||||||
|
for _, innerInstr := range meta.InnerInstructions {
|
||||||
|
var instrs []Instruction
|
||||||
|
for _, instr := range innerInstr.Instructions {
|
||||||
|
instrs = append(instrs, Instruction{
|
||||||
|
ProgramIDIndex: int(instr.ProgramIDIndex),
|
||||||
|
Accounts: func() []int {
|
||||||
|
var out []int
|
||||||
|
for i := range instr.Accounts {
|
||||||
|
out = append(out, int(instr.Accounts[i]))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}(),
|
||||||
|
Data: instr.Data,
|
||||||
|
StackHeight: newInt16(instr.StackHeight),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sTx.Meta.InnerInstructions = append(sTx.Meta.InnerInstructions, InnerInstructions{
|
||||||
|
Index: int(innerInstr.Index),
|
||||||
|
Instructions: instrs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sTx.Meta.LogMessages = meta.LogMessages
|
||||||
|
sTx.Meta.PostBalances = meta.PostBalances
|
||||||
|
sTx.Meta.PreBalances = meta.PreBalances
|
||||||
|
sTx.Meta.PostTokenBalances = convertTokenBalanceFromRpc(meta.PostTokenBalances)
|
||||||
|
sTx.Meta.PreTokenBalances = convertTokenBalanceFromRpc(meta.PreTokenBalances)
|
||||||
|
sTx.Meta.Rewards = nil
|
||||||
|
sTx.Meta.LoadedAddresses.Readonly = meta.LoadedAddresses.ReadOnly
|
||||||
|
sTx.Meta.LoadedAddresses.Writable = meta.LoadedAddresses.Writable
|
||||||
|
|
||||||
|
// copy signatures
|
||||||
|
for i := range yTx.Signatures {
|
||||||
|
sTx.Transaction.Signatures = append(sTx.Transaction.Signatures, yTx.Signatures[i])
|
||||||
|
}
|
||||||
|
// copy message
|
||||||
|
sTx.Transaction.Message = Message{
|
||||||
|
RecentBlockHash: yTx.Message.RecentBlockhash.String(),
|
||||||
|
}
|
||||||
|
// copy message.AccountKeys
|
||||||
|
//stopAt := len(yTx.Message.AccountKeys) - sTx.Message.NumLookups()
|
||||||
|
stopAt := len(yTx.Message.AccountKeys)
|
||||||
|
for accIndex, acc := range yTx.Message.AccountKeys {
|
||||||
|
sTx.Transaction.Message.AccountKeys = append(sTx.Transaction.Message.AccountKeys, acc)
|
||||||
|
if accIndex == stopAt-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy message.Header
|
||||||
|
sTx.Transaction.Message.Header = Header{
|
||||||
|
NumRequiredSignatures: int(yTx.Message.Header.NumRequiredSignatures),
|
||||||
|
NumReadonlySignedAccounts: int(yTx.Message.Header.NumReadonlySignedAccounts),
|
||||||
|
NumReadonlyUnsignedAccounts: int(yTx.Message.Header.NumReadonlyUnsignedAccounts),
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy message.versioned
|
||||||
|
if yTx.Message.IsVersioned() {
|
||||||
|
sTx.Version = solana.MessageVersionV0
|
||||||
|
} else {
|
||||||
|
sTx.Version = solana.MessageVersionLegacy
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy address table lookups
|
||||||
|
{
|
||||||
|
tables := map[solana.PublicKey]solana.PublicKeySlice{}
|
||||||
|
writable := meta.LoadedAddresses.Writable
|
||||||
|
readonly := meta.LoadedAddresses.ReadOnly
|
||||||
|
for _, addr := range yTx.Message.AddressTableLookups {
|
||||||
|
sTx.Transaction.Message.AddressTableLookups = append(sTx.Transaction.Message.AddressTableLookups, solana.MessageAddressTableLookup{
|
||||||
|
AccountKey: addr.AccountKey,
|
||||||
|
WritableIndexes: addr.WritableIndexes,
|
||||||
|
ReadonlyIndexes: addr.ReadonlyIndexes,
|
||||||
|
})
|
||||||
|
numTakeWritable := len(addr.WritableIndexes)
|
||||||
|
numTakeReadonly := len(addr.ReadonlyIndexes)
|
||||||
|
tableKey := addr.AccountKey
|
||||||
|
{
|
||||||
|
// now need to rebuild the address table taking into account the indexes, and put the keys into the tables
|
||||||
|
maxIndex := 0
|
||||||
|
for _, indexB := range addr.WritableIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
if index > maxIndex {
|
||||||
|
maxIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, indexB := range addr.ReadonlyIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
if index > maxIndex {
|
||||||
|
maxIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tables[tableKey] = make([]solana.PublicKey, maxIndex+1)
|
||||||
|
}
|
||||||
|
if numTakeWritable > 0 {
|
||||||
|
writableForTable := writable[:numTakeWritable]
|
||||||
|
for i, indexB := range addr.WritableIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
tables[tableKey][index] = writableForTable[i]
|
||||||
|
}
|
||||||
|
writable = writable[numTakeWritable:]
|
||||||
|
}
|
||||||
|
if numTakeReadonly > 0 {
|
||||||
|
readableForTable := readonly[:numTakeReadonly]
|
||||||
|
for i, indexB := range addr.ReadonlyIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
tables[tableKey][index] = readableForTable[i]
|
||||||
|
}
|
||||||
|
readonly = readonly[numTakeReadonly:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy instructions
|
||||||
|
for _, instr := range yTx.Message.Instructions {
|
||||||
|
sTx.Transaction.Message.Instructions = append(sTx.Transaction.Message.Instructions, Instruction{
|
||||||
|
ProgramIDIndex: int(instr.ProgramIDIndex),
|
||||||
|
Accounts: func() []int {
|
||||||
|
var out []int
|
||||||
|
for i := range instr.Accounts {
|
||||||
|
out = append(out, int(instr.Accounts[i]))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}(),
|
||||||
|
Data: instr.Data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return sTx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertTokenBalanceFromRpc(tb []rpc.TokenBalance) []TokenBalance {
|
||||||
|
var tokenBalances []TokenBalance = make([]TokenBalance, len(tb))
|
||||||
|
for i, balance := range tb {
|
||||||
|
var uiAmount = float64(0)
|
||||||
|
if balance.UiTokenAmount.UiAmount != nil {
|
||||||
|
uiAmount = *balance.UiTokenAmount.UiAmount
|
||||||
|
}
|
||||||
|
tokenBalances[i] = TokenBalance{
|
||||||
|
AccountIndex: int(balance.AccountIndex),
|
||||||
|
MintAccount: balance.Mint,
|
||||||
|
OwnerAccount: balance.Owner,
|
||||||
|
ProgramIDAccount: func() solana.PublicKey {
|
||||||
|
if balance.ProgramId != nil {
|
||||||
|
return *balance.ProgramId
|
||||||
|
}
|
||||||
|
return solana.PublicKey{}
|
||||||
|
}(),
|
||||||
|
UITokenAmount: UITokenAmount{
|
||||||
|
Amount: balance.UiTokenAmount.Amount,
|
||||||
|
Decimals: uint64(balance.UiTokenAmount.Decimals),
|
||||||
|
UIAmount: uiAmount,
|
||||||
|
UIAmountString: balance.UiTokenAmount.UiAmountString,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenBalances
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func InnerInstructionsFromRpc(instructions []rpc.InnerInstruction) []InnerInstructions {
|
func InnerInstructionsFromRpc(instructions []rpc.InnerInstruction) []InnerInstructions {
|
||||||
var innerInstructions []InnerInstructions = make([]InnerInstructions, len(instructions))
|
var innerInstructions []InnerInstructions = make([]InnerInstructions, len(instructions))
|
||||||
for i, instruction := range instructions {
|
for i, instruction := range instructions {
|
||||||
@@ -374,6 +567,49 @@ func getAccountBalanceAfterTx(result *RawTx, accountIndex int) decimal.Decimal {
|
|||||||
return amount
|
return amount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tokenBalanceChange(result *RawTx, accountIndex int, tokenProgram, mint solana.PublicKey) (change decimal.Decimal, ataIndex int) {
|
||||||
|
ataAccount, _, _ := solana.FindProgramAddress([][]byte{
|
||||||
|
result.accountList[accountIndex][:],
|
||||||
|
tokenProgram[:],
|
||||||
|
mint[:],
|
||||||
|
},
|
||||||
|
solana.SPLAssociatedTokenAccountProgramID)
|
||||||
|
|
||||||
|
for i, account := range result.accountList {
|
||||||
|
if account.Equals(ataAccount) {
|
||||||
|
ataIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ataIndex == 0 {
|
||||||
|
return decimal.Zero, ataIndex
|
||||||
|
}
|
||||||
|
before := decimal.Zero
|
||||||
|
after := decimal.Zero
|
||||||
|
|
||||||
|
for _, pre := range result.Meta.PreTokenBalances {
|
||||||
|
if pre.AccountIndex == ataIndex {
|
||||||
|
amount, err := decimal.NewFromString(pre.UITokenAmount.Amount)
|
||||||
|
if err != nil {
|
||||||
|
return decimal.Zero, ataIndex
|
||||||
|
}
|
||||||
|
before = amount
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, post := range result.Meta.PostTokenBalances {
|
||||||
|
if post.AccountIndex == ataIndex {
|
||||||
|
amount, err := decimal.NewFromString(post.UITokenAmount.Amount)
|
||||||
|
if err != nil {
|
||||||
|
return decimal.Zero, ataIndex
|
||||||
|
}
|
||||||
|
after = amount
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return after.Sub(before).Abs(), ataIndex
|
||||||
|
}
|
||||||
|
|
||||||
func GetTokenBalanceAfterTx(result *RawTx, accountIndex int, tokenProgram, mint solana.PublicKey) decimal.Decimal {
|
func GetTokenBalanceAfterTx(result *RawTx, accountIndex int, tokenProgram, mint solana.PublicKey) decimal.Decimal {
|
||||||
ataAccount, _, _ := solana.FindProgramAddress([][]byte{
|
ataAccount, _, _ := solana.FindProgramAddress([][]byte{
|
||||||
result.accountList[accountIndex][:],
|
result.accountList[accountIndex][:],
|
||||||
@@ -445,3 +681,250 @@ func isAccountOwner(account, owner, mint solana.PublicKey) (bool, error) {
|
|||||||
}
|
}
|
||||||
return account == ata, nil
|
return account == ata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertYellowstoneGrpcTransactionToSolanaTransaction(y *pb.SubscribeUpdateTransaction, created int64) (*RawTx, error) {
|
||||||
|
sTx := &RawTx{
|
||||||
|
BlockTime: created,
|
||||||
|
Slot: y.Slot,
|
||||||
|
IndexWithinBlock: int64(y.Transaction.Index),
|
||||||
|
Meta: Meta{
|
||||||
|
Err: nil,
|
||||||
|
Fee: 0,
|
||||||
|
InnerInstructions: nil,
|
||||||
|
LoadedAddresses: LoadedAddresses{},
|
||||||
|
LogMessages: nil,
|
||||||
|
PostBalances: nil,
|
||||||
|
PostTokenBalances: nil,
|
||||||
|
PreBalances: nil,
|
||||||
|
PreTokenBalances: nil,
|
||||||
|
Rewards: nil,
|
||||||
|
},
|
||||||
|
//Transaction: types.Transaction{
|
||||||
|
// Message: types.Message{
|
||||||
|
// AccountKeys: nil,
|
||||||
|
// AddressTableLookups: nil,
|
||||||
|
// Header: types.Header{},
|
||||||
|
// Instructions: nil,
|
||||||
|
// RecentBlockHash: "",
|
||||||
|
// },
|
||||||
|
// Signatures: nil,
|
||||||
|
//},
|
||||||
|
//Version: nil,
|
||||||
|
}
|
||||||
|
meta := y.Transaction.GetMeta()
|
||||||
|
yTx := y.Transaction.Transaction
|
||||||
|
|
||||||
|
if meta.Err != nil && len(meta.Err.GetErr()) > 0 {
|
||||||
|
// If the transaction has an error, we set the error in the Meta
|
||||||
|
transError, err := DecodeTransactionError(meta.Err.GetErr())
|
||||||
|
if err != nil {
|
||||||
|
sTx.Meta.Err = err
|
||||||
|
} else {
|
||||||
|
sTx.Meta.Err = transError
|
||||||
|
}
|
||||||
|
// sTx.Meta.Err = meta.Err.GetErr()
|
||||||
|
}
|
||||||
|
sTx.Meta.Fee = meta.Fee
|
||||||
|
//sTx.Meta.InnerInstructions = meta.InnerInstructions
|
||||||
|
|
||||||
|
for _, innerInstr := range meta.InnerInstructions {
|
||||||
|
var instrs []Instruction
|
||||||
|
for _, instr := range innerInstr.Instructions {
|
||||||
|
instrs = append(instrs, Instruction{
|
||||||
|
ProgramIDIndex: int(instr.ProgramIdIndex),
|
||||||
|
Accounts: func() []int {
|
||||||
|
var out []int
|
||||||
|
for i := range instr.Accounts {
|
||||||
|
out = append(out, int(instr.Accounts[i]))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}(),
|
||||||
|
Data: instr.Data,
|
||||||
|
StackHeight: newInt(instr.StackHeight),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sTx.Meta.InnerInstructions = append(sTx.Meta.InnerInstructions, InnerInstructions{
|
||||||
|
Index: int(innerInstr.Index),
|
||||||
|
Instructions: instrs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sTx.Meta.LogMessages = meta.LogMessages
|
||||||
|
sTx.Meta.PostBalances = meta.PostBalances
|
||||||
|
sTx.Meta.PostTokenBalances = grpcTokenBalance(meta.PostTokenBalances)
|
||||||
|
sTx.Meta.PreBalances = meta.PreBalances
|
||||||
|
sTx.Meta.PreTokenBalances = grpcTokenBalance(meta.PreTokenBalances)
|
||||||
|
sTx.Meta.Rewards = nil
|
||||||
|
sTx.Meta.LoadedAddresses.Readonly = byteSlicesToKeySlices(meta.LoadedReadonlyAddresses)
|
||||||
|
sTx.Meta.LoadedAddresses.Writable = byteSlicesToKeySlices(meta.LoadedWritableAddresses)
|
||||||
|
|
||||||
|
// copy signatures
|
||||||
|
for i := range yTx.Signatures {
|
||||||
|
sTx.Transaction.Signatures = append(sTx.Transaction.Signatures, solana.SignatureFromBytes(yTx.Signatures[i]))
|
||||||
|
}
|
||||||
|
// copy message
|
||||||
|
sTx.Transaction.Message = Message{
|
||||||
|
RecentBlockHash: solana.HashFromBytes(yTx.Message.RecentBlockhash).String(),
|
||||||
|
}
|
||||||
|
// copy message.AccountKeys
|
||||||
|
//stopAt := len(yTx.Message.AccountKeys) - sTx.Message.NumLookups()
|
||||||
|
stopAt := len(yTx.Message.AccountKeys)
|
||||||
|
for accIndex, acc := range yTx.Message.AccountKeys {
|
||||||
|
sTx.Transaction.Message.AccountKeys = append(sTx.Transaction.Message.AccountKeys, solana.PublicKeyFromBytes(acc))
|
||||||
|
if accIndex == stopAt-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy message.Header
|
||||||
|
sTx.Transaction.Message.Header = Header{
|
||||||
|
NumRequiredSignatures: int(yTx.Message.Header.NumRequiredSignatures),
|
||||||
|
NumReadonlySignedAccounts: int(yTx.Message.Header.NumReadonlySignedAccounts),
|
||||||
|
NumReadonlyUnsignedAccounts: int(yTx.Message.Header.NumReadonlyUnsignedAccounts),
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy message.versioned
|
||||||
|
if yTx.Message.Versioned {
|
||||||
|
sTx.Version = solana.MessageVersionV0
|
||||||
|
} else {
|
||||||
|
sTx.Version = solana.MessageVersionLegacy
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy address table lookups
|
||||||
|
{
|
||||||
|
tables := map[solana.PublicKey]solana.PublicKeySlice{}
|
||||||
|
writable := byteSlicesToKeySlices(meta.LoadedWritableAddresses)
|
||||||
|
readonly := byteSlicesToKeySlices(meta.LoadedReadonlyAddresses)
|
||||||
|
for _, addr := range yTx.Message.AddressTableLookups {
|
||||||
|
sTx.Transaction.Message.AddressTableLookups = append(sTx.Transaction.Message.AddressTableLookups, solana.MessageAddressTableLookup{
|
||||||
|
AccountKey: solana.PublicKeyFromBytes(addr.AccountKey),
|
||||||
|
WritableIndexes: addr.WritableIndexes,
|
||||||
|
ReadonlyIndexes: addr.ReadonlyIndexes,
|
||||||
|
})
|
||||||
|
numTakeWritable := len(addr.WritableIndexes)
|
||||||
|
numTakeReadonly := len(addr.ReadonlyIndexes)
|
||||||
|
tableKey := solana.PublicKeyFromBytes(addr.AccountKey)
|
||||||
|
{
|
||||||
|
// now need to rebuild the address table taking into account the indexes, and put the keys into the tables
|
||||||
|
maxIndex := 0
|
||||||
|
for _, indexB := range addr.WritableIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
if index > maxIndex {
|
||||||
|
maxIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, indexB := range addr.ReadonlyIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
if index > maxIndex {
|
||||||
|
maxIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tables[tableKey] = make([]solana.PublicKey, maxIndex+1)
|
||||||
|
}
|
||||||
|
if numTakeWritable > 0 {
|
||||||
|
writableForTable := writable[:numTakeWritable]
|
||||||
|
for i, indexB := range addr.WritableIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
tables[tableKey][index] = writableForTable[i]
|
||||||
|
}
|
||||||
|
writable = writable[numTakeWritable:]
|
||||||
|
}
|
||||||
|
if numTakeReadonly > 0 {
|
||||||
|
readableForTable := readonly[:numTakeReadonly]
|
||||||
|
for i, indexB := range addr.ReadonlyIndexes {
|
||||||
|
index := int(indexB)
|
||||||
|
tables[tableKey][index] = readableForTable[i]
|
||||||
|
}
|
||||||
|
readonly = readonly[numTakeReadonly:]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy instructions
|
||||||
|
for _, instr := range yTx.Message.Instructions {
|
||||||
|
sTx.Transaction.Message.Instructions = append(sTx.Transaction.Message.Instructions, Instruction{
|
||||||
|
ProgramIDIndex: int(instr.ProgramIdIndex),
|
||||||
|
Accounts: func() []int {
|
||||||
|
var out []int
|
||||||
|
for i := range instr.Accounts {
|
||||||
|
out = append(out, int(instr.Accounts[i]))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}(),
|
||||||
|
Data: instr.Data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve the lookups
|
||||||
|
//{
|
||||||
|
// if sTx.Transaction.Message.IsVersioned() {
|
||||||
|
// // only versioned transactions have address table lookups
|
||||||
|
// err := sTx.Transaction.Message.ResolveLookups()
|
||||||
|
// if err != nil {
|
||||||
|
// return sTx, fmt.Errorf("failed to resolve lookups: %w", err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
return sTx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInt16(x uint16) *int {
|
||||||
|
y := int(x)
|
||||||
|
return &y
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInt(x *uint32) *int {
|
||||||
|
if x == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
y := int(*x)
|
||||||
|
return &y
|
||||||
|
}
|
||||||
|
|
||||||
|
func byteSlicesToKeySlices(keys [][]byte) []solana.PublicKey {
|
||||||
|
var out []solana.PublicKey
|
||||||
|
for _, key := range keys {
|
||||||
|
var k solana.PublicKey
|
||||||
|
copy(k[:], key)
|
||||||
|
out = append(out, k)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func grpcTokenBalance(src []*pb.TokenBalance) []TokenBalance {
|
||||||
|
out := make([]TokenBalance, len(src))
|
||||||
|
for i, tb := range src {
|
||||||
|
var (
|
||||||
|
mintAccount solana.PublicKey
|
||||||
|
ownerAccount solana.PublicKey
|
||||||
|
programIDAccount solana.PublicKey
|
||||||
|
)
|
||||||
|
|
||||||
|
if tb.Mint != "" {
|
||||||
|
mintAccount, _ = solana.PublicKeyFromBase58(tb.Mint)
|
||||||
|
}
|
||||||
|
if tb.Owner != "" {
|
||||||
|
ownerAccount, _ = solana.PublicKeyFromBase58(tb.Owner)
|
||||||
|
}
|
||||||
|
if tb.ProgramId != "" {
|
||||||
|
programIDAccount, _ = solana.PublicKeyFromBase58(tb.ProgramId)
|
||||||
|
}
|
||||||
|
|
||||||
|
out[i] = TokenBalance{
|
||||||
|
AccountIndex: int(tb.AccountIndex),
|
||||||
|
MintAccount: mintAccount,
|
||||||
|
OwnerAccount: &ownerAccount,
|
||||||
|
ProgramIDAccount: programIDAccount,
|
||||||
|
Mint: tb.Mint,
|
||||||
|
Owner: tb.Owner,
|
||||||
|
ProgramID: tb.ProgramId,
|
||||||
|
UITokenAmount: UITokenAmount{
|
||||||
|
Amount: tb.UiTokenAmount.Amount,
|
||||||
|
Decimals: uint64(tb.UiTokenAmount.Decimals),
|
||||||
|
UIAmount: tb.UiTokenAmount.UiAmount,
|
||||||
|
UIAmountString: tb.UiTokenAmount.UiAmountString,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,9 +31,16 @@ func TransferParser(result *RawTx, instruction Instruction, offset [2]uint, tx *
|
|||||||
}
|
}
|
||||||
var lamports uint64 = binary.LittleEndian.Uint64(decodeData)
|
var lamports uint64 = binary.LittleEndian.Uint64(decodeData)
|
||||||
|
|
||||||
//from := result.accountList[result.Transaction.Message.Instructions[offset[0]].Accounts[0]]
|
from := result.accountList[result.Transaction.Message.Instructions[offset[0]].Accounts[0]]
|
||||||
to := result.accountList[instruction.Accounts[1]]
|
to := result.accountList[instruction.Accounts[1]]
|
||||||
|
|
||||||
|
if offset[1] == 0 {
|
||||||
|
tx.SolTransfer = append(tx.SolTransfer, SolTransfer{
|
||||||
|
From: from,
|
||||||
|
To: to,
|
||||||
|
Amount: decimal.NewFromInt(int64(lamports)), // solana decimals
|
||||||
|
})
|
||||||
|
}
|
||||||
// load platform by to address
|
// load platform by to address
|
||||||
platform, ok := platformFeeAddresses[to]
|
platform, ok := platformFeeAddresses[to]
|
||||||
if ok {
|
if ok {
|
||||||
|
|||||||
33
tx.go
33
tx.go
@@ -45,15 +45,24 @@ type mevInfo struct {
|
|||||||
MevAgentFee decimal.Decimal
|
MevAgentFee decimal.Decimal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SolTransfer struct {
|
||||||
|
From solana.PublicKey
|
||||||
|
To solana.PublicKey
|
||||||
|
Amount decimal.Decimal
|
||||||
|
}
|
||||||
|
|
||||||
type Tx struct {
|
type Tx struct {
|
||||||
rawTx *RawTx
|
rawTx *RawTx
|
||||||
Signer solana.PublicKey
|
Signer solana.PublicKey
|
||||||
Err interface{} `json:"err,omitempty"`
|
Err interface{} `json:"err,omitempty"`
|
||||||
Swaps []Swap `json:"swaps,omitempty"`
|
Swaps []Swap `json:"swaps,omitempty"`
|
||||||
Block uint64 `json:"block"`
|
SolTransfer []SolTransfer `json:"sol_transfer,omitempty"`
|
||||||
BlockIndex uint64 `json:"index"`
|
Block uint64 `json:"block"`
|
||||||
TxHash *[64]byte `json:"-"`
|
BlockIndex uint64 `json:"index"`
|
||||||
BlockAt int64 `json:"block_at"`
|
TxHash *[64]byte `json:"-"`
|
||||||
|
BlockAt int64 `json:"block_at"`
|
||||||
|
|
||||||
|
CuFee decimal.Decimal `json:"cu_fee"`
|
||||||
|
|
||||||
cachedTxHash string
|
cachedTxHash string
|
||||||
|
|
||||||
@@ -174,3 +183,11 @@ func (s Swap) CheckEntryContract() string {
|
|||||||
}
|
}
|
||||||
return EntryContractUnknown
|
return EntryContractUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Swap) CheckEntryContractV2() string {
|
||||||
|
name, ok := entryContractAddresses[s.EntryContract]
|
||||||
|
if ok {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
return s.EntryContract.String()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user