add solana explorer subtreams
This commit is contained in:
6
solana-explorer/.gitignore
vendored
Normal file
6
solana-explorer/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.vscode
|
||||
.idea
|
||||
.DS_Store
|
||||
buf.gen.yaml
|
||||
/target
|
||||
*.spkg
|
||||
10
solana-explorer/.gitpod.yml
Normal file
10
solana-explorer/.gitpod.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
image: ghcr.io/graphprotocol/substreams-gitpod:latest
|
||||
tasks:
|
||||
- command: |
|
||||
# Authenticate with the substreams server
|
||||
export SUBSTREAMS_API_TOKEN=$(curl https://auth.dfuse.io/v1/auth/issue -s --data-binary '{"api_key":"'$STREAMINGFAST_KEY'"}' | jq -r .token)
|
||||
ports:
|
||||
- port: 6060
|
||||
onOpen: ignore
|
||||
- port: 1065
|
||||
onOpen: ignore
|
||||
1
solana-explorer/.rustfmt.toml
Normal file
1
solana-explorer/.rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
||||
max_width = 120
|
||||
652
solana-explorer/Cargo.lock
generated
Normal file
652
solana-explorer/Cargo.lock
generated
Normal file
@@ -0,0 +1,652 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bigdecimal"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hex-literal"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "pad"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
|
||||
dependencies = [
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.190"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.190"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af972e374502cdfc9998132f5343848d1c58f27a295dc061a89804371f408a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bigdecimal",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"pad",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
"substreams-macro",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams-macro"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6521ccd011a4c3f52cd3c31fc7400733e4feba2094e0e0e6354adca25b2b3f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams-solana"
|
||||
version = "0.10.2"
|
||||
source = "git+https://github.com/streamingfast/substreams-solana#c00176f6c3b45ddb17153d980762caa693c8cf18"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"substreams",
|
||||
"substreams-solana-core",
|
||||
"substreams-solana-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams-solana-core"
|
||||
version = "0.10.2"
|
||||
source = "git+https://github.com/streamingfast/substreams-solana#c00176f6c3b45ddb17153d980762caa693c8cf18"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams-solana-explorer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58",
|
||||
"getrandom",
|
||||
"hex-literal",
|
||||
"num-bigint",
|
||||
"prost",
|
||||
"serde",
|
||||
"serde_qs",
|
||||
"substreams",
|
||||
"substreams-solana",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substreams-solana-macro"
|
||||
version = "0.10.2"
|
||||
source = "git+https://github.com/streamingfast/substreams-solana#c00176f6c3b45ddb17153d980762caa693c8cf18"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
32
solana-explorer/Cargo.toml
Normal file
32
solana-explorer/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "substreams-solana-explorer"
|
||||
version = "0.1.0"
|
||||
description = "Substreams showcasing the building blocks of Solana"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/streamingfast/substreams-explorers"
|
||||
license = "Apache 2.0"
|
||||
|
||||
[lib]
|
||||
name = "substreams"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
bs58 = "0.4"
|
||||
hex-literal = "0.3"
|
||||
num-bigint = "0.4"
|
||||
prost = "0.11"
|
||||
# Use latest from https://crates.io/crates/substreams
|
||||
substreams = "0.5"
|
||||
# Use latest from https://crates.io/crates/substreams-solana
|
||||
substreams-solana = { git = "https://github.com/streamingfast/substreams-solana" }
|
||||
serde_qs = "0.12.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
anyhow = "1.0"
|
||||
|
||||
[target.wasm32-unknown-unknown.dependencies]
|
||||
getrandom = { version = "0.2", features = ["custom"] }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = 's'
|
||||
strip = "debuginfo"
|
||||
11
solana-explorer/Makefile
Normal file
11
solana-explorer/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
.PHONY: build
|
||||
build:
|
||||
cargo build --target wasm32-unknown-unknown --release
|
||||
|
||||
.PHONY: protogen
|
||||
protogen:
|
||||
substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google"
|
||||
|
||||
.PHONY: pack
|
||||
pack: build
|
||||
substreams pack substreams.yaml
|
||||
170
solana-explorer/README.md
Normal file
170
solana-explorer/README.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# Solana Explorer
|
||||
|
||||
The Solana Explorer consists of several Substreams modules showcasing the most basic operations that you can perform with Substreams on the Solana blockchain.
|
||||
|
||||
## Before You Begin
|
||||
|
||||
Make sure you have the [Substreams CLI installed](https://substreams.streamingfast.io/getting-started/installing-the-cli), and you know the [basic structure of a Substreams module](https://substreams.streamingfast.io/getting-started/quickstart). You must also provide an [authentication token](https://substreams.streamingfast.io/reference-and-specs/authentication).
|
||||
|
||||
## Modules
|
||||
|
||||
## Running the Substreams
|
||||
|
||||
First, generate the Protobuf code, which are the outputs of the Substreams:
|
||||
|
||||
```
|
||||
> make protogen
|
||||
```
|
||||
|
||||
Then, build the Rust code using the `cargo` command-line tool:
|
||||
|
||||
```
|
||||
> make build
|
||||
```
|
||||
|
||||
### Running the "map_block_meta" Module
|
||||
|
||||
In the following command, you retrieve the metadata of the block with slot number `153000000`. You specify the starting block by using the `--start-block` parameter.
|
||||
|
||||
```bash
|
||||
> substreams gui -e mainnet.sol.streamingfast.io:443 ./solana-explorer-v0.1.0.spkg map_block_meta --start-block 153000000 --stop-block +1
|
||||
Connected (trace ID 0c93ceb65b98b138f0b8caf8a0e81c77)
|
||||
Progress messages received: 0 (0/sec)
|
||||
Backprocessing history up to requested target block 153000000:
|
||||
(hit 'm' to switch mode)
|
||||
|
||||
----------- BLOCK #153,000,000 (ENZNjBKCxXQqgFxX63T6kn7DJwc7fQiwy3W3vyehtEGA) ---------------
|
||||
{
|
||||
"@module": "map_block_meta",
|
||||
"@block": 153000000,
|
||||
"@type": "sol.block_meta.v1.BlockMeta",
|
||||
"@data": {
|
||||
"slot": "153000000",
|
||||
"hash": "ENZNjBKCxXQqgFxX63T6kn7DJwc7fQiwy3W3vyehtEGA",
|
||||
"parentHash": "7Eric2Heq94zoz5zBf5xg3K7opnWDaRVoS6DVa4Xxtcn"
|
||||
}
|
||||
}
|
||||
|
||||
all done
|
||||
```
|
||||
|
||||
### Running the "map_filter_instructions" Module
|
||||
|
||||
To run this module, you must provide a program id value in the parameters in your substreams.yaml manifest.
|
||||
|
||||
This example will use the default `Stake11111111111111111111111111111111111111` program.
|
||||
|
||||
```yaml
|
||||
params:
|
||||
map_filter_instructions: "program_id=Stake11111111111111111111111111111111111111"
|
||||
```
|
||||
|
||||
```bash
|
||||
> substreams run -e mainnet.sol.streamingfast.io:443 ./solana-explorer-v0.1.0.spkg map_filter_instructions -s 153000000 -t +50
|
||||
----------- BLOCK #153,000,000 (ENZNjBKCxXQqgFxX63T6kn7DJwc7fQiwy3W3vyehtEGA) ---------------
|
||||
----------- BLOCK #153,000,001 (8q2n7y3ozKWUWrAGVbNc3wrkxdmT6iSdgf8CHgqrvSv1) ---------------
|
||||
----------- BLOCK #153,000,002 (AfE4vBBsvcCXzdexP4sX9byHYrdZsUpd2GTTTTvkShxu) ---------------
|
||||
----------- BLOCK #153,000,003 (H5RZGAShGm7sMW6NvaPY3TsX36WEvugZ64Y1gSBRPyLV) ---------------
|
||||
----------- BLOCK #153,000,004 (Egf4PFv5636rycdntsBfi26Bou2Mt3Z5UAgH4hBbkZat) ---------------
|
||||
----------- BLOCK #153,000,005 (DmkkhPG2RDWkJnLbSiG1XTUotJVpLbjqBeRa9FoQB3Tg) ---------------
|
||||
----------- BLOCK #153,000,006 (Dy9YQQrTed69j7fsy7z3F3sa1x34T4CGmCVQVFoWobRE) ---------------
|
||||
----------- BLOCK #153,000,007 (3bHscyCgsvzLo6u4CpvCzJe7ELkuf9k8MSwHyLUtif9L) ---------------
|
||||
----------- BLOCK #153,000,008 (CkDjN7c4hjYqtuYXH9Vw8MTmk29XjgMnbEtAzrjbyjnU) ---------------
|
||||
----------- BLOCK #153,000,009 (8SVnGrwbwpAWCPdRXKgyNCvJRedEqmYnLazB3mB7Rehg) ---------------
|
||||
----------- BLOCK #153,000,010 (BTVDWyLK26P2CBjGjCvsHwNqaUcn15xUauwCJmkCSAx1) ---------------
|
||||
----------- BLOCK #153,000,011 (DVzw63xEAHmWTdo9iA9ca7yTiaondmGGvr4VczQnFhbn) ---------------
|
||||
----------- BLOCK #153,000,012 (EtMvzAbrkdWpawfP7ozcL86yocFNYxvWvtS4f8pMrajD) ---------------
|
||||
{
|
||||
"@module": "map_filter_instructions",
|
||||
"@block": 153000012,
|
||||
"@type": "sol.programs.v1.Instructions",
|
||||
"@data": {
|
||||
"instructions": [
|
||||
{
|
||||
"programId": "Stake11111111111111111111111111111111111111",
|
||||
"accounts": [
|
||||
"4nicrkdB15JqjMViy8guLFi8x1RLqTQud37XGX5LZVkN",
|
||||
"SysvarRent111111111111111111111111111111111"
|
||||
],
|
||||
"data": "1111jgvBfvfPuc2GLifVk9vJpXFTL5urtkjvyJHP6p7TqNR9G47jkYe3RGab9rya96yeGycaY8SVbcpaBkRLZonTJL7y4GyDWwyEmYmvNz74HWew5cPsky18ppTT1WyqmjxvmznzUWXfRogakvUscqJ8C54tP",
|
||||
"slotNumber": "153000012",
|
||||
"blockHash": "EtMvzAbrkdWpawfP7ozcL86yocFNYxvWvtS4f8pMrajD"
|
||||
},
|
||||
{
|
||||
"programId": "Stake11111111111111111111111111111111111111",
|
||||
"accounts": [
|
||||
"4nicrkdB15JqjMViy8guLFi8x1RLqTQud37XGX5LZVkN",
|
||||
"6F5xdRXh2W3B2vhte12VG79JVUkUSLYrHydGX1SAadfZ",
|
||||
"SysvarC1ock11111111111111111111111111111111",
|
||||
"SysvarStakeHistory1111111111111111111111111",
|
||||
"StakeConfig11111111111111111111111111111111",
|
||||
"GJYanGsBPyRUgAYkXBTyBYdZiH5wppXoJys9HaJwitzk"
|
||||
],
|
||||
"data": "3xyZh",
|
||||
"slotNumber": "153000012",
|
||||
"blockHash": "EtMvzAbrkdWpawfP7ozcL86yocFNYxvWvtS4f8pMrajD"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
----------- BLOCK #153,000,013 (7NVSAZZefTrNkK7JSg227yoponB6Tig27PXnEm7kQFJf) ---------------
|
||||
----------- BLOCK #153,000,014 (3nfE81F85ggdWxjRZUENBPhvXStAJsVxnwrQ99VcTMME) ---------------
|
||||
----------- BLOCK #153,000,015 (4N3sqbbJEZobfu1pL6rZEZf6Kpx2WYB8fHm1hbqASa6S) ---------------
|
||||
----------- BLOCK #153,000,016 (812uX2UUSvvep5APemSmTDk4bDnMkZnJtMBSa6enBmFN) ---------------
|
||||
----------- BLOCK #153,000,017 (CXsKxq7LmJVW6P3YjBVbrfgDiyMyzYDX5jNhgdsryMfv) ---------------
|
||||
----------- BLOCK #153,000,018 (FnVqabMm8VEKCr9pchMFxipxSssNeioxx7bCaqyGbzgX) ---------------
|
||||
----------- BLOCK #153,000,019 (J49iZE979hGtK4hnxUigpxQiNsU3oNq9UMMJqknGLJVT) ---------------
|
||||
----------- BLOCK #153,000,020 (GJ1BNqsBtyxucvqkipkZDaHW2KGdsU3sR41ebmCxth24) ---------------
|
||||
----------- BLOCK #153,000,021 (Bxc99wYm1heyzfY1ViXNnJFmf81BFHzLKrwizW5TPemn) ---------------
|
||||
----------- BLOCK #153,000,022 (2iLweM1VHWnkmXpF7G2fHr52zGuwsEjFXd8ZtpwwUcDw) ---------------
|
||||
----------- BLOCK #153,000,023 (6JpfNdC2qTErHpXd8e74E5aAkm11USA2rJJbCvQdtHyg) ---------------
|
||||
----------- BLOCK #153,000,024 (AjN8rk6c8ya5TNYRBUWKUgEYEJceqtJsPMMDdweg4MPR) ---------------
|
||||
----------- BLOCK #153,000,025 (F7dvT2mwGusrLmRwdJrGZ7cAXsxq43kHsrKpzeseywwg) ---------------
|
||||
----------- BLOCK #153,000,026 (aGdXha9hhhaETuNywV2XY39Y6B719NBZ6xbUzAu3wah) ---------------
|
||||
----------- BLOCK #153,000,027 (GfoPvdzekjLV1QHvvHzyVG7xbjajDKA4Ev7gXum2Ry1S) ---------------
|
||||
----------- BLOCK #153,000,028 (5xj9iYo6nuAiXvPFDUieUKBcRLbg9rz5qiBQg2NYjyBv) ---------------
|
||||
{
|
||||
"@module": "map_filter_instructions",
|
||||
"@block": 153000028,
|
||||
"@type": "sol.programs.v1.Instructions",
|
||||
"@data": {
|
||||
"instructions": [
|
||||
{
|
||||
"programId": "Stake11111111111111111111111111111111111111",
|
||||
"accounts": [
|
||||
"EQFsbzpgBufUVPV65tt3awmnv1E8anaWfNSBCfnf4bUh",
|
||||
"SysvarC1ock11111111111111111111111111111111",
|
||||
"4sUsH6ZzqWU2g1xzM8udFErB4qN3GSL1QbNjiSHc3QxN"
|
||||
],
|
||||
"data": "8QwQj",
|
||||
"slotNumber": "153000028",
|
||||
"blockHash": "5xj9iYo6nuAiXvPFDUieUKBcRLbg9rz5qiBQg2NYjyBv"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
----------- BLOCK #153,000,029 (3LBYvzhWfdtcAwuCvoBzTCkUbpVbckyBFAcJezdScGhP) ---------------
|
||||
----------- BLOCK #153,000,030 (B97KXhFadGBEkMjZ6FTyK6dP6Lyk79p2CqgQBYmjhSdf) ---------------
|
||||
----------- BLOCK #153,000,031 (C2SgWr1LvVrG3N37DtvN3rd5mQisswU87PfSD6pyLdae) ---------------
|
||||
----------- BLOCK #153,000,032 (4buy43g7PDLmR196MtRDDid1ZfWbqxJbTi2RWt7gvjqn) ---------------
|
||||
----------- BLOCK #153,000,033 (C7RAFX27t2cpPyVWXbCACccQAjyHxoyyP2GbKmy7to3y) ---------------
|
||||
----------- BLOCK #153,000,034 (CyigpnTa5q9j6vLMFpBCNyEUjViojVQcwicb89DAntq6) ---------------
|
||||
----------- BLOCK #153,000,035 (8npojbiPbBFau8GuXtbYnn6JfBa2tkzfmv6uKEwAKhJ) ---------------
|
||||
----------- BLOCK #153,000,036 (AAhLqu8Z8REBTMGh5FcMuWyWANBiVpf65XP6PWXG11rx) ---------------
|
||||
----------- BLOCK #153,000,037 (8AYAF1uiVtnC94c99wmzZP7gRAs7oMFcvE99dtXaNYFL) ---------------
|
||||
----------- BLOCK #153,000,038 (3aopsHdWuQLT4X11x4bo1e6Vcyyou9HB8wVV7hbMphvi) ---------------
|
||||
----------- BLOCK #153,000,039 (8HpRgRVePiSpTUqRJBsnvSF3XMFQCyfy2STrTCqTCt2J) ---------------
|
||||
----------- BLOCK #153,000,040 (AhfUVwbX1SinS8hXzfgSM1ESkrU9CV6aMvTQgch9nZhY) ---------------
|
||||
----------- BLOCK #153,000,041 (A6JVr9HVkqQL1mvqGLzDuKvbsf9PFQffvS4PnaDNa44F) ---------------
|
||||
----------- BLOCK #153,000,042 (FMqcoisPGNatsBt3eWmiWJuX1cLGAu3qLAy9696RNp4s) ---------------
|
||||
----------- BLOCK #153,000,043 (47ARP75kLw3m6s3yWcUWmjsGB4avyNmspgFq6UkxYQde) ---------------
|
||||
----------- BLOCK #153,000,044 (DzDjDvU1vXCHBeoYwEPZKy3VGByVAM6DkQEKZop3Z8Wn) ---------------
|
||||
----------- BLOCK #153,000,045 (CrgFgZFxVCSqXUfysNe7GXQ71oTK8eGUVaM9FvsPG81C) ---------------
|
||||
----------- BLOCK #153,000,046 (4bNCMpe2E3W1zMxHCNmKYooGe2ptTo1EMe92qRKQYMP5) ---------------
|
||||
----------- BLOCK #153,000,047 (6MqMSHpKjwavQp4FRs5wAGEbKqkp8D82EH8KFkF2YXyH) ---------------
|
||||
----------- BLOCK #153,000,048 (2E8ncPZMAqa5RKPvEUAMt6abLNcDZM7J6nawyaiSboGD) ---------------
|
||||
----------- BLOCK #153,000,049 (GyG9Rw4Mo8sYb9WLzz8oqHgV3k4sYa3UWeveGG2uLGWX) ---------------
|
||||
all done
|
||||
```
|
||||
9
solana-explorer/proto/block_meta.proto
Normal file
9
solana-explorer/proto/block_meta.proto
Normal file
@@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package sol.block_meta.v1;
|
||||
|
||||
message BlockMeta {
|
||||
uint64 slot = 1;
|
||||
string hash = 2;
|
||||
string parent_hash = 3;
|
||||
}
|
||||
16
solana-explorer/proto/program_instructions.proto
Normal file
16
solana-explorer/proto/program_instructions.proto
Normal file
@@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package sol.programs.v1;
|
||||
|
||||
message Instructions {
|
||||
repeated Instruction instructions = 1;
|
||||
}
|
||||
|
||||
message Instruction {
|
||||
string program_id = 1;
|
||||
repeated string accounts = 2;
|
||||
string data = 3;
|
||||
|
||||
uint64 slot_number = 4;
|
||||
string block_hash = 5;
|
||||
}
|
||||
4
solana-explorer/rust-toolchain.toml
Normal file
4
solana-explorer/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "1.69"
|
||||
components = [ "rustfmt" ]
|
||||
targets = [ "wasm32-unknown-unknown" ]
|
||||
4
solana-explorer/src/lib.rs
Normal file
4
solana-explorer/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
mod pb;
|
||||
mod map_block_full;
|
||||
mod map_block_meta;
|
||||
mod map_filter_instructions;
|
||||
6
solana-explorer/src/map_block_full.rs
Normal file
6
solana-explorer/src/map_block_full.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use substreams_solana::pb::sf::solana::r#type::v1::Block;
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_block_full(blk: Block) -> Result<Block, substreams::errors::Error> {
|
||||
Ok(blk)
|
||||
}
|
||||
11
solana-explorer/src/map_block_meta.rs
Normal file
11
solana-explorer/src/map_block_meta.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use substreams_solana::pb::sf::solana::r#type::v1::Block;
|
||||
use crate::pb::sol::block_meta::v1::BlockMeta;
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_block_meta(blk: Block) -> Result<BlockMeta, substreams::errors::Error> {
|
||||
Ok(BlockMeta {
|
||||
slot: blk.slot,
|
||||
hash: blk.blockhash,
|
||||
parent_hash: blk.previous_blockhash,
|
||||
})
|
||||
}
|
||||
69
solana-explorer/src/map_filter_instructions.rs
Normal file
69
solana-explorer/src/map_filter_instructions.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use anyhow::anyhow;
|
||||
use serde::Deserialize;
|
||||
use substreams_solana::pb::sf::solana::r#type::v1::{Block, CompiledInstruction};
|
||||
use crate::pb::sol::programs::v1::{Instruction, Instructions};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct TransactionFilterParams {
|
||||
program_id: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_filter_instructions(params: String, blk: Block) -> Result<Instructions, Vec<substreams::errors::Error>> {
|
||||
let filters = parse_filters_from_params(params)?;
|
||||
|
||||
let mut instructions : Vec<Instruction> = Vec::new();
|
||||
|
||||
blk.transactions.iter().for_each(|tx| {
|
||||
let msg = tx.transaction.clone().unwrap().message.unwrap();
|
||||
tx.transaction.clone().unwrap().
|
||||
let acct_keys = msg.account_keys.as_slice();
|
||||
let insts : Vec<Instruction> = msg.instructions.iter()
|
||||
.filter(|inst| apply_filter(inst, &filters, acct_keys.to_vec()))
|
||||
.map(|inst| {
|
||||
Instruction {
|
||||
slot_number: blk.slot,
|
||||
block_hash: blk.blockhash.clone(),
|
||||
program_id: bs58::encode(acct_keys[inst.program_id_index as usize].to_vec()).into_string(),
|
||||
accounts: inst.accounts.iter().map(|acct| bs58::encode(acct_keys[*acct as usize].to_vec()).into_string()).collect(),
|
||||
data: bs58::encode(inst.data.clone()).into_string(),
|
||||
}
|
||||
}).collect();
|
||||
instructions.extend(insts);
|
||||
});
|
||||
|
||||
Ok(Instructions { instructions })
|
||||
}
|
||||
|
||||
fn parse_filters_from_params(params: String) -> Result<TransactionFilterParams, Vec<substreams::errors::Error>> {
|
||||
let parsed_result = serde_qs::from_str(¶ms);
|
||||
if parsed_result.is_err() {
|
||||
return Err(Vec::from([anyhow!("Unexpected error while parsing parameters")]));
|
||||
}
|
||||
|
||||
let filters = parsed_result.unwrap();
|
||||
//todo: verify_filters(&filters)?;
|
||||
|
||||
Ok(filters)
|
||||
}
|
||||
|
||||
fn apply_filter(instruction: &CompiledInstruction, filters: &TransactionFilterParams, account_keys: Vec<Vec<u8>>) -> bool {
|
||||
if filters.program_id.is_none() {
|
||||
return true;
|
||||
}
|
||||
let program_id_filter = filters.program_id.clone().unwrap();
|
||||
|
||||
let program_account_key = account_keys.get(instruction.program_id_index as usize);
|
||||
if program_account_key.is_none() {
|
||||
return false;
|
||||
}
|
||||
let program_account_key_val = bs58::encode(program_account_key.unwrap()).into_string();
|
||||
|
||||
//check if account key value is equal to the program id
|
||||
if program_account_key_val != program_id_filter {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
28
solana-explorer/src/pb/mod.rs
Normal file
28
solana-explorer/src/pb/mod.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
// @generated
|
||||
pub mod sf {
|
||||
pub mod solana {
|
||||
pub mod r#type {
|
||||
// @@protoc_insertion_point(attribute:sf.solana.type.v1)
|
||||
pub mod v1 {
|
||||
include!("sf.solana.type.v1.rs");
|
||||
// @@protoc_insertion_point(sf.solana.type.v1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub mod sol {
|
||||
pub mod block_meta {
|
||||
// @@protoc_insertion_point(attribute:sol.block_meta.v1)
|
||||
pub mod v1 {
|
||||
include!("sol.block_meta.v1.rs");
|
||||
// @@protoc_insertion_point(sol.block_meta.v1)
|
||||
}
|
||||
}
|
||||
pub mod programs {
|
||||
// @@protoc_insertion_point(attribute:sol.programs.v1)
|
||||
pub mod v1 {
|
||||
include!("sol.programs.v1.rs");
|
||||
// @@protoc_insertion_point(sol.programs.v1)
|
||||
}
|
||||
}
|
||||
}
|
||||
256
solana-explorer/src/pb/sf.solana.type.v1.rs
Normal file
256
solana-explorer/src/pb/sf.solana.type.v1.rs
Normal file
@@ -0,0 +1,256 @@
|
||||
// @generated
|
||||
/// This Block is backwards compatible with solana.storage.ConfirmedBlock.ConfirmedBlock from
|
||||
/// the Solana Labs repositories.
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Block {
|
||||
#[prost(string, tag="1")]
|
||||
pub previous_blockhash: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="2")]
|
||||
pub blockhash: ::prost::alloc::string::String,
|
||||
#[prost(uint64, tag="3")]
|
||||
pub parent_slot: u64,
|
||||
#[prost(message, repeated, tag="4")]
|
||||
pub transactions: ::prost::alloc::vec::Vec<ConfirmedTransaction>,
|
||||
#[prost(message, repeated, tag="5")]
|
||||
pub rewards: ::prost::alloc::vec::Vec<Reward>,
|
||||
#[prost(message, optional, tag="6")]
|
||||
pub block_time: ::core::option::Option<UnixTimestamp>,
|
||||
#[prost(message, optional, tag="7")]
|
||||
pub block_height: ::core::option::Option<BlockHeight>,
|
||||
/// StreamingFast additions
|
||||
#[prost(uint64, tag="20")]
|
||||
pub slot: u64,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ConfirmedTransaction {
|
||||
#[prost(message, optional, tag="1")]
|
||||
pub transaction: ::core::option::Option<Transaction>,
|
||||
#[prost(message, optional, tag="2")]
|
||||
pub meta: ::core::option::Option<TransactionStatusMeta>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Transaction {
|
||||
#[prost(bytes="vec", repeated, tag="1")]
|
||||
pub signatures: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(message, optional, tag="2")]
|
||||
pub message: ::core::option::Option<Message>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Message {
|
||||
#[prost(message, optional, tag="1")]
|
||||
pub header: ::core::option::Option<MessageHeader>,
|
||||
#[prost(bytes="vec", repeated, tag="2")]
|
||||
pub account_keys: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub recent_blockhash: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(message, repeated, tag="4")]
|
||||
pub instructions: ::prost::alloc::vec::Vec<CompiledInstruction>,
|
||||
#[prost(bool, tag="5")]
|
||||
pub versioned: bool,
|
||||
#[prost(message, repeated, tag="6")]
|
||||
pub address_table_lookups: ::prost::alloc::vec::Vec<MessageAddressTableLookup>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct MessageHeader {
|
||||
#[prost(uint32, tag="1")]
|
||||
pub num_required_signatures: u32,
|
||||
#[prost(uint32, tag="2")]
|
||||
pub num_readonly_signed_accounts: u32,
|
||||
#[prost(uint32, tag="3")]
|
||||
pub num_readonly_unsigned_accounts: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct MessageAddressTableLookup {
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub account_key: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub writable_indexes: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub readonly_indexes: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TransactionStatusMeta {
|
||||
#[prost(message, optional, tag="1")]
|
||||
pub err: ::core::option::Option<TransactionError>,
|
||||
#[prost(uint64, tag="2")]
|
||||
pub fee: u64,
|
||||
#[prost(uint64, repeated, tag="3")]
|
||||
pub pre_balances: ::prost::alloc::vec::Vec<u64>,
|
||||
#[prost(uint64, repeated, tag="4")]
|
||||
pub post_balances: ::prost::alloc::vec::Vec<u64>,
|
||||
#[prost(message, repeated, tag="5")]
|
||||
pub inner_instructions: ::prost::alloc::vec::Vec<InnerInstructions>,
|
||||
#[prost(bool, tag="10")]
|
||||
pub inner_instructions_none: bool,
|
||||
#[prost(string, repeated, tag="6")]
|
||||
pub log_messages: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||
#[prost(bool, tag="11")]
|
||||
pub log_messages_none: bool,
|
||||
#[prost(message, repeated, tag="7")]
|
||||
pub pre_token_balances: ::prost::alloc::vec::Vec<TokenBalance>,
|
||||
#[prost(message, repeated, tag="8")]
|
||||
pub post_token_balances: ::prost::alloc::vec::Vec<TokenBalance>,
|
||||
#[prost(message, repeated, tag="9")]
|
||||
pub rewards: ::prost::alloc::vec::Vec<Reward>,
|
||||
#[prost(bytes="vec", repeated, tag="12")]
|
||||
pub loaded_writable_addresses: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(bytes="vec", repeated, tag="13")]
|
||||
pub loaded_readonly_addresses: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(message, optional, tag="14")]
|
||||
pub return_data: ::core::option::Option<ReturnData>,
|
||||
#[prost(bool, tag="15")]
|
||||
pub return_data_none: bool,
|
||||
/// 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.
|
||||
#[prost(uint64, optional, tag="16")]
|
||||
pub compute_units_consumed: ::core::option::Option<u64>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TransactionError {
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub err: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct InnerInstructions {
|
||||
#[prost(uint32, tag="1")]
|
||||
pub index: u32,
|
||||
#[prost(message, repeated, tag="2")]
|
||||
pub instructions: ::prost::alloc::vec::Vec<InnerInstruction>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct InnerInstruction {
|
||||
#[prost(uint32, tag="1")]
|
||||
pub program_id_index: u32,
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub accounts: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub data: ::prost::alloc::vec::Vec<u8>,
|
||||
/// Invocation stack height of an inner instruction.
|
||||
/// Available since Solana v1.14.6
|
||||
/// Set to `None` for txs executed on earlier versions.
|
||||
#[prost(uint32, optional, tag="4")]
|
||||
pub stack_height: ::core::option::Option<u32>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct CompiledInstruction {
|
||||
#[prost(uint32, tag="1")]
|
||||
pub program_id_index: u32,
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub accounts: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub data: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TokenBalance {
|
||||
#[prost(uint32, tag="1")]
|
||||
pub account_index: u32,
|
||||
#[prost(string, tag="2")]
|
||||
pub mint: ::prost::alloc::string::String,
|
||||
#[prost(message, optional, tag="3")]
|
||||
pub ui_token_amount: ::core::option::Option<UiTokenAmount>,
|
||||
#[prost(string, tag="4")]
|
||||
pub owner: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="5")]
|
||||
pub program_id: ::prost::alloc::string::String,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct UiTokenAmount {
|
||||
#[prost(double, tag="1")]
|
||||
pub ui_amount: f64,
|
||||
#[prost(uint32, tag="2")]
|
||||
pub decimals: u32,
|
||||
#[prost(string, tag="3")]
|
||||
pub amount: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="4")]
|
||||
pub ui_amount_string: ::prost::alloc::string::String,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ReturnData {
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub program_id: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub data: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Reward {
|
||||
#[prost(string, tag="1")]
|
||||
pub pubkey: ::prost::alloc::string::String,
|
||||
#[prost(int64, tag="2")]
|
||||
pub lamports: i64,
|
||||
#[prost(uint64, tag="3")]
|
||||
pub post_balance: u64,
|
||||
#[prost(enumeration="RewardType", tag="4")]
|
||||
pub reward_type: i32,
|
||||
#[prost(string, tag="5")]
|
||||
pub commission: ::prost::alloc::string::String,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Rewards {
|
||||
#[prost(message, repeated, tag="1")]
|
||||
pub rewards: ::prost::alloc::vec::Vec<Reward>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct UnixTimestamp {
|
||||
#[prost(int64, tag="1")]
|
||||
pub timestamp: i64,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct BlockHeight {
|
||||
#[prost(uint64, tag="1")]
|
||||
pub block_height: u64,
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum RewardType {
|
||||
Unspecified = 0,
|
||||
Fee = 1,
|
||||
Rent = 2,
|
||||
Staking = 3,
|
||||
Voting = 4,
|
||||
}
|
||||
impl RewardType {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
RewardType::Unspecified => "Unspecified",
|
||||
RewardType::Fee => "Fee",
|
||||
RewardType::Rent => "Rent",
|
||||
RewardType::Staking => "Staking",
|
||||
RewardType::Voting => "Voting",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"Unspecified" => Some(Self::Unspecified),
|
||||
"Fee" => Some(Self::Fee),
|
||||
"Rent" => Some(Self::Rent),
|
||||
"Staking" => Some(Self::Staking),
|
||||
"Voting" => Some(Self::Voting),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
12
solana-explorer/src/pb/sol.block_meta.v1.rs
Normal file
12
solana-explorer/src/pb/sol.block_meta.v1.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct BlockMeta {
|
||||
#[prost(uint64, tag="1")]
|
||||
pub slot: u64,
|
||||
#[prost(string, tag="2")]
|
||||
pub hash: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="3")]
|
||||
pub parent_hash: ::prost::alloc::string::String,
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
22
solana-explorer/src/pb/sol.programs.v1.rs
Normal file
22
solana-explorer/src/pb/sol.programs.v1.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
// @generated
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Instructions {
|
||||
#[prost(message, repeated, tag="1")]
|
||||
pub instructions: ::prost::alloc::vec::Vec<Instruction>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Instruction {
|
||||
#[prost(string, tag="1")]
|
||||
pub program_id: ::prost::alloc::string::String,
|
||||
#[prost(string, repeated, tag="2")]
|
||||
pub accounts: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||
#[prost(string, tag="3")]
|
||||
pub data: ::prost::alloc::string::String,
|
||||
#[prost(uint64, tag="4")]
|
||||
pub slot_number: u64,
|
||||
#[prost(string, tag="5")]
|
||||
pub block_hash: ::prost::alloc::string::String,
|
||||
}
|
||||
// @@protoc_insertion_point(module)
|
||||
45
solana-explorer/substreams.yaml
Normal file
45
solana-explorer/substreams.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
specVersion: v0.1.0
|
||||
package:
|
||||
name: "solana_explorer"
|
||||
version: v0.1.0
|
||||
|
||||
imports:
|
||||
solana: https://github.com/streamingfast/firehose-solana/releases/download/v0.1.1/solana-v0.1.1.spkg
|
||||
|
||||
protobuf:
|
||||
files:
|
||||
- block_meta.proto
|
||||
- program_instructions.proto
|
||||
importPaths:
|
||||
- ./proto
|
||||
|
||||
binaries:
|
||||
default:
|
||||
type: wasm/rust-v1
|
||||
file: ./target/wasm32-unknown-unknown/release/substreams.wasm
|
||||
|
||||
modules:
|
||||
- name: map_block_meta
|
||||
kind: map
|
||||
inputs:
|
||||
- source: sf.solana.type.v1.Block
|
||||
output:
|
||||
type: proto:sol.block_meta.v1.BlockMeta
|
||||
|
||||
- name: map_block_full
|
||||
kind: map
|
||||
inputs:
|
||||
- source: sf.solana.type.v1.Block
|
||||
output:
|
||||
type: proto:sf.solana.type.v1.Block
|
||||
|
||||
- name: map_filter_instructions
|
||||
kind: map
|
||||
inputs:
|
||||
- params: string
|
||||
- source: sf.solana.type.v1.Block
|
||||
output:
|
||||
type: proto:sol.programs.v1.Instructions
|
||||
|
||||
params:
|
||||
map_filter_instructions: "program_id=Stake11111111111111111111111111111111111111"
|
||||
Reference in New Issue
Block a user