commit b484273cba9e5ef61c293f41e0899d1a3b3a3f8c Author: samlior Date: Fri Dec 26 10:57:37 2025 +0800 chore: add all diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db595c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool +*.out + +# Dependency directories +vendor/ + +# Go workspace file +go.work + +# IDE specific files +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS specific files +.DS_Store +Thumbs.db + +# Binaries +bin/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2ca9aa2 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +.PHONY: init +# init env +init: + go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + +.PHONY: shreder +# generate shreder proto +shreder: + protoc --proto_path=./third_party/shreder_protos \ + --go_opt=Mshreder.proto=github.com/samlior/libsam/third_party/shreder_protos \ + --go_opt=paths=source_relative \ + --go_out=./third_party/shreder_protos \ + --go-grpc_opt=Mshreder.proto=github.com/samlior/libsam/third_party/shreder_protos \ + --go-grpc_opt=paths=source_relative \ + --go-grpc_out=./third_party/shreder_protos \ + third_party/shreder_protos/shreder.proto + +.PHONY: build +# build +build: + mkdir -p bin/ && CGO_ENABLED=0 go build -o ./bin/ ./... \ No newline at end of file diff --git a/cmd/example/main.go b/cmd/example/main.go new file mode 100644 index 0000000..a3dd973 --- /dev/null +++ b/cmd/example/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello, World!") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..22214ef --- /dev/null +++ b/go.mod @@ -0,0 +1,41 @@ +module github.com/samlior/libsam + +go 1.25.1 + +require ( + google.golang.org/grpc v1.78.0 + google.golang.org/protobuf v1.36.11 +) + +require ( + filippo.io/edwards25519 v1.0.0-rc.1 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.9.0 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/solana-go v1.14.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.11 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/near/borsh-go v0.3.1 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect + go.mongodb.org/mongo-driver v1.12.2 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5ef1e81 --- /dev/null +++ b/go.sum @@ -0,0 +1,170 @@ +filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +github.com/benbjohnson/clock v1.1.0/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/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/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/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/solana-go v1.14.0 h1:3WfAi70jOOjAJ0deFMjdhFYlLXATF4tOQXsDNWJtOLw= +github.com/gagliardetto/solana-go v1.14.0/go.mod h1:l/qqqIN6qJJPtxW/G1PF4JtcE3Zg2vD2EliZrr9Gn5k= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +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/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/near/borsh-go v0.3.1 h1:ukNbhJlPKxfua0/nIuMZhggSU8zvtRP/VyC25LLqPUA= +github.com/near/borsh-go v0.3.1/go.mod h1:NeMochZp7jN/pYFuxLkrZtmLqbADmnp/y1+/dL+AsyQ= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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.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/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +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/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +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.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +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.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 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/consts/consts.go b/pkg/consts/consts.go new file mode 100644 index 0000000..75216bd --- /dev/null +++ b/pkg/consts/consts.go @@ -0,0 +1,6 @@ +package consts + +const ( + SolDecimals = 9 // Decimals for SOL + TokenDecimals = 6 // Default decimals for SPL tokens +) \ No newline at end of file diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go new file mode 100644 index 0000000..c3d4f4b --- /dev/null +++ b/pkg/logger/logger.go @@ -0,0 +1,18 @@ +package logger + +type Logger interface { + Info(a ...interface{}) + Infof(format string, a ...interface{}) + + Error(a ...interface{}) + Errorf(format string, a ...interface{}) + + Debug(a ...interface{}) + Debugf(format string, a ...interface{}) + + Warn(a ...interface{}) + Warnf(format string, a ...interface{}) + + Fatal(a ...interface{}) + Fatalf(format string, a ...interface{}) +} \ No newline at end of file diff --git a/pkg/shreder/shreder_client.go b/pkg/shreder/shreder_client.go new file mode 100644 index 0000000..5dea9ce --- /dev/null +++ b/pkg/shreder/shreder_client.go @@ -0,0 +1,105 @@ +package shreder_client + +import ( + "context" + + "github.com/samlior/libsam/pkg/logger" + "github.com/samlior/libsam/pkg/txparser" + "github.com/samlior/libsam/pkg/types" + "github.com/samlior/libsam/third_party/shreder_protos" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +type ShrederClient struct { + log logger.Logger + + conn *grpc.ClientConn + client shreder_protos.ShrederServiceClient +} + +func NewShrederClient(logger logger.Logger, url string) (*ShrederClient, func(), error) { + conn, err := grpc.NewClient(url, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, func() {}, err + } + + s := &ShrederClient{ + log: logger, + conn: conn, + client: shreder_protos.NewShrederServiceClient(conn), + } + + return s, func() { + s.Wait() + }, nil +} + +func (c *ShrederClient) Wait() { + c.log.Debug("waiting for shreder client to stop") + + err := c.conn.Close() + if err != nil { + c.log.Errorf("failed to close connection: %v", err) + } + + c.log.Debug("shreder client stopped") +} + +func (c *ShrederClient) ReadSync(ctx context.Context, txCh chan<- types.TxSignalBatch) error { + stream, err := c.client.SubscribeTransactions(ctx) + if err != nil { + return err + } + + err = stream.Send(&shreder_protos.SubscribeTransactionsRequest{ + Transactions: map[string]*shreder_protos.SubscribeRequestFilterTransactions{ + "pumpfun": { + AccountRequired: []string{ + "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P", + }, + }, + "axiom": { + AccountRequired: []string{ + "F5tfvbLog9VdGUPqBDTT8rgXvTTcq7e5UiGnupL1zvBq", + }, + }, + "photon": { + AccountRequired: []string{ + "BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW", + }, + }, + "fjsz": { + AccountRequired: []string{ + "FJsZbftBqRLfF7uqUKpm4s2goDr6xsQ5Q3mN7AFJB6hK", + }, + }, + }, + }) + if err != nil { + return err + } + + for { + response, err := stream.Recv() + if err != nil { + return err + } + + txBatch := txparser.ParseTransaction(response.Transaction) + if len(txBatch) == 0 { + continue + } + + // set fixed source for tx signals + for _, tx := range txBatch { + tx.Source = "shreder" + } + + select { + case <-ctx.Done(): + return ctx.Err() + case txCh <- txBatch: + } + } +} diff --git a/pkg/txparser/txparser.go b/pkg/txparser/txparser.go new file mode 100644 index 0000000..ab01396 --- /dev/null +++ b/pkg/txparser/txparser.go @@ -0,0 +1,1232 @@ +package txparser + +import ( + "bytes" + "encoding/binary" + "fmt" + "log" + "math/big" + + "github.com/gagliardetto/solana-go" + "github.com/near/borsh-go" + "github.com/samlior/libsam/pkg/types" + "github.com/samlior/libsam/third_party/shreder_protos" + "github.com/shopspring/decimal" +) + +const ( + wsolMint = "So11111111111111111111111111111111111111112" + tokenProgram = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" +) + +// program ids +const ( + pumpProgramID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" + azczProgramID = "AzcZqCRUQgKEg5FTAgY7JacATABEYCEfMbjXEzspLYFB" + f5tfProgramID = "F5tfvbLog9VdGUPqBDTT8rgXvTTcq7e5UiGnupL1zvBq" + photonProgramID = "BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW" + pumpAmmProgramID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA" + _6hb1ProgramID = "6HB1VBBS8LrdQiR9MZcXV5VdpKFb7vjTMZuQQEQEPioC" + _8rsrProgramID = "8rsrfqvEQFKDm66uGx1swVJhkGf2fDet5Q7bygUjYYA3" + boboProgramID = "BobogA5N2KN2GG4XN3E3rNNRw3L8H1QPXp7QLxGrNHGM" + qtkvProgramID = "qtkvapJEvRWWrB7i5K6RaA1kvq5x3qmMKZ98ad71XQ7" + fjszProgramID = "FJsZbftBqRLfF7uqUKpm4s2goDr6xsQ5Q3mN7AFJB6hK" + flasProgramID = "FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9" +) + +// instruction discriminators +const ( + pumpCreateCoinIX = uint8(24) + pumpCreateCoinV2IX = uint8(214) + pumpExtendedSellIX = uint8(51) + pumpBuyTokensIX = uint8(102) + + azczBuyTokensIX = uint8(11) + f5tfBuyTokensIX = uint8(0) + flasBuyTokensIX = uint8(0) + + pumpAmmBuyTokensIX = uint8(102) + _6hb1BuyTokensIX = uint8(0) + + qtkvBuyTokensIX = uint8(0x02) +) + +var ( + boboBuyPumpTokensIX = []byte{0xff, 0xe7, 0x11, 0x53, 0x15, 0xc5, 0xc3, 0xdf} + fjszBuyTokensIX = []byte{0xe7, 0x3f, 0x99, 0x83, 0xf3, 0xed, 0xe3, 0x3c} + _8rsrBuyTokensIX = []byte{0xd9, 0xa1, 0x42, 0x0c, 0xbb, 0xc4, 0xe8, 0x30} + photonBuyPumpTokensIX = []byte{0x52, 0xe1, 0x77, 0xe7, 0x4e, 0x1d, 0x2d, 0x46} + photonSwapPumpAmmIX = []byte{0x2c, 0x77, 0xaf, 0xda, 0xc7, 0x4d, 0xc4, 0xeb} +) + +// table lookups +const ( + _6hb1TableLookup1 = "GwME2SEvkgtiL5d2UeR2ZCsEecvg879majGF5pAA1aTS" + _6hb1TableLookup2 = "7RKtfATWCe98ChuwecNq8XCzAzfoK3DtZTprFsPMGtio" + _8rsrTableLookup1 = "DSaHkhDp17UexbZsg2VUnWjEuTwKNCJrnG4LW122ANfd" + photonTableLookup = "3r6paeFSLpeUVmWtShb5uZtXYpcBE3729kUxkUS7xKi1" +) + +type compiledInstruction struct { + ProgramIDIndex uint8 + Accounts []uint8 + Data []byte +} + +type addressTableLookup struct { + AccountKey solana.PublicKey + WritableIndexes []uint8 + ReadonlyIndexes []uint8 +} + +type versionedMessage struct { + StaticAccountKeys []solana.PublicKey + Instructions []compiledInstruction + AddressTableLookups []addressTableLookup +} + +type versionedTransaction struct { + Signatures []solana.Signature + Message versionedMessage + Block uint64 +} + +type pumpExtendedSellArgs struct { + Amount uint64 + MinSolOutput uint64 +} + +type pumpBuyArgs struct { + Amount uint64 + MaxSolCost uint64 +} + +type pumpCreateCoinV2Args struct { + Name string + Symbol string + Uri string + Creator solana.PublicKey + IsMayhemMode bool +} + +type azczBuyArgs struct { + SolAmount uint64 + TokenAmount uint64 +} + +type f5tfBuyArgs struct { + SolAmount uint64 + TokenAmount uint64 +} + +type flasBuyArgs struct { + SolAmount uint64 + TokenAmount uint64 + Placeholder [3]uint8 +} + +type photonBuyPumpArgs struct { + Timestamp uint64 + SolAmount uint64 + TokenAmount uint64 + Fee uint64 +} + +type photonSwapPumpAmmArgs struct { + FromAmount uint64 + ToAmount uint64 +} + +type pumpAmmBuyArgs struct { + Amount uint64 + MaxSolCost uint64 +} + +type _6hb1BuyArgs struct { + SolAmount uint64 + TokenNumber uint64 +} + +type _8rsrBuyArgs struct { + SolIn uint64 + TokenOut uint64 +} + +type boboBuyArgs struct { + Placeholder1 uint64 + Placeholder2 uint64 + SolAmount uint64 + Placeholder3 uint64 + Placeholder4 uint64 + Placeholder5 uint64 + Placeholder6 uint64 +} + +type qtkvBuyArgs struct { + Placeholder uint64 + TokenNumber uint64 + SolAmount uint64 +} + +type fjszBuyArgs struct { + SolAmount uint64 + TokenAmount uint64 +} + +// ParseTransaction mirrors the Rust parse_transaction entry point. +func ParseTransaction(update *shreder_protos.SubscribeUpdateTransaction) []*types.TxSignal { + versioned, err := toVersionedTransaction(update) + if err != nil || versioned == nil || len(versioned.Signatures) == 0 { + return nil + } + + txHash := versioned.Signatures[0].String() + staticKeys := versioned.Message.StaticAccountKeys + instructions := versioned.Message.Instructions + + var parsed []*types.TxSignal + + for i := range instructions { + inst := instructions[i] + if int(inst.ProgramIDIndex) >= len(staticKeys) { + continue + } + + programID := staticKeys[inst.ProgramIDIndex].String() + switch programID { + case pumpProgramID: + txRes, err := parsePumpInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "pump") + case azczProgramID: + txRes, err := parseAzczInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "azcz") + case f5tfProgramID: + txRes, err := parseF5tfInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "f5tf") + case flasProgramID: + txRes, err := parseFlasInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "flas") + case photonProgramID: + txRes, err := parsePhotonInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "photon") + case pumpAmmProgramID: + txRes, err := parsePumpAmmInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "pumpamm") + case _6hb1ProgramID: + txRes, err := parse6hb1Instruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "6hb1") + case _8rsrProgramID: + txRes, err := parse8rsrInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "8rsr") + case boboProgramID: + txRes, err := parseBoboInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "bobo") + case qtkvProgramID: + txRes, err := parseQtkvInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "qtkv") + case fjszProgramID: + txRes, err := parseFjszInstruction(versioned, i) + parsed = appendParsed(parsed, txRes, err, txHash, "fjsz") + } + } + + return parsed +} + +func appendParsed(list []*types.TxSignal, parsed *types.TxSignal, err error, txHash string, label string) []*types.TxSignal { + if err != nil { + log.Printf("txparser: failed to parse %s instruction: %v, tx_hash: %s", label, err, txHash) + return list + } + if parsed != nil { + list = append(list, parsed) + } + return list +} + +func toVersionedTransaction(update *shreder_protos.SubscribeUpdateTransaction) (*versionedTransaction, error) { + if update == nil || update.Transaction == nil || update.Transaction.Message == nil { + return nil, fmt.Errorf("transaction is nil") + } + + protoTx := update.Transaction + msg := protoTx.Message + + signatures := make([]solana.Signature, len(protoTx.Signatures)) + for i, rawSig := range protoTx.Signatures { + signatures[i] = solana.SignatureFromBytes(rawSig) + } + + staticKeys := make([]solana.PublicKey, len(msg.AccountKeys)) + for i, key := range msg.AccountKeys { + staticKeys[i] = solana.PublicKeyFromBytes(key) + } + + instructions := make([]compiledInstruction, len(msg.Instructions)) + for i, instr := range msg.Instructions { + accounts := append([]uint8(nil), instr.Accounts...) + instructions[i] = compiledInstruction{ + ProgramIDIndex: uint8(instr.ProgramIdIndex), + Accounts: accounts, + Data: instr.Data, + } + } + + lookups := make([]addressTableLookup, len(msg.AddressTableLookups)) + for i, lookup := range msg.AddressTableLookups { + writable := append([]uint8(nil), lookup.WritableIndexes...) + readonly := append([]uint8(nil), lookup.ReadonlyIndexes...) + lookups[i] = addressTableLookup{ + AccountKey: solana.PublicKeyFromBytes(lookup.AccountKey), + WritableIndexes: writable, + ReadonlyIndexes: readonly, + } + } + + return &versionedTransaction{ + Signatures: signatures, + Message: versionedMessage{ + StaticAccountKeys: staticKeys, + Instructions: instructions, + AddressTableLookups: lookups, + }, + Block: update.GetSlot(), + }, nil +} + +func formatTokenAmount(amount uint64) decimal.Decimal { + val := decimal.NewFromBigInt(new(big.Int).SetUint64(amount), 0) + return val.Div(decimal.NewFromInt(1_000_000)) +} + +func formatSolAmount(lamports uint64) decimal.Decimal { + val := decimal.NewFromBigInt(new(big.Int).SetUint64(lamports), 0) + return val.Div(decimal.NewFromInt(1_000_000_000)) +} + +func getStaticKey(static []solana.PublicKey, index int) (solana.PublicKey, error) { + if index < 0 || index >= len(static) { + return solana.PublicKey{}, fmt.Errorf("account index %d out of bounds", index) + } + return static[index], nil +} + +func parsePumpInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + switch instruction.Data[0] { + case pumpBuyTokensIX: + return parsePumpBuy(tx, &instruction) + case pumpExtendedSellIX: + return parsePumpSell(tx, &instruction) + case pumpCreateCoinIX: + return parsePumpCreate(tx, &instruction) + case pumpCreateCoinV2IX: + return parsePumpCreateV2(tx, &instruction) + default: + return nil, nil + } +} + +func parsePumpCreate(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[0])) + if err != nil { + return nil, err + } + creator, err := getStaticKey(staticKeys, int(instruction.Accounts[7])) + if err != nil { + return nil, err + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: creator.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: decimal.Zero, + Token1Amount: decimal.Zero, + Program: "Pump", + Event: "create", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: 0, + Token1AmountUint64: 0, + }, nil +} + +func parsePumpCreateV2(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 8 { + return nil, fmt.Errorf("data too short for create v2 args") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[0])) + if err != nil { + return nil, err + } + tokenProgramKey, err := getStaticKey(staticKeys, int(instruction.Accounts[7])) + if err != nil { + return nil, err + } + + var args pumpCreateCoinV2Args + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse create coin v2 args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: args.Creator.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: decimal.Zero, + Token1Amount: decimal.Zero, + Program: "Pump", + Event: "create", + IsToken2022: tokenProgramKey.String() != tokenProgram, + IsMayhemMode: args.IsMayhemMode, + Block: tx.Block, + Token0AmountUint64: 0, + Token1AmountUint64: 0, + }, nil +} + +func decodePumpBuyArgs(data []byte) (uint64, uint64, error) { + if len(data) < 9 { + return 0, 0, fmt.Errorf("data too short for buy args") + } + + var args pumpBuyArgs + if err := borsh.Deserialize(&args, data[8:]); err == nil { + return args.Amount, args.MaxSolCost, nil + } + + if len(data) >= 24 { + amount := binary.LittleEndian.Uint64(data[8:16]) + maxSol := binary.LittleEndian.Uint64(data[16:24]) + return amount, maxSol, nil + } + + return 0, 0, fmt.Errorf("failed to parse buy tokens args") +} + +func parsePumpBuy(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + amount, maxSol, err := decodePumpBuyArgs(instruction.Data) + if err != nil { + return nil, err + } + + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2])) + if err != nil { + return nil, err + } + buyer, err := getStaticKey(staticKeys, int(instruction.Accounts[6])) + if err != nil { + return nil, err + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: buyer.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(amount), + Token1Amount: formatSolAmount(maxSol), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: amount, + Token1AmountUint64: maxSol, + }, nil +} + +func decodePumpSellArgs(data []byte) (uint64, uint64, error) { + if len(data) < 9 { + return 0, 0, fmt.Errorf("data too short for sell args") + } + + var args pumpExtendedSellArgs + if err := borsh.Deserialize(&args, data[8:]); err == nil { + return args.Amount, args.MinSolOutput, nil + } + + if len(data) >= 24 { + amount := binary.LittleEndian.Uint64(data[8:16]) + minSol := binary.LittleEndian.Uint64(data[16:24]) + return amount, minSol, nil + } + + return 0, 0, fmt.Errorf("failed to parse sell tokens args") +} + +func parsePumpSell(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + amount, minSol, err := decodePumpSellArgs(instruction.Data) + if err != nil { + return nil, err + } + + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2])) + if err != nil { + return nil, err + } + seller, err := getStaticKey(staticKeys, int(instruction.Accounts[6])) + if err != nil { + return nil, err + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: seller.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(amount), + Token1Amount: formatSolAmount(minSol), + Program: "Pump", + Event: "sell", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: amount, + Token1AmountUint64: minSol, + }, nil +} + +func parseAzczInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != azczBuyTokensIX { + return nil, nil + } + + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := msg.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[7])) + if err != nil { + return nil, err + } + + if len(instruction.Data) < 2 { + return nil, fmt.Errorf("data too short for buy args") + } + + var args azczBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[1:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenAmount), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenAmount, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parseF5tfInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != f5tfBuyTokensIX { + return nil, nil + } + + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := msg.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[6])) + if err != nil { + return nil, err + } + + if len(instruction.Data) < 2 { + return nil, fmt.Errorf("data too short for buy args") + } + + var args f5tfBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[1:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenAmount), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenAmount, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parseFlasInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != flasBuyTokensIX { + return nil, nil + } + + if len(instruction.Accounts) < 9 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := msg.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[8])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[0])) + if err != nil { + return nil, err + } + + if len(instruction.Data) < 2 { + return nil, fmt.Errorf("data too short for buy args") + } + + var args flasBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[1:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenAmount), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenAmount, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parsePhotonInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + if len(instruction.Data) < 8 { + return nil, nil + } + + switch { + case bytes.Equal(instruction.Data[:8], photonBuyPumpTokensIX): + return parsePhotonBuy(tx, &instruction) + case bytes.Equal(instruction.Data[:8], photonSwapPumpAmmIX): + return parsePhotonSwap(tx, &instruction) + default: + return nil, nil + } +} + +func parsePhotonBuy(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 16 { + return nil, fmt.Errorf("data too short for buy args") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[7])) + if err != nil { + return nil, err + } + + var args photonBuyPumpArgs + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + solAmount := args.SolAmount * (100000000 - 1234568) / 100000000 + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenAmount), + Token1Amount: formatSolAmount(solAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenAmount, + Token1AmountUint64: solAmount, + }, nil +} + +func parsePhotonSwap(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 16 { + return nil, fmt.Errorf("data too short for swap args") + } + + staticKeys := tx.Message.StaticAccountKeys + base, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + + quoteIndex := int(instruction.Accounts[4]) + quote, err := resolveQuoteAccount(tx, quoteIndex, []string{photonTableLookup}, 0) + if err != nil { + return nil, err + } + if quote != wsolMint { + return nil, nil + } + + buyer, err := getStaticKey(staticKeys, int(instruction.Accounts[1])) + if err != nil { + return nil, err + } + + var args photonSwapPumpAmmArgs + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse swap pump amm tokens args: %w", err) + } + + if args.FromAmount > args.ToAmount { + // sell; ignore + return nil, nil + } + + solAmount := args.FromAmount * (100000000 - 1234568) / 100000000 + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: buyer.String(), + Token0Address: base.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.ToAmount), + Token1Amount: formatSolAmount(solAmount), + Program: "PumpAMM", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.ToAmount, + Token1AmountUint64: solAmount, + }, nil +} + +func parsePumpAmmInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != pumpAmmBuyTokensIX { + return nil, nil + } + + return parsePumpAmmBuy(tx, &instruction) +} + +func decodePumpAmmBuyArgs(data []byte) (uint64, uint64, error) { + if len(data) < 9 { + return 0, 0, fmt.Errorf("data too short for buy args") + } + + var args pumpAmmBuyArgs + if err := borsh.Deserialize(&args, data[8:]); err == nil { + return args.Amount, args.MaxSolCost, nil + } + + if len(data) >= 24 { + amount := binary.LittleEndian.Uint64(data[8:16]) + maxSol := binary.LittleEndian.Uint64(data[16:24]) + return amount, maxSol, nil + } + + return 0, 0, fmt.Errorf("failed to parse buy tokens args") +} + +func parsePumpAmmBuy(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + amount, maxSol, err := decodePumpAmmBuyArgs(instruction.Data) + if err != nil { + return nil, err + } + + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + base, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + quoteIndex := int(instruction.Accounts[4]) + quote, err := resolveQuoteAccount(tx, quoteIndex, nil, 0) + if err != nil { + return nil, err + } + if quote != wsolMint { + return nil, nil + } + + buyer, err := getStaticKey(staticKeys, int(instruction.Accounts[1])) + if err != nil { + return nil, err + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: buyer.String(), + Token0Address: base.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(amount), + Token1Amount: formatSolAmount(maxSol), + Program: "PumpAMM", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: amount, + Token1AmountUint64: maxSol, + }, nil +} + +func parse6hb1Instruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != _6hb1BuyTokensIX { + return nil, nil + } + + return parse6hb1Buy(tx, &instruction) +} + +func parse6hb1Buy(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + base, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + + quoteIndex := int(instruction.Accounts[4]) + quote, err := resolveQuoteAccount(tx, quoteIndex, []string{_6hb1TableLookup1, _6hb1TableLookup2}, 7) + if err != nil { + return nil, err + } + if quote != wsolMint { + return nil, nil + } + + buyer, err := getStaticKey(staticKeys, int(instruction.Accounts[1])) + if err != nil { + return nil, err + } + + if len(instruction.Data) < 2 { + return nil, fmt.Errorf("data too short for buy args") + } + + var args _6hb1BuyArgs + if err := borsh.Deserialize(&args, instruction.Data[1:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: buyer.String(), + Token0Address: base.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenNumber), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "PumpAMM", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenNumber, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parse8rsrInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if len(instruction.Data) < 8 || !bytes.Equal(instruction.Data[:8], _8rsrBuyTokensIX) { + return nil, nil + } + + return parse8rsrBuy(tx, &instruction) +} + +func parse8rsrBuy(tx *versionedTransaction, instruction *compiledInstruction) (*types.TxSignal, error) { + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 16 { + return nil, fmt.Errorf("data too short for buy args") + } + + staticKeys := tx.Message.StaticAccountKeys + base, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + + quoteIndex := int(instruction.Accounts[4]) + quote, err := resolveQuoteAccount(tx, quoteIndex, []string{_8rsrTableLookup1}, 1) + if err != nil { + return nil, err + } + if quote != wsolMint { + return nil, nil + } + + buyer, err := getStaticKey(staticKeys, int(instruction.Accounts[1])) + if err != nil { + return nil, err + } + + var args _8rsrBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: buyer.String(), + Token0Address: base.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenOut), + Token1Amount: formatSolAmount(args.SolIn), + Program: "PumpAMM", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenOut, + Token1AmountUint64: args.SolIn, + }, nil +} + +func parseBoboInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + if len(instruction.Data) < 8 || !bytes.Equal(instruction.Data[:8], boboBuyPumpTokensIX) { + return nil, nil + } + + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 16 { + return nil, fmt.Errorf("data too short for buy args") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[6])) + if err != nil { + return nil, err + } + + var args boboBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: decimal.NewFromInt(1), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: 1, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parseQtkvInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if instruction.Data[0] != qtkvBuyTokensIX { + return nil, nil + } + if len(instruction.Data) < 2 { + return nil, fmt.Errorf("data too short for buy args") + } + if len(instruction.Accounts) < 8 { + return nil, fmt.Errorf("accounts too short") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[3])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[0])) + if err != nil { + return nil, err + } + + var args qtkvBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[1:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenNumber), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenNumber, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func parseFjszInstruction(tx *versionedTransaction, instructionIndex int) (*types.TxSignal, error) { + msg := tx.Message + if instructionIndex >= len(msg.Instructions) { + return nil, fmt.Errorf("instruction index out of bounds") + } + + instruction := msg.Instructions[instructionIndex] + if len(instruction.Data) == 0 { + return nil, fmt.Errorf("data is empty") + } + + if len(instruction.Data) < 8 || !bytes.Equal(instruction.Data[:8], fjszBuyTokensIX) { + return nil, nil + } + if len(instruction.Accounts) < 7 { + return nil, fmt.Errorf("accounts too short") + } + if len(instruction.Data) < 16 { + return nil, fmt.Errorf("data too short for buy args") + } + + staticKeys := tx.Message.StaticAccountKeys + mint, err := getStaticKey(staticKeys, int(instruction.Accounts[2])) + if err != nil { + return nil, err + } + user, err := getStaticKey(staticKeys, int(instruction.Accounts[6])) + if err != nil { + return nil, err + } + + var args fjszBuyArgs + if err := borsh.Deserialize(&args, instruction.Data[8:]); err != nil { + return nil, fmt.Errorf("failed to parse buy tokens args: %w", err) + } + + return &types.TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: user.String(), + Token0Address: mint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(args.TokenAmount), + Token1Amount: formatSolAmount(args.SolAmount), + Program: "Pump", + Event: "buy", + IsToken2022: false, + IsMayhemMode: false, + Block: tx.Block, + Token0AmountUint64: args.TokenAmount, + Token1AmountUint64: args.SolAmount, + }, nil +} + +func resolveQuoteAccount(tx *versionedTransaction, quoteIndex int, expectedTableKeys []string, targetIndex uint8) (string, error) { + staticKeys := tx.Message.StaticAccountKeys + if quoteIndex < len(staticKeys) { + quoteKey := staticKeys[quoteIndex].String() + return quoteKey, nil + } + + // attempt to load from address table lookup + if len(expectedTableKeys) == 0 || len(tx.Message.AddressTableLookups) != 1 { + return "", fmt.Errorf("parse quote from table lookup failed") + } + + table := tx.Message.AddressTableLookups[0] + match := false + for _, key := range expectedTableKeys { + if table.AccountKey.String() == key { + match = true + break + } + } + if !match { + return "", fmt.Errorf("parse quote from table lookup failed") + } + + indexOfTarget := indexOf(table.ReadonlyIndexes, targetIndex) + if indexOfTarget < 0 { + return "", fmt.Errorf("parse quote from table lookup failed") + } + + expectedIndex := len(staticKeys) + len(table.WritableIndexes) + indexOfTarget + if quoteIndex != expectedIndex { + return "", fmt.Errorf("parse quote from table lookup failed") + } + + return wsolMint, nil +} + +func indexOf(haystack []uint8, needle uint8) int { + for i, v := range haystack { + if v == needle { + return i + } + } + return -1 +} diff --git a/pkg/types/tx_signal.go b/pkg/types/tx_signal.go new file mode 100644 index 0000000..26bf4a3 --- /dev/null +++ b/pkg/types/tx_signal.go @@ -0,0 +1,38 @@ +package types + +import ( + "time" + + "github.com/samlior/libsam/pkg/consts" + "github.com/shopspring/decimal" +) + +type TxSignal struct { + Source string + TxHash string + Maker string + Token0Address string + Token1Address string + Token0Amount decimal.Decimal + Token1Amount decimal.Decimal + Block uint64 + BlockAt time.Time + BlockIndex uint64 + Event string + Program string + IsProcessed bool + IsToken2022 bool + IsMayhemMode bool + TxFee decimal.Decimal + + Token0AmountUint64 uint64 + Token1AmountUint64 uint64 +} + +func (t *TxSignal) Parse() *TxSignal { + t.Token0AmountUint64 = t.Token0Amount.Mul(decimal.New(1, consts.TokenDecimals)).BigInt().Uint64() + t.Token1AmountUint64 = t.Token1Amount.Mul(decimal.New(1, consts.SolDecimals)).BigInt().Uint64() + return t +} + +type TxSignalBatch = []*TxSignal \ No newline at end of file diff --git a/third_party/google/api/annotations.proto b/third_party/google/api/annotations.proto new file mode 100644 index 0000000..85c361b --- /dev/null +++ b/third_party/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright (c) 2015, Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/third_party/google/api/client.proto b/third_party/google/api/client.proto new file mode 100644 index 0000000..d3d1ead --- /dev/null +++ b/third_party/google/api/client.proto @@ -0,0 +1,101 @@ +// Copyright 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "ClientProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +extend google.protobuf.ServiceOptions { + // The hostname for this service. + // This should be specified with no prefix or protocol. + // + // Example: + // + // service Foo { + // option (google.api.default_host) = "foo.googleapi.com"; + // ... + // } + string default_host = 1049; + + // OAuth scopes needed for the client. + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform"; + // ... + // } + // + // If there is more than one scope, use a comma-separated string: + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform," + // "https://www.googleapis.com/auth/monitoring"; + // ... + // } + string oauth_scopes = 1050; +} + + +extend google.protobuf.MethodOptions { + // A definition of a client library method signature. + // + // In client libraries, each proto RPC corresponds to one or more methods + // which the end user is able to call, and calls the underlying RPC. + // Normally, this method receives a single argument (a struct or instance + // corresponding to the RPC request object). Defining this field will + // add one or more overloads providing flattened or simpler method signatures + // in some languages. + // + // The fields on the method signature are provided as a comma-separated + // string. + // + // For example, the proto RPC and annotation: + // + // rpc CreateSubscription(CreateSubscriptionRequest) + // returns (Subscription) { + // option (google.api.method_signature) = "name,topic"; + // } + // + // Would add the following Java overload (in addition to the method accepting + // the request object): + // + // public final Subscription createSubscription(String name, String topic) + // + // The following backwards-compatibility guidelines apply: + // + // * Adding this annotation to an unannotated method is backwards + // compatible. + // * Adding this annotation to a method which already has existing + // method signature annotations is backwards compatible if and only if + // the new method signature annotation is last in the sequence. + // * Modifying or removing an existing method signature annotation is + // a breaking change. + // * Re-ordering existing method signature annotations is a breaking + // change. + repeated string method_signature = 1051; +} \ No newline at end of file diff --git a/third_party/google/api/field_behavior.proto b/third_party/google/api/field_behavior.proto new file mode 100644 index 0000000..e9716a2 --- /dev/null +++ b/third_party/google/api/field_behavior.proto @@ -0,0 +1,80 @@ +// Copyright 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "FieldBehaviorProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +enum FieldBehavior { + // Conventional default for enums. Do not use this. + FIELD_BEHAVIOR_UNSPECIFIED = 0; + + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + OPTIONAL = 1; + + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + REQUIRED = 2; + + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + OUTPUT_ONLY = 3; + + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + INPUT_ONLY = 4; + + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + IMMUTABLE = 5; +} + + +extend google.protobuf.FieldOptions { + // A designation of a specific field behavior (required, output only, etc.) + // in protobuf messages. + // + // Examples: + // + // string name = 1 [(google.api.field_behavior) = REQUIRED]; + // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + // google.protobuf.Duration ttl = 1 + // [(google.api.field_behavior) = INPUT_ONLY]; + // google.protobuf.Timestamp expire_time = 1 + // [(google.api.field_behavior) = OUTPUT_ONLY, + // (google.api.field_behavior) = IMMUTABLE]; + repeated FieldBehavior field_behavior = 1052; +} \ No newline at end of file diff --git a/third_party/google/api/http.proto b/third_party/google/api/http.proto new file mode 100644 index 0000000..69460cf --- /dev/null +++ b/third_party/google/api/http.proto @@ -0,0 +1,375 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/third_party/google/api/httpbody.proto b/third_party/google/api/httpbody.proto new file mode 100644 index 0000000..1a5bb78 --- /dev/null +++ b/third_party/google/api/httpbody.proto @@ -0,0 +1,77 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; +option java_multiple_files = true; +option java_outer_classname = "HttpBodyProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Message that represents an arbitrary HTTP body. It should only be used for +// payload formats that can't be represented as JSON, such as raw binary or +// an HTML page. +// +// +// This message can be used both in streaming and non-streaming API methods in +// the request as well as the response. +// +// It can be used as a top-level request field, which is convenient if one +// wants to extract parameters from either the URL or HTTP template into the +// request fields and also want access to the raw HTTP body. +// +// Example: +// +// message GetResourceRequest { +// // A unique request id. +// string request_id = 1; +// +// // The raw HTTP body is bound to this field. +// google.api.HttpBody http_body = 2; +// } +// +// service ResourceService { +// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) returns +// (google.protobuf.Empty); +// } +// +// Example with streaming methods: +// +// service CaldavService { +// rpc GetCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// rpc UpdateCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// } +// +// Use of this type only changes how the request and response bodies are +// handled, all other features will continue to work unchanged. +message HttpBody { + // The HTTP Content-Type header value specifying the content type of the body. + string content_type = 1; + + // The HTTP request/response body as raw binary. + bytes data = 2; + + // Application specific response metadata. Must be set in the first response + // for streaming APIs. + repeated google.protobuf.Any extensions = 3; +} diff --git a/third_party/google/protobuf/any.proto b/third_party/google/protobuf/any.proto new file mode 100644 index 0000000..e2c2042 --- /dev/null +++ b/third_party/google/protobuf/any.proto @@ -0,0 +1,158 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/third_party/google/protobuf/api.proto b/third_party/google/protobuf/api.proto new file mode 100644 index 0000000..3d598fc --- /dev/null +++ b/third_party/google/protobuf/api.proto @@ -0,0 +1,208 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inheriting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/third_party/google/protobuf/compiler/plugin.proto b/third_party/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..9242aac --- /dev/null +++ b/third_party/google/protobuf/compiler/plugin.proto @@ -0,0 +1,183 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option go_package = "google.golang.org/protobuf/types/pluginpb"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // The version number of protocol compiler. + optional Version compiler_version = 3; + +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + } + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; + } + repeated File file = 15; +} diff --git a/third_party/google/protobuf/descriptor.proto b/third_party/google/protobuf/descriptor.proto new file mode 100644 index 0000000..49ec653 --- /dev/null +++ b/third_party/google/protobuf/descriptor.proto @@ -0,0 +1,921 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + // + // As of 2021, lazy does no correctness checks on the byte stream during + // parsing. This may lead to crashes if and when an invalid byte stream is + // finally parsed upon access. + // + // TODO(b/211906113): Enable validation on lazy fields. + optional bool lazy = 5 [default = false]; + + // unverified_lazy does no correctness checks on the byte stream. This should + // only be used where lazy with verification is prohibitive for performance + // reasons. + optional bool unverified_lazy = 15 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition occurs. + // For example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/third_party/google/protobuf/duration.proto b/third_party/google/protobuf/duration.proto new file mode 100644 index 0000000..81c3e36 --- /dev/null +++ b/third_party/google/protobuf/duration.proto @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/third_party/google/protobuf/empty.proto b/third_party/google/protobuf/empty.proto new file mode 100644 index 0000000..5f992de --- /dev/null +++ b/third_party/google/protobuf/empty.proto @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/emptypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +message Empty {} diff --git a/third_party/google/protobuf/field_mask.proto b/third_party/google/protobuf/field_mask.proto new file mode 100644 index 0000000..6b5104f --- /dev/null +++ b/third_party/google/protobuf/field_mask.proto @@ -0,0 +1,245 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/third_party/google/protobuf/source_context.proto b/third_party/google/protobuf/source_context.proto new file mode 100644 index 0000000..06bfc43 --- /dev/null +++ b/third_party/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/third_party/google/protobuf/struct.proto b/third_party/google/protobuf/struct.proto new file mode 100644 index 0000000..0ac843c --- /dev/null +++ b/third_party/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/third_party/google/protobuf/timestamp.proto b/third_party/google/protobuf/timestamp.proto new file mode 100644 index 0000000..3b2df6d --- /dev/null +++ b/third_party/google/protobuf/timestamp.proto @@ -0,0 +1,147 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/third_party/google/protobuf/type.proto b/third_party/google/protobuf/type.proto new file mode 100644 index 0000000..d3f6a68 --- /dev/null +++ b/third_party/google/protobuf/type.proto @@ -0,0 +1,187 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + } + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; +} diff --git a/third_party/google/protobuf/wrappers.proto b/third_party/google/protobuf/wrappers.proto new file mode 100644 index 0000000..d49dd53 --- /dev/null +++ b/third_party/google/protobuf/wrappers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/third_party/shreder_protos/shreder.pb.go b/third_party/shreder_protos/shreder.pb.go new file mode 100644 index 0000000..282401f --- /dev/null +++ b/third_party/shreder_protos/shreder.pb.go @@ -0,0 +1,773 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: shreder.proto + +package shreder_protos + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SubscribeEntriesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscribeEntriesRequest) Reset() { + *x = SubscribeEntriesRequest{} + mi := &file_shreder_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscribeEntriesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeEntriesRequest) ProtoMessage() {} + +func (x *SubscribeEntriesRequest) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeEntriesRequest.ProtoReflect.Descriptor instead. +func (*SubscribeEntriesRequest) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{0} +} + +type SubscribeTransactionsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Transactions map[string]*SubscribeRequestFilterTransactions `protobuf:"bytes,3,rep,name=transactions,proto3" json:"transactions,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscribeTransactionsRequest) Reset() { + *x = SubscribeTransactionsRequest{} + mi := &file_shreder_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscribeTransactionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeTransactionsRequest) ProtoMessage() {} + +func (x *SubscribeTransactionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeTransactionsRequest.ProtoReflect.Descriptor instead. +func (*SubscribeTransactionsRequest) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{1} +} + +func (x *SubscribeTransactionsRequest) GetTransactions() map[string]*SubscribeRequestFilterTransactions { + if x != nil { + return x.Transactions + } + return nil +} + +type SubscribeTransactionsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filters []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` + Transaction *SubscribeUpdateTransaction `protobuf:"bytes,4,opt,name=transaction,proto3" json:"transaction,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscribeTransactionsResponse) Reset() { + *x = SubscribeTransactionsResponse{} + mi := &file_shreder_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscribeTransactionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeTransactionsResponse) ProtoMessage() {} + +func (x *SubscribeTransactionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeTransactionsResponse.ProtoReflect.Descriptor instead. +func (*SubscribeTransactionsResponse) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{2} +} + +func (x *SubscribeTransactionsResponse) GetFilters() []string { + if x != nil { + return x.Filters + } + return nil +} + +func (x *SubscribeTransactionsResponse) GetTransaction() *SubscribeUpdateTransaction { + if x != nil { + return x.Transaction + } + return nil +} + +func (x *SubscribeTransactionsResponse) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type SubscribeUpdateTransaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Transaction *Transaction `protobuf:"bytes,1,opt,name=transaction,proto3" json:"transaction,omitempty"` + Slot uint64 `protobuf:"varint,2,opt,name=slot,proto3" json:"slot,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscribeUpdateTransaction) Reset() { + *x = SubscribeUpdateTransaction{} + mi := &file_shreder_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscribeUpdateTransaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeUpdateTransaction) ProtoMessage() {} + +func (x *SubscribeUpdateTransaction) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeUpdateTransaction.ProtoReflect.Descriptor instead. +func (*SubscribeUpdateTransaction) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{3} +} + +func (x *SubscribeUpdateTransaction) GetTransaction() *Transaction { + if x != nil { + return x.Transaction + } + return nil +} + +func (x *SubscribeUpdateTransaction) GetSlot() uint64 { + if x != nil { + return x.Slot + } + return 0 +} + +type SubscribeRequestFilterTransactions struct { + state protoimpl.MessageState `protogen:"open.v1"` + AccountInclude []string `protobuf:"bytes,3,rep,name=account_include,json=accountInclude,proto3" json:"account_include,omitempty"` + AccountExclude []string `protobuf:"bytes,4,rep,name=account_exclude,json=accountExclude,proto3" json:"account_exclude,omitempty"` + AccountRequired []string `protobuf:"bytes,6,rep,name=account_required,json=accountRequired,proto3" json:"account_required,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscribeRequestFilterTransactions) Reset() { + *x = SubscribeRequestFilterTransactions{} + mi := &file_shreder_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscribeRequestFilterTransactions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeRequestFilterTransactions) ProtoMessage() {} + +func (x *SubscribeRequestFilterTransactions) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeRequestFilterTransactions.ProtoReflect.Descriptor instead. +func (*SubscribeRequestFilterTransactions) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{4} +} + +func (x *SubscribeRequestFilterTransactions) GetAccountInclude() []string { + if x != nil { + return x.AccountInclude + } + return nil +} + +func (x *SubscribeRequestFilterTransactions) GetAccountExclude() []string { + if x != nil { + return x.AccountExclude + } + return nil +} + +func (x *SubscribeRequestFilterTransactions) GetAccountRequired() []string { + if x != nil { + return x.AccountRequired + } + return nil +} + +type Entry struct { + state protoimpl.MessageState `protogen:"open.v1"` + // the slot that the entry is from + Slot uint64 `protobuf:"varint,1,opt,name=slot,proto3" json:"slot,omitempty"` + // Serialized bytes of Vec: https://docs.rs/solana-entry/latest/solana_entry/entry/struct.Entry.html + Entries []byte `protobuf:"bytes,2,opt,name=entries,proto3" json:"entries,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Entry) Reset() { + *x = Entry{} + mi := &file_shreder_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Entry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Entry) ProtoMessage() {} + +func (x *Entry) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Entry.ProtoReflect.Descriptor instead. +func (*Entry) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{5} +} + +func (x *Entry) GetSlot() uint64 { + if x != nil { + return x.Slot + } + return 0 +} + +func (x *Entry) GetEntries() []byte { + if x != nil { + return x.Entries + } + return nil +} + +type MessageHeader struct { + state protoimpl.MessageState `protogen:"open.v1"` + NumRequiredSignatures uint32 `protobuf:"varint,1,opt,name=num_required_signatures,json=numRequiredSignatures,proto3" json:"num_required_signatures,omitempty"` + NumReadonlySignedAccounts uint32 `protobuf:"varint,2,opt,name=num_readonly_signed_accounts,json=numReadonlySignedAccounts,proto3" json:"num_readonly_signed_accounts,omitempty"` + NumReadonlyUnsignedAccounts uint32 `protobuf:"varint,3,opt,name=num_readonly_unsigned_accounts,json=numReadonlyUnsignedAccounts,proto3" json:"num_readonly_unsigned_accounts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessageHeader) Reset() { + *x = MessageHeader{} + mi := &file_shreder_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessageHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageHeader) ProtoMessage() {} + +func (x *MessageHeader) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageHeader.ProtoReflect.Descriptor instead. +func (*MessageHeader) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{6} +} + +func (x *MessageHeader) GetNumRequiredSignatures() uint32 { + if x != nil { + return x.NumRequiredSignatures + } + return 0 +} + +func (x *MessageHeader) GetNumReadonlySignedAccounts() uint32 { + if x != nil { + return x.NumReadonlySignedAccounts + } + return 0 +} + +func (x *MessageHeader) GetNumReadonlyUnsignedAccounts() uint32 { + if x != nil { + return x.NumReadonlyUnsignedAccounts + } + return 0 +} + +type CompiledInstruction struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProgramIdIndex uint32 `protobuf:"varint,1,opt,name=program_id_index,json=programIdIndex,proto3" json:"program_id_index,omitempty"` + Accounts []byte `protobuf:"bytes,2,opt,name=accounts,proto3" json:"accounts,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompiledInstruction) Reset() { + *x = CompiledInstruction{} + mi := &file_shreder_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompiledInstruction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompiledInstruction) ProtoMessage() {} + +func (x *CompiledInstruction) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompiledInstruction.ProtoReflect.Descriptor instead. +func (*CompiledInstruction) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{7} +} + +func (x *CompiledInstruction) GetProgramIdIndex() uint32 { + if x != nil { + return x.ProgramIdIndex + } + return 0 +} + +func (x *CompiledInstruction) GetAccounts() []byte { + if x != nil { + return x.Accounts + } + return nil +} + +func (x *CompiledInstruction) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type MessageAddressTableLookup struct { + state protoimpl.MessageState `protogen:"open.v1"` + AccountKey []byte `protobuf:"bytes,1,opt,name=account_key,json=accountKey,proto3" json:"account_key,omitempty"` + WritableIndexes []byte `protobuf:"bytes,2,opt,name=writable_indexes,json=writableIndexes,proto3" json:"writable_indexes,omitempty"` + ReadonlyIndexes []byte `protobuf:"bytes,3,opt,name=readonly_indexes,json=readonlyIndexes,proto3" json:"readonly_indexes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessageAddressTableLookup) Reset() { + *x = MessageAddressTableLookup{} + mi := &file_shreder_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessageAddressTableLookup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageAddressTableLookup) ProtoMessage() {} + +func (x *MessageAddressTableLookup) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageAddressTableLookup.ProtoReflect.Descriptor instead. +func (*MessageAddressTableLookup) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{8} +} + +func (x *MessageAddressTableLookup) GetAccountKey() []byte { + if x != nil { + return x.AccountKey + } + return nil +} + +func (x *MessageAddressTableLookup) GetWritableIndexes() []byte { + if x != nil { + return x.WritableIndexes + } + return nil +} + +func (x *MessageAddressTableLookup) GetReadonlyIndexes() []byte { + if x != nil { + return x.ReadonlyIndexes + } + return nil +} + +type Message struct { + state protoimpl.MessageState `protogen:"open.v1"` + Header *MessageHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + AccountKeys [][]byte `protobuf:"bytes,2,rep,name=account_keys,json=accountKeys,proto3" json:"account_keys,omitempty"` + RecentBlockhash []byte `protobuf:"bytes,3,opt,name=recent_blockhash,json=recentBlockhash,proto3" json:"recent_blockhash,omitempty"` + Instructions []*CompiledInstruction `protobuf:"bytes,4,rep,name=instructions,proto3" json:"instructions,omitempty"` + Versioned bool `protobuf:"varint,5,opt,name=versioned,proto3" json:"versioned,omitempty"` + AddressTableLookups []*MessageAddressTableLookup `protobuf:"bytes,6,rep,name=address_table_lookups,json=addressTableLookups,proto3" json:"address_table_lookups,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Message) Reset() { + *x = Message{} + mi := &file_shreder_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{9} +} + +func (x *Message) GetHeader() *MessageHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *Message) GetAccountKeys() [][]byte { + if x != nil { + return x.AccountKeys + } + return nil +} + +func (x *Message) GetRecentBlockhash() []byte { + if x != nil { + return x.RecentBlockhash + } + return nil +} + +func (x *Message) GetInstructions() []*CompiledInstruction { + if x != nil { + return x.Instructions + } + return nil +} + +func (x *Message) GetVersioned() bool { + if x != nil { + return x.Versioned + } + return false +} + +func (x *Message) GetAddressTableLookups() []*MessageAddressTableLookup { + if x != nil { + return x.AddressTableLookups + } + return nil +} + +type Transaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Signatures [][]byte `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Transaction) Reset() { + *x = Transaction{} + mi := &file_shreder_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Transaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Transaction) ProtoMessage() {} + +func (x *Transaction) ProtoReflect() protoreflect.Message { + mi := &file_shreder_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Transaction.ProtoReflect.Descriptor instead. +func (*Transaction) Descriptor() ([]byte, []int) { + return file_shreder_proto_rawDescGZIP(), []int{10} +} + +func (x *Transaction) GetSignatures() [][]byte { + if x != nil { + return x.Signatures + } + return nil +} + +func (x *Transaction) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +var File_shreder_proto protoreflect.FileDescriptor + +const file_shreder_proto_rawDesc = "" + + "\n" + + "\rshreder.proto\x12\vshredstream\x1a\x1fgoogle/protobuf/timestamp.proto\"\x19\n" + + "\x17SubscribeEntriesRequest\"\xf1\x01\n" + + "\x1cSubscribeTransactionsRequest\x12_\n" + + "\ftransactions\x18\x03 \x03(\v2;.shredstream.SubscribeTransactionsRequest.TransactionsEntryR\ftransactions\x1ap\n" + + "\x11TransactionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12E\n" + + "\x05value\x18\x02 \x01(\v2/.shredstream.SubscribeRequestFilterTransactionsR\x05value:\x028\x01\"\xbf\x01\n" + + "\x1dSubscribeTransactionsResponse\x12\x18\n" + + "\afilters\x18\x01 \x03(\tR\afilters\x12I\n" + + "\vtransaction\x18\x04 \x01(\v2'.shredstream.SubscribeUpdateTransactionR\vtransaction\x129\n" + + "\n" + + "created_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\"l\n" + + "\x1aSubscribeUpdateTransaction\x12:\n" + + "\vtransaction\x18\x01 \x01(\v2\x18.shredstream.TransactionR\vtransaction\x12\x12\n" + + "\x04slot\x18\x02 \x01(\x04R\x04slot\"\xa1\x01\n" + + "\"SubscribeRequestFilterTransactions\x12'\n" + + "\x0faccount_include\x18\x03 \x03(\tR\x0eaccountInclude\x12'\n" + + "\x0faccount_exclude\x18\x04 \x03(\tR\x0eaccountExclude\x12)\n" + + "\x10account_required\x18\x06 \x03(\tR\x0faccountRequired\"5\n" + + "\x05Entry\x12\x12\n" + + "\x04slot\x18\x01 \x01(\x04R\x04slot\x12\x18\n" + + "\aentries\x18\x02 \x01(\fR\aentries\"\xcd\x01\n" + + "\rMessageHeader\x126\n" + + "\x17num_required_signatures\x18\x01 \x01(\rR\x15numRequiredSignatures\x12?\n" + + "\x1cnum_readonly_signed_accounts\x18\x02 \x01(\rR\x19numReadonlySignedAccounts\x12C\n" + + "\x1enum_readonly_unsigned_accounts\x18\x03 \x01(\rR\x1bnumReadonlyUnsignedAccounts\"o\n" + + "\x13CompiledInstruction\x12(\n" + + "\x10program_id_index\x18\x01 \x01(\rR\x0eprogramIdIndex\x12\x1a\n" + + "\baccounts\x18\x02 \x01(\fR\baccounts\x12\x12\n" + + "\x04data\x18\x03 \x01(\fR\x04data\"\x92\x01\n" + + "\x19MessageAddressTableLookup\x12\x1f\n" + + "\vaccount_key\x18\x01 \x01(\fR\n" + + "accountKey\x12)\n" + + "\x10writable_indexes\x18\x02 \x01(\fR\x0fwritableIndexes\x12)\n" + + "\x10readonly_indexes\x18\x03 \x01(\fR\x0freadonlyIndexes\"\xcb\x02\n" + + "\aMessage\x122\n" + + "\x06header\x18\x01 \x01(\v2\x1a.shredstream.MessageHeaderR\x06header\x12!\n" + + "\faccount_keys\x18\x02 \x03(\fR\vaccountKeys\x12)\n" + + "\x10recent_blockhash\x18\x03 \x01(\fR\x0frecentBlockhash\x12D\n" + + "\finstructions\x18\x04 \x03(\v2 .shredstream.CompiledInstructionR\finstructions\x12\x1c\n" + + "\tversioned\x18\x05 \x01(\bR\tversioned\x12Z\n" + + "\x15address_table_lookups\x18\x06 \x03(\v2&.shredstream.MessageAddressTableLookupR\x13addressTableLookups\"]\n" + + "\vTransaction\x12\x1e\n" + + "\n" + + "signatures\x18\x01 \x03(\fR\n" + + "signatures\x12.\n" + + "\amessage\x18\x02 \x01(\v2\x14.shredstream.MessageR\amessage2\xd4\x01\n" + + "\x0eShrederService\x12N\n" + + "\x10SubscribeEntries\x12$.shredstream.SubscribeEntriesRequest\x1a\x12.shredstream.Entry0\x01\x12r\n" + + "\x15SubscribeTransactions\x12).shredstream.SubscribeTransactionsRequest\x1a*.shredstream.SubscribeTransactionsResponse(\x010\x01b\x06proto3" + +var ( + file_shreder_proto_rawDescOnce sync.Once + file_shreder_proto_rawDescData []byte +) + +func file_shreder_proto_rawDescGZIP() []byte { + file_shreder_proto_rawDescOnce.Do(func() { + file_shreder_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_shreder_proto_rawDesc), len(file_shreder_proto_rawDesc))) + }) + return file_shreder_proto_rawDescData +} + +var file_shreder_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_shreder_proto_goTypes = []any{ + (*SubscribeEntriesRequest)(nil), // 0: shredstream.SubscribeEntriesRequest + (*SubscribeTransactionsRequest)(nil), // 1: shredstream.SubscribeTransactionsRequest + (*SubscribeTransactionsResponse)(nil), // 2: shredstream.SubscribeTransactionsResponse + (*SubscribeUpdateTransaction)(nil), // 3: shredstream.SubscribeUpdateTransaction + (*SubscribeRequestFilterTransactions)(nil), // 4: shredstream.SubscribeRequestFilterTransactions + (*Entry)(nil), // 5: shredstream.Entry + (*MessageHeader)(nil), // 6: shredstream.MessageHeader + (*CompiledInstruction)(nil), // 7: shredstream.CompiledInstruction + (*MessageAddressTableLookup)(nil), // 8: shredstream.MessageAddressTableLookup + (*Message)(nil), // 9: shredstream.Message + (*Transaction)(nil), // 10: shredstream.Transaction + nil, // 11: shredstream.SubscribeTransactionsRequest.TransactionsEntry + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp +} +var file_shreder_proto_depIdxs = []int32{ + 11, // 0: shredstream.SubscribeTransactionsRequest.transactions:type_name -> shredstream.SubscribeTransactionsRequest.TransactionsEntry + 3, // 1: shredstream.SubscribeTransactionsResponse.transaction:type_name -> shredstream.SubscribeUpdateTransaction + 12, // 2: shredstream.SubscribeTransactionsResponse.created_at:type_name -> google.protobuf.Timestamp + 10, // 3: shredstream.SubscribeUpdateTransaction.transaction:type_name -> shredstream.Transaction + 6, // 4: shredstream.Message.header:type_name -> shredstream.MessageHeader + 7, // 5: shredstream.Message.instructions:type_name -> shredstream.CompiledInstruction + 8, // 6: shredstream.Message.address_table_lookups:type_name -> shredstream.MessageAddressTableLookup + 9, // 7: shredstream.Transaction.message:type_name -> shredstream.Message + 4, // 8: shredstream.SubscribeTransactionsRequest.TransactionsEntry.value:type_name -> shredstream.SubscribeRequestFilterTransactions + 0, // 9: shredstream.ShrederService.SubscribeEntries:input_type -> shredstream.SubscribeEntriesRequest + 1, // 10: shredstream.ShrederService.SubscribeTransactions:input_type -> shredstream.SubscribeTransactionsRequest + 5, // 11: shredstream.ShrederService.SubscribeEntries:output_type -> shredstream.Entry + 2, // 12: shredstream.ShrederService.SubscribeTransactions:output_type -> shredstream.SubscribeTransactionsResponse + 11, // [11:13] is the sub-list for method output_type + 9, // [9:11] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_shreder_proto_init() } +func file_shreder_proto_init() { + if File_shreder_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_shreder_proto_rawDesc), len(file_shreder_proto_rawDesc)), + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_shreder_proto_goTypes, + DependencyIndexes: file_shreder_proto_depIdxs, + MessageInfos: file_shreder_proto_msgTypes, + }.Build() + File_shreder_proto = out.File + file_shreder_proto_goTypes = nil + file_shreder_proto_depIdxs = nil +} diff --git a/third_party/shreder_protos/shreder.proto b/third_party/shreder_protos/shreder.proto new file mode 100644 index 0000000..41fc023 --- /dev/null +++ b/third_party/shreder_protos/shreder.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; + +package shredstream; +import "google/protobuf/timestamp.proto"; + + +service ShrederService { + rpc SubscribeEntries(SubscribeEntriesRequest) returns (stream Entry); + rpc SubscribeTransactions(stream SubscribeTransactionsRequest) returns (stream SubscribeTransactionsResponse); +} + +message SubscribeEntriesRequest { + // tbd: we may want to add filters here +} + +message SubscribeTransactionsRequest { + map transactions = 3; +} + +message SubscribeTransactionsResponse { + repeated string filters = 1; + SubscribeUpdateTransaction transaction = 4; + google.protobuf.Timestamp created_at = 11; +} + +message SubscribeUpdateTransaction { + Transaction transaction = 1; + uint64 slot = 2; +} + +message SubscribeRequestFilterTransactions { + repeated string account_include = 3; + repeated string account_exclude = 4; + repeated string account_required = 6; +} + +message Entry { + // the slot that the entry is from + uint64 slot = 1; + + // Serialized bytes of Vec: https://docs.rs/solana-entry/latest/solana_entry/entry/struct.Entry.html + bytes entries = 2; +} + +message MessageHeader { + uint32 num_required_signatures = 1; + uint32 num_readonly_signed_accounts = 2; + uint32 num_readonly_unsigned_accounts = 3; +} + +message CompiledInstruction { + uint32 program_id_index = 1; + bytes accounts = 2; + bytes data = 3; +} + +message MessageAddressTableLookup { + bytes account_key = 1; + bytes writable_indexes = 2; + bytes readonly_indexes = 3; +} + +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 Transaction { + repeated bytes signatures = 1; + Message message = 2; +} \ No newline at end of file diff --git a/third_party/shreder_protos/shreder_grpc.pb.go b/third_party/shreder_protos/shreder_grpc.pb.go new file mode 100644 index 0000000..033a1f4 --- /dev/null +++ b/third_party/shreder_protos/shreder_grpc.pb.go @@ -0,0 +1,156 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc v6.33.1 +// source: shreder.proto + +package shreder_protos + +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 ( + ShrederService_SubscribeEntries_FullMethodName = "/shredstream.ShrederService/SubscribeEntries" + ShrederService_SubscribeTransactions_FullMethodName = "/shredstream.ShrederService/SubscribeTransactions" +) + +// ShrederServiceClient is the client API for ShrederService 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 ShrederServiceClient interface { + SubscribeEntries(ctx context.Context, in *SubscribeEntriesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Entry], error) + SubscribeTransactions(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SubscribeTransactionsRequest, SubscribeTransactionsResponse], error) +} + +type shrederServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewShrederServiceClient(cc grpc.ClientConnInterface) ShrederServiceClient { + return &shrederServiceClient{cc} +} + +func (c *shrederServiceClient) SubscribeEntries(ctx context.Context, in *SubscribeEntriesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Entry], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ShrederService_ServiceDesc.Streams[0], ShrederService_SubscribeEntries_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[SubscribeEntriesRequest, Entry]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + 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 ShrederService_SubscribeEntriesClient = grpc.ServerStreamingClient[Entry] + +func (c *shrederServiceClient) SubscribeTransactions(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SubscribeTransactionsRequest, SubscribeTransactionsResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ShrederService_ServiceDesc.Streams[1], ShrederService_SubscribeTransactions_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[SubscribeTransactionsRequest, SubscribeTransactionsResponse]{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 ShrederService_SubscribeTransactionsClient = grpc.BidiStreamingClient[SubscribeTransactionsRequest, SubscribeTransactionsResponse] + +// ShrederServiceServer is the server API for ShrederService service. +// All implementations must embed UnimplementedShrederServiceServer +// for forward compatibility. +type ShrederServiceServer interface { + SubscribeEntries(*SubscribeEntriesRequest, grpc.ServerStreamingServer[Entry]) error + SubscribeTransactions(grpc.BidiStreamingServer[SubscribeTransactionsRequest, SubscribeTransactionsResponse]) error + mustEmbedUnimplementedShrederServiceServer() +} + +// UnimplementedShrederServiceServer 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 UnimplementedShrederServiceServer struct{} + +func (UnimplementedShrederServiceServer) SubscribeEntries(*SubscribeEntriesRequest, grpc.ServerStreamingServer[Entry]) error { + return status.Error(codes.Unimplemented, "method SubscribeEntries not implemented") +} +func (UnimplementedShrederServiceServer) SubscribeTransactions(grpc.BidiStreamingServer[SubscribeTransactionsRequest, SubscribeTransactionsResponse]) error { + return status.Error(codes.Unimplemented, "method SubscribeTransactions not implemented") +} +func (UnimplementedShrederServiceServer) mustEmbedUnimplementedShrederServiceServer() {} +func (UnimplementedShrederServiceServer) testEmbeddedByValue() {} + +// UnsafeShrederServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ShrederServiceServer will +// result in compilation errors. +type UnsafeShrederServiceServer interface { + mustEmbedUnimplementedShrederServiceServer() +} + +func RegisterShrederServiceServer(s grpc.ServiceRegistrar, srv ShrederServiceServer) { + // If the following call panics, it indicates UnimplementedShrederServiceServer 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(&ShrederService_ServiceDesc, srv) +} + +func _ShrederService_SubscribeEntries_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SubscribeEntriesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ShrederServiceServer).SubscribeEntries(m, &grpc.GenericServerStream[SubscribeEntriesRequest, Entry]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ShrederService_SubscribeEntriesServer = grpc.ServerStreamingServer[Entry] + +func _ShrederService_SubscribeTransactions_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ShrederServiceServer).SubscribeTransactions(&grpc.GenericServerStream[SubscribeTransactionsRequest, SubscribeTransactionsResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ShrederService_SubscribeTransactionsServer = grpc.BidiStreamingServer[SubscribeTransactionsRequest, SubscribeTransactionsResponse] + +// ShrederService_ServiceDesc is the grpc.ServiceDesc for ShrederService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ShrederService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "shredstream.ShrederService", + HandlerType: (*ShrederServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "SubscribeEntries", + Handler: _ShrederService_SubscribeEntries_Handler, + ServerStreams: true, + }, + { + StreamName: "SubscribeTransactions", + Handler: _ShrederService_SubscribeTransactions_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "shreder.proto", +}