diff --git a/packages/services/Makefile b/packages/services/Makefile index e21923e8d3..3f3167e188 100644 --- a/packages/services/Makefile +++ b/packages/services/Makefile @@ -15,18 +15,21 @@ protoc-go: protoc --go_out=. --go-grpc_out=. ./proto/ecs-stream.proto protoc --go_out=. --go-grpc_out=. ./proto/ecs-snapshot.proto protoc --go_out=. --go-grpc_out=. ./proto/ecs-relay.proto + protoc --go_out=. --go-grpc_out=. ./proto/faucet.proto .PHONY: protoc-go protoc-ts: mkdir -p ./protobuf/ts/ecs-stream mkdir -p ./protobuf/ts/ecs-snapshot mkdir -p ./protobuf/ts/ecs-relay + mkdir -p ./protobuf/ts/faucet npx protoc --ts_opt eslint_disable --ts_out ./protobuf/ts/ecs-stream --proto_path proto proto/ecs-stream.proto npx protoc --ts_opt eslint_disable --ts_out ./protobuf/ts/ecs-snapshot --proto_path proto proto/ecs-snapshot.proto npx protoc --ts_opt eslint_disable --ts_out ./protobuf/ts/ecs-relay --proto_path proto proto/ecs-relay.proto + npx protoc --ts_opt eslint_disable --ts_out ./protobuf/ts/faucet --proto_path proto proto/faucet.proto .PHONY: protoc-ts -build: ecs-stream ecs-snapshot ecs-relay +build: ecs-stream ecs-snapshot ecs-relay faucet .PHONY: build ecs-stream: @@ -41,6 +44,10 @@ ecs-relay: go build $(LDFLAGS) -o ./bin/ecs-relay ./cmd/ecs-relay .PHONY: ecs-relay +faucet: + go build $(LDFLAGS) -o ./bin/faucet ./cmd/faucet +.PHONY: faucet + run-ecs-stream: ./bin/ecs-stream -ws-url $(WS_URL) .PHONY: run-ecs-stream @@ -51,4 +58,8 @@ run-ecs-snapshot: run-ecs-relay: ./bin/ecs-relay -.PHONY: run-ecs-relay \ No newline at end of file +.PHONY: run-ecs-relay + +run-faucet: + ./bin/faucet --faucet-private-key ${FAUCET_PK} +.PHONY: run-faucet diff --git a/packages/services/cmd/faucet/main.go b/packages/services/cmd/faucet/main.go new file mode 100644 index 0000000000..bb9789e7c1 --- /dev/null +++ b/packages/services/cmd/faucet/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "crypto/ecdsa" + "flag" + "os" + "time" + + "latticexyz/mud/packages/services/pkg/eth" + "latticexyz/mud/packages/services/pkg/faucet" + "latticexyz/mud/packages/services/pkg/grpc" + "latticexyz/mud/packages/services/pkg/logger" + + "github.com/dghubble/go-twitter/twitter" + "github.com/ethereum/go-ethereum/crypto" + "go.uber.org/zap" + "golang.org/x/oauth2/clientcredentials" +) + +var ( + wsUrl = flag.String("ws-url", "ws://localhost:8545", "Websocket Url") + port = flag.Int("port", 50081, "gRPC Server Port") + faucetPrivateKey = flag.String("faucet-private-key", "0x", "Private key to use for faucet") + dripAmount = flag.Int64("drip-amount", 10000000000000000, "Drip amount in wei. Default to 0.01 ETH") + dripFrequency = flag.Float64("drip-frequency", 60, "Drip frequency per account in minutes. Default to 60 minutes") + dripLimit = flag.Uint64("drip-limit", 1000000000000000000, "Drip limit in wei per drip frequency interval. Default to 1 ETH") +) + +func main() { + // Parse command line flags. + flag.Parse() + + // Setup logging. + logger.InitLogger() + logger := logger.GetLogger() + defer logger.Sync() + + // Create a drip config. + dripConfig := &faucet.DripConfig{ + DripAmount: *dripAmount, + DripFrequency: *dripFrequency, + DripLimit: *dripLimit, + } + logger.Info("using a drip configuration", + zap.Int64("amount", dripConfig.DripAmount), + zap.Float64("frequency", dripConfig.DripFrequency), + zap.Uint64("limit", dripConfig.DripLimit), + ) + + // Ensure that a twitter <-> address store is setup. + faucet.SetupStore() + + // Oauth2 configures a client that uses app credentials to keep a fresh token. + config := &clientcredentials.Config{ + ClientID: os.Getenv("CLIENT_ID"), + ClientSecret: os.Getenv("CLIENT_SECRET"), + TokenURL: "https://api.twitter.com/oauth2/token", + } + + // Get a connection to Twitter API with a client. + twitterClient := twitter.NewClient(config.Client(context.Background())) + + // Get an instance of ethereum client. + ethClient := eth.GetEthereumClient(*wsUrl, logger) + + // Create a private key ECDSA object. + privateKey, err := crypto.HexToECDSA(*faucetPrivateKey) + if err != nil { + logger.Fatal("error creating ECDSA object from private key string", zap.String("privateKey", *faucetPrivateKey)) + } + + publicKey, ok := privateKey.Public().(*ecdsa.PublicKey) + if !ok { + logger.Fatal("error casting public key to ECDSA") + } + + // Kick off a worked that will reset the faucet limit at the specified interval. + // Note: the duration here matches whatever time units are used in 'drip-frequency'. + go faucet.ReplenishFaucetWorker(time.NewTicker(time.Duration(*dripFrequency)*time.Minute), make(chan struct{})) + + // Start the faucet gRPC server. + grpc.StartFaucetServer(*port, twitterClient, ethClient, privateKey, publicKey, dripConfig, logger) +} diff --git a/packages/services/go.mod b/packages/services/go.mod index 656a6bd543..0e24e08f14 100644 --- a/packages/services/go.mod +++ b/packages/services/go.mod @@ -6,9 +6,11 @@ replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism require ( github.com/avast/retry-go v3.0.0+incompatible + github.com/dghubble/go-twitter v0.0.0-20220816163853-8a0df96f1e6d github.com/ethereum/go-ethereum v1.10.21 github.com/improbable-eng/grpc-web v0.15.0 go.uber.org/zap v1.22.0 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d google.golang.org/grpc v1.48.0 google.golang.org/protobuf v1.28.1 ) @@ -16,14 +18,16 @@ require ( require ( github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dghubble/sling v1.4.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/golang-jwt/jwt/v4 v4.3.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/klauspost/compress v1.11.7 // indirect @@ -32,15 +36,14 @@ require ( github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/yuin/goldmark v1.4.13 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.12 // indirect + google.golang.org/appengine v1.4.0 // indirect google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect nhooyr.io/websocket v1.8.6 // indirect diff --git a/packages/services/go.sum b/packages/services/go.sum index 8472068f62..53b770c822 100644 --- a/packages/services/go.sum +++ b/packages/services/go.sum @@ -38,8 +38,9 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFA github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= @@ -71,6 +72,10 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dghubble/go-twitter v0.0.0-20220816163853-8a0df96f1e6d h1:qiUGPQxwkgoeDXtYaBEioXLEHffmBsRkM/9eum0vLS4= +github.com/dghubble/go-twitter v0.0.0-20220816163853-8a0df96f1e6d/go.mod h1:q7VYuSasPO79IE/QBNAMYVNlzZNy4Zr7vay6is50u5I= +github.com/dghubble/sling v1.4.0 h1:/n8MRosVTthvMbwlNZgLx579OGVjUOy3GNEv5BIqAWY= +github.com/dghubble/sling v1.4.0/go.mod h1:0r40aNsU9EdDUVBNhfCstAtFgutjgJGYbO1oNzkMoM8= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -158,9 +163,12 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -367,7 +375,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= @@ -385,8 +393,6 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -431,8 +437,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -454,12 +458,11 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -467,8 +470,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -499,8 +502,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -527,8 +528,6 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -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= @@ -537,6 +536,7 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3k google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/packages/services/pkg/faucet/constants.go b/packages/services/pkg/faucet/constants.go new file mode 100644 index 0000000000..964737b4ef --- /dev/null +++ b/packages/services/pkg/faucet/constants.go @@ -0,0 +1,5 @@ +package faucet + +const MatchingHashtag = "#mud" + +const FaucetStoreFilename = "./FaucetStore" diff --git a/packages/services/pkg/faucet/core.go b/packages/services/pkg/faucet/core.go new file mode 100644 index 0000000000..871e4fe3cc --- /dev/null +++ b/packages/services/pkg/faucet/core.go @@ -0,0 +1,257 @@ +package faucet + +import ( + "fmt" + "io/ioutil" + "latticexyz/mud/packages/services/pkg/logger" + "os" + "strings" + "time" + + "github.com/dghubble/go-twitter/twitter" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "go.uber.org/zap" + "google.golang.org/protobuf/proto" + + pb "latticexyz/mud/packages/services/protobuf/go/faucet" +) + +type DripConfig struct { + DripAmount int64 + DripFrequency float64 + DripLimit uint64 +} + +func TwitterUsernameQuery(username string) string { + return fmt.Sprintf("from:%s AND %s", username, MatchingHashtag) +} + +func VerifySig(from, sigHex string, msg []byte) (bool, string) { + sig := hexutil.MustDecode(sigHex) + + msg = accounts.TextHash(msg) + if sig[crypto.RecoveryIDOffset] == 27 || sig[crypto.RecoveryIDOffset] == 28 { + sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1 + } + + recovered, err := crypto.SigToPub(msg, sig) + if err != nil { + return false, "" + } + + recoveredAddr := crypto.PubkeyToAddress(*recovered) + + return from == recoveredAddr.Hex(), recoveredAddr.Hex() +} + +func ExtractSignatureFromTweet(tweet twitter.Tweet) string { + tokens := strings.Split(tweet.FullText, "faucet") + return strings.TrimSpace(tokens[1])[:132] +} + +func VerifyDripRequestTweet(tweet twitter.Tweet, username string, address string) error { + tweetSignature := ExtractSignatureFromTweet(tweet) + + isVerified, recoveredAddress := VerifySig( + address, + tweetSignature, + []byte(fmt.Sprintf("%s tweetooor requesting drip to %s address", username, address)), + ) + if !isVerified { + return fmt.Errorf("recovered address %s != provided address %s", recoveredAddress, address) + } + return nil +} + +func readStore(fileName string) []byte { + encoding, err := ioutil.ReadFile(fileName) + if err != nil { + logger.GetLogger().Fatal("failed to read encoded store", zap.String("fileName", fileName), zap.Error(err)) + } + return encoding +} + +func writeStore(encoding []byte, fileName string) { + if err := ioutil.WriteFile(fileName, encoding, 0644); err != nil { + logger.GetLogger().Fatal("failed to write FaucetStore", zap.String("fileName", fileName), zap.Error(err)) + } +} + +func decodeStore(encoding []byte) *pb.FaucetStore { + store := &pb.FaucetStore{} + if err := proto.Unmarshal(encoding, store); err != nil { + logger.GetLogger().Error("failed to decode FaucetStore", zap.Error(err)) + } + return store +} + +func encodeStore(store *pb.FaucetStore) []byte { + encoding, err := proto.Marshal(store) + if err != nil { + logger.GetLogger().Error("failed to encode FaucetStore", zap.Error(err)) + } + return encoding +} + +func GetStore() *pb.FaucetStore { + return decodeStore(readStore(FaucetStoreFilename)) +} + +func GetAddressForUsername(username string) string { + store := GetStore() + if address, ok := store.UsernameToAddress[username]; ok { + return address + } + return "" +} + +func GetUsernameForAddress(address string) string { + store := GetStore() + if username, ok := store.AddressToUsername[address]; ok { + return username + } + return "" +} + +func GetTimestampForDrip(address string) int64 { + store := GetStore() + if dripTimestamp, ok := store.LatestDrip[address]; ok { + return dripTimestamp + } + return 0 +} + +func GetTotalDripCount() uint64 { + store := GetStore() + return store.TotalDripCount +} + +func SetUsernameForAddress(username string, address string, store *pb.FaucetStore) { + if store.AddressToUsername == nil { + store.AddressToUsername = map[string]string{} + } + store.AddressToUsername[address] = username +} + +func SetAddressForUsername(address string, username string, store *pb.FaucetStore) { + if store.UsernameToAddress == nil { + store.UsernameToAddress = map[string]string{} + } + store.UsernameToAddress[username] = address +} + +func SetTimestampForDrip(address string, timestamp int64, store *pb.FaucetStore) { + if store.LatestDrip == nil { + store.LatestDrip = map[string]int64{} + } + store.LatestDrip[address] = timestamp +} + +func SetTotalDripCount(dripCount uint64, store *pb.FaucetStore) { + store.TotalDripCount = dripCount +} + +func LinkAddressAndUsername(address string, username string) { + // Get current store from file. + store := GetStore() + + // Update store to link. + SetUsernameForAddress(username, address, store) + SetAddressForUsername(address, username, store) + + // Write the updated store to file. + writeStore( + encodeStore(store), + FaucetStoreFilename, + ) + + logger.GetLogger().Info("linked username to address and updated store", + zap.String("username", username), + zap.String("address", address), + ) +} + +func UpdateDripRequestTimestamp(address string) { + // Get current store from file. + store := GetStore() + + // Update timestamp for address. + timestamp := time.Now().Unix() + SetTimestampForDrip(address, timestamp, store) + + // Write the updated store to file. + writeStore( + encodeStore(store), + FaucetStoreFilename, + ) + + logger.GetLogger().Info("updated drip request timestamp", + zap.String("address", address), + zap.Int64("timestamp", timestamp), + ) +} + +func IncrementTotalDripCount(dripConfig *DripConfig) { + // Get current store from file. + store := GetStore() + + // Update the total drip count to current count + drip amount. + SetTotalDripCount(store.TotalDripCount+uint64(dripConfig.DripAmount), store) + + // Write the updated store to file. + writeStore( + encodeStore(store), + FaucetStoreFilename, + ) + + logger.GetLogger().Info("incremented total drip amount by one drip increment", + zap.Uint64("current", store.TotalDripCount), + ) +} + +func ResetTotalDripCount() { + // Get current store from file. + store := GetStore() + + // Update the total drip count to zero. + SetTotalDripCount(0, store) + + // Write the updated store to file. + writeStore( + encodeStore(store), + FaucetStoreFilename, + ) + + logger.GetLogger().Info("reset total drip count to zero") +} + +func SetupStore() { + _, err := os.Stat(FaucetStoreFilename) + if err != nil { + // Write an empty store. + writeStore( + encodeStore(&pb.FaucetStore{ + AddressToUsername: map[string]string{}, + UsernameToAddress: map[string]string{}, + LatestDrip: map[string]int64{}, + TotalDripCount: 0, + }), + FaucetStoreFilename, + ) + } +} + +func ReplenishFaucetWorker(ticker *time.Ticker, quit chan struct{}) { + for { + select { + case <-ticker.C: + ResetTotalDripCount() + logger.GetLogger().Info("replenished faucet") + case <-quit: + ticker.Stop() + return + } + } +} diff --git a/packages/services/pkg/faucet/utils.go b/packages/services/pkg/faucet/utils.go new file mode 100644 index 0000000000..403d61175e --- /dev/null +++ b/packages/services/pkg/faucet/utils.go @@ -0,0 +1,11 @@ +package faucet + +import "time" + +func IsLinked(linked string, requested string) bool { + return linked != "" && linked != requested +} + +func TimeDiff(earlierTime time.Time, laterTime time.Time) time.Duration { + return laterTime.Sub(earlierTime) +} diff --git a/packages/services/pkg/grpc/faucet.go b/packages/services/pkg/grpc/faucet.go new file mode 100644 index 0000000000..bb9323f528 --- /dev/null +++ b/packages/services/pkg/grpc/faucet.go @@ -0,0 +1,204 @@ +package grpc + +import ( + "context" + "crypto/ecdsa" + "fmt" + "latticexyz/mud/packages/services/pkg/faucet" + pb "latticexyz/mud/packages/services/protobuf/go/faucet" + "math/big" + "time" + + "github.com/dghubble/go-twitter/twitter" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "go.uber.org/zap" +) + +type faucetServer struct { + pb.UnimplementedFaucetServiceServer + twitterClient *twitter.Client + ethClient *ethclient.Client + privateKey *ecdsa.PrivateKey + publicKey *ecdsa.PublicKey + dripConfig *faucet.DripConfig + logger *zap.Logger +} + +/// +/// gRPC ENDPOINTS +/// + +func (server *faucetServer) VerifyTweet(ctx context.Context, request *pb.VerifyTweetRequest) (*pb.VerifyTweetResponse, error) { + // Check if there are any funds left to drip per the current period (before they refresh). + totalDripCount := faucet.GetTotalDripCount() + if totalDripCount >= server.dripConfig.DripLimit { + return nil, fmt.Errorf("faucet limit exhausted, come back soon") + } + + if request.Username == "" { + return nil, fmt.Errorf("username required") + } + if request.Address == "" { + return nil, fmt.Errorf("address required") + } + + // Verify that this request has a valid address / username pairing. + // First verify that no other username is linked to address. + linkedUsername := faucet.GetUsernameForAddress(request.Address) + if faucet.IsLinked(linkedUsername, request.Username) { + return nil, fmt.Errorf("address %s is already connected to username @%s", request.Address, linkedUsername) + } + // Now verify that no other address is linked to username. + linkedAddress := faucet.GetAddressForUsername(request.Username) + if faucet.IsLinked(linkedAddress, request.Address) { + return nil, fmt.Errorf("username @%s is already connected to address %s", request.Username, linkedAddress) + } + + // Verify that the address / username pairing has not requested drip recently. + latestDrip := faucet.GetTimestampForDrip(request.Address) + timeDiffSinceDrip := faucet.TimeDiff(time.Unix(latestDrip, 0), time.Now()) + if latestDrip != 0 && timeDiffSinceDrip.Minutes() < server.dripConfig.DripFrequency { + return nil, fmt.Errorf("address %s received drip recently, come back in %.2f minutes", request.Address, (server.dripConfig.DripFrequency - timeDiffSinceDrip.Minutes())) + } + + query := faucet.TwitterUsernameQuery(request.Username) + search, resp, err := server.twitterClient.Search.Tweets(&twitter.SearchTweetParams{ + Query: query, + TweetMode: "extended", + }) + + if err != nil { + server.logger.Error("could not get tweets from account", zap.Error(err)) + return nil, fmt.Errorf("could not get tweets from account") + } + if resp.StatusCode != 200 { + server.logger.Error("response not 200-OK Twitter API", zap.String("status", resp.Status)) + return nil, fmt.Errorf("response not 200-OK from Twitter API") + } + + if len(search.Statuses) == 0 { + server.logger.Error("twitter search did not return any tweets matching query", zap.String("query", query)) + return nil, fmt.Errorf("did not find the tweet") + } + latestTweet := search.Statuses[0] + + // Verify the signature inside of the tweet. + err = faucet.VerifyDripRequestTweet(latestTweet, request.Username, request.Address) + if err != nil { + server.logger.Error("tweet drip request verification failed", zap.Error(err)) + return nil, err + } + server.logger.Info("tweet drip request verified successfully", + zap.String("username", request.Username), + zap.String("address", request.Address), + ) + + // Send a tx dripping the funds. + txHash, err := server.SendDripTransaction(request.Address) + if err != nil { + return nil, err + } + // Update the current total drip amount. + faucet.IncrementTotalDripCount(server.dripConfig) + + // Update the timestamp of the latest drip. + faucet.UpdateDripRequestTimestamp(request.Address) + + // Link the address and username, if not linked already. + if linkedAddress == "" && linkedUsername == "" { + faucet.LinkAddressAndUsername(request.Address, request.Username) + } + + return &pb.VerifyTweetResponse{ + TxHash: txHash, + }, nil +} + +func (server *faucetServer) SendDripTransaction(recipientAddress string) (string, error) { + fromAddress := crypto.PubkeyToAddress(*server.publicKey) + nonce, err := server.ethClient.PendingNonceAt(context.Background(), fromAddress) + if err != nil { + return "", err + } + + value := big.NewInt(server.dripConfig.DripAmount) + gasLimit := uint64(21000) + + gasPrice, err := server.ethClient.SuggestGasPrice(context.Background()) + if err != nil { + return "", err + } + + toAddress := common.HexToAddress(recipientAddress) + var data []byte + tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data) + + // Get the chain ID. + chainID, err := server.ethClient.NetworkID(context.Background()) + if err != nil { + return "", err + } + + // Sign the transaction. + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), server.privateKey) + if err != nil { + return "", err + } + + // Send the transaction. + err = server.ethClient.SendTransaction(context.Background(), signedTx) + if err != nil { + return "", err + } + + txHash := signedTx.Hash().Hex() + server.logger.Info("drip tx sent", zap.String("tx", txHash)) + + return txHash, nil +} + +func (server *faucetServer) GetLinkedTwitterForAddress(ctx context.Context, request *pb.LinkedTwitterForAddressRequest) (*pb.LinkedTwitterForAddressResponse, error) { + linkedUsername := faucet.GetUsernameForAddress(request.Address) + + server.logger.Info("getting linked username for address", + zap.String("address", request.Address), + zap.String("username", linkedUsername), + ) + + return &pb.LinkedTwitterForAddressResponse{ + Username: linkedUsername, + }, nil +} + +func (server *faucetServer) GetLinkedAddressForTwitter(ctx context.Context, request *pb.LinkedAddressForTwitterRequest) (*pb.LinkedAddressForTwitterResponse, error) { + linkedAddress := faucet.GetAddressForUsername(request.Username) + + server.logger.Info("getting linked address for username", + zap.String("username", request.Username), + zap.String("address", linkedAddress), + ) + return &pb.LinkedAddressForTwitterResponse{ + Address: linkedAddress, + }, nil +} + +func (server *faucetServer) GetLinkedTwitters(context.Context, *pb.GetLinkedTwittersRequest) (*pb.GetLinkedTwittersResponse, error) { + store := faucet.GetStore() + if store.UsernameToAddress == nil { + return nil, fmt.Errorf("no linked twitters yet") + } + + linkedTwitters := &pb.GetLinkedTwittersResponse{} + for username, address := range store.UsernameToAddress { + linkedTwitters.LinkedTwitters = append(linkedTwitters.LinkedTwitters, &pb.LinkedTwitterPair{ + Username: username, + Address: address, + }) + } + server.logger.Info("returning linked twitters", zap.Int("count", len(linkedTwitters.LinkedTwitters))) + + return linkedTwitters, nil +} diff --git a/packages/services/pkg/grpc/server.go b/packages/services/pkg/grpc/server.go index 9538afbb5b..f8dfbb1e94 100644 --- a/packages/services/pkg/grpc/server.go +++ b/packages/services/pkg/grpc/server.go @@ -1,15 +1,19 @@ package grpc import ( + "crypto/ecdsa" "fmt" + "latticexyz/mud/packages/services/pkg/faucet" multiplexer "latticexyz/mud/packages/services/pkg/multiplexer" "latticexyz/mud/packages/services/pkg/relay" pb_relay "latticexyz/mud/packages/services/protobuf/go/ecs-relay" pb_snapshot "latticexyz/mud/packages/services/protobuf/go/ecs-snapshot" pb_stream "latticexyz/mud/packages/services/protobuf/go/ecs-stream" + pb_faucet "latticexyz/mud/packages/services/protobuf/go/faucet" "net" "net/http" + "github.com/dghubble/go-twitter/twitter" "github.com/ethereum/go-ethereum/ethclient" "github.com/improbable-eng/grpc-web/go/grpcweb" "go.uber.org/zap" @@ -131,6 +135,48 @@ func StartRelayServer(port int, config *relay.RelayServerConfig, logger *zap.Log startHTTPServer(httpServer, logger) } +func StartFaucetServer( + port int, + twitterClient *twitter.Client, + ethClient *ethclient.Client, + privateKey *ecdsa.PrivateKey, + publicKey *ecdsa.PublicKey, + dripConfig *faucet.DripConfig, + logger *zap.Logger, +) { + var options []grpc.ServerOption + grpcServer := grpc.NewServer(options...) + + pb_faucet.RegisterFaucetServiceServer(grpcServer, createFaucetServer(twitterClient, ethClient, privateKey, publicKey, dripConfig, logger)) + + // Register reflection service on gRPC server. + reflection.Register(grpcServer) + + // Start the RPC server at PORT. + listener, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) + if err != nil { + logger.Fatal("failed to listen", zap.String("category", "gRPC server"), zap.Error(err)) + } + go startRPCServer(grpcServer, listener, logger) + logger.Info("started listening", zap.String("category", "gRPC server"), zap.String("address", listener.Addr().String())) + + // Wrap gRPC server into a gRPC-web HTTP server. + grpcWebServer := grpcweb.WrapServer( + grpcServer, + // Enable CORS. + grpcweb.WithCorsForRegisteredEndpointsOnly(false), + grpcweb.WithOriginFunc(func(origin string) bool { return true }), + ) + // Create and start the HTTP server at PORT+1. + httpServer := &http.Server{ + Handler: grpcWebServer, + Addr: fmt.Sprintf("0.0.0.0:%d", port+1), + } + + logger.Info("started listening", zap.String("category", "http server"), zap.String("address", httpServer.Addr)) + startHTTPServer(httpServer, logger) +} + func createStreamServer(ethclient *ethclient.Client, multiplexer *multiplexer.Multiplexer, logger *zap.Logger) *ecsStreamServer { return &ecsStreamServer{ ethclient: ethclient, @@ -151,3 +197,21 @@ func createRelayServer(logger *zap.Logger, config *relay.RelayServerConfig) *ecs server.Init() return server } + +func createFaucetServer( + twitterClient *twitter.Client, + ethClient *ethclient.Client, + privateKey *ecdsa.PrivateKey, + publicKey *ecdsa.PublicKey, + dripConfig *faucet.DripConfig, + logger *zap.Logger, +) *faucetServer { + return &faucetServer{ + twitterClient: twitterClient, + ethClient: ethClient, + privateKey: privateKey, + publicKey: publicKey, + dripConfig: dripConfig, + logger: logger, + } +} diff --git a/packages/services/proto/faucet.proto b/packages/services/proto/faucet.proto new file mode 100644 index 0000000000..848e29477b --- /dev/null +++ b/packages/services/proto/faucet.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; +package faucet; + +option go_package = "protobuf/go/faucet"; + +message LinkedTwitterPair { + string username = 1; + string address = 2; +} + +message FaucetStore { + map addressToUsername = 1; + map usernameToAddress = 2; + + // Username to timestamp of latest drip. + map latestDrip = 3; + + // Global drip counter. + uint64 totalDripCount = 4; +} + +// The Faucet Service definition. +service FaucetService { + rpc VerifyTweet (VerifyTweetRequest) returns (VerifyTweetResponse) {} + + rpc GetLinkedTwitters (GetLinkedTwittersRequest) returns (GetLinkedTwittersResponse) {} + rpc GetLinkedTwitterForAddress (LinkedTwitterForAddressRequest) returns (LinkedTwitterForAddressResponse) {} + rpc GetLinkedAddressForTwitter (LinkedAddressForTwitterRequest) returns (LinkedAddressForTwitterResponse) {} +} + +message VerifyTweetRequest { + string username = 1; + string address = 2; +} + +message VerifyTweetResponse { + string txHash = 1; +} + +message GetLinkedTwittersRequest {} + +message GetLinkedTwittersResponse { + repeated LinkedTwitterPair linkedTwitters = 1; +} + +message LinkedTwitterForAddressRequest { + string address = 1; +} + +message LinkedTwitterForAddressResponse { + string username = 1; +} + +message LinkedAddressForTwitterRequest { + string username = 1; +} + +message LinkedAddressForTwitterResponse { + string address = 1; +} diff --git a/packages/services/protobuf/go/faucet/faucet.pb.go b/packages/services/protobuf/go/faucet/faucet.pb.go new file mode 100644 index 0000000000..7cd7cc5920 --- /dev/null +++ b/packages/services/protobuf/go/faucet/faucet.pb.go @@ -0,0 +1,821 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.3 +// source: proto/faucet.proto + +package faucet + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 LinkedTwitterPair struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *LinkedTwitterPair) Reset() { + *x = LinkedTwitterPair{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkedTwitterPair) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkedTwitterPair) ProtoMessage() {} + +func (x *LinkedTwitterPair) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkedTwitterPair.ProtoReflect.Descriptor instead. +func (*LinkedTwitterPair) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{0} +} + +func (x *LinkedTwitterPair) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *LinkedTwitterPair) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type FaucetStore struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressToUsername map[string]string `protobuf:"bytes,1,rep,name=addressToUsername,proto3" json:"addressToUsername,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + UsernameToAddress map[string]string `protobuf:"bytes,2,rep,name=usernameToAddress,proto3" json:"usernameToAddress,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Username to timestamp of latest drip. + LatestDrip map[string]int64 `protobuf:"bytes,3,rep,name=latestDrip,proto3" json:"latestDrip,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + // Global drip counter. + TotalDripCount uint64 `protobuf:"varint,4,opt,name=totalDripCount,proto3" json:"totalDripCount,omitempty"` +} + +func (x *FaucetStore) Reset() { + *x = FaucetStore{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FaucetStore) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FaucetStore) ProtoMessage() {} + +func (x *FaucetStore) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FaucetStore.ProtoReflect.Descriptor instead. +func (*FaucetStore) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{1} +} + +func (x *FaucetStore) GetAddressToUsername() map[string]string { + if x != nil { + return x.AddressToUsername + } + return nil +} + +func (x *FaucetStore) GetUsernameToAddress() map[string]string { + if x != nil { + return x.UsernameToAddress + } + return nil +} + +func (x *FaucetStore) GetLatestDrip() map[string]int64 { + if x != nil { + return x.LatestDrip + } + return nil +} + +func (x *FaucetStore) GetTotalDripCount() uint64 { + if x != nil { + return x.TotalDripCount + } + return 0 +} + +type VerifyTweetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *VerifyTweetRequest) Reset() { + *x = VerifyTweetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyTweetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyTweetRequest) ProtoMessage() {} + +func (x *VerifyTweetRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyTweetRequest.ProtoReflect.Descriptor instead. +func (*VerifyTweetRequest) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{2} +} + +func (x *VerifyTweetRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *VerifyTweetRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type VerifyTweetResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TxHash string `protobuf:"bytes,1,opt,name=txHash,proto3" json:"txHash,omitempty"` +} + +func (x *VerifyTweetResponse) Reset() { + *x = VerifyTweetResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyTweetResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyTweetResponse) ProtoMessage() {} + +func (x *VerifyTweetResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyTweetResponse.ProtoReflect.Descriptor instead. +func (*VerifyTweetResponse) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{3} +} + +func (x *VerifyTweetResponse) GetTxHash() string { + if x != nil { + return x.TxHash + } + return "" +} + +type GetLinkedTwittersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetLinkedTwittersRequest) Reset() { + *x = GetLinkedTwittersRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLinkedTwittersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLinkedTwittersRequest) ProtoMessage() {} + +func (x *GetLinkedTwittersRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLinkedTwittersRequest.ProtoReflect.Descriptor instead. +func (*GetLinkedTwittersRequest) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{4} +} + +type GetLinkedTwittersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LinkedTwitters []*LinkedTwitterPair `protobuf:"bytes,1,rep,name=linkedTwitters,proto3" json:"linkedTwitters,omitempty"` +} + +func (x *GetLinkedTwittersResponse) Reset() { + *x = GetLinkedTwittersResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLinkedTwittersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLinkedTwittersResponse) ProtoMessage() {} + +func (x *GetLinkedTwittersResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLinkedTwittersResponse.ProtoReflect.Descriptor instead. +func (*GetLinkedTwittersResponse) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{5} +} + +func (x *GetLinkedTwittersResponse) GetLinkedTwitters() []*LinkedTwitterPair { + if x != nil { + return x.LinkedTwitters + } + return nil +} + +type LinkedTwitterForAddressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *LinkedTwitterForAddressRequest) Reset() { + *x = LinkedTwitterForAddressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkedTwitterForAddressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkedTwitterForAddressRequest) ProtoMessage() {} + +func (x *LinkedTwitterForAddressRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkedTwitterForAddressRequest.ProtoReflect.Descriptor instead. +func (*LinkedTwitterForAddressRequest) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{6} +} + +func (x *LinkedTwitterForAddressRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type LinkedTwitterForAddressResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *LinkedTwitterForAddressResponse) Reset() { + *x = LinkedTwitterForAddressResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkedTwitterForAddressResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkedTwitterForAddressResponse) ProtoMessage() {} + +func (x *LinkedTwitterForAddressResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkedTwitterForAddressResponse.ProtoReflect.Descriptor instead. +func (*LinkedTwitterForAddressResponse) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{7} +} + +func (x *LinkedTwitterForAddressResponse) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +type LinkedAddressForTwitterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *LinkedAddressForTwitterRequest) Reset() { + *x = LinkedAddressForTwitterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkedAddressForTwitterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkedAddressForTwitterRequest) ProtoMessage() {} + +func (x *LinkedAddressForTwitterRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkedAddressForTwitterRequest.ProtoReflect.Descriptor instead. +func (*LinkedAddressForTwitterRequest) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{8} +} + +func (x *LinkedAddressForTwitterRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +type LinkedAddressForTwitterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *LinkedAddressForTwitterResponse) Reset() { + *x = LinkedAddressForTwitterResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_faucet_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkedAddressForTwitterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkedAddressForTwitterResponse) ProtoMessage() {} + +func (x *LinkedAddressForTwitterResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_faucet_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkedAddressForTwitterResponse.ProtoReflect.Descriptor instead. +func (*LinkedAddressForTwitterResponse) Descriptor() ([]byte, []int) { + return file_proto_faucet_proto_rawDescGZIP(), []int{9} +} + +func (x *LinkedAddressForTwitterResponse) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +var File_proto_faucet_proto protoreflect.FileDescriptor + +var file_proto_faucet_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x22, 0x49, 0x0a, 0x11, + 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x50, 0x61, 0x69, + 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xf9, 0x03, 0x0a, 0x0b, 0x46, 0x61, 0x75, 0x63, + 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x46, 0x61, 0x75, 0x63, + 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, + 0x6f, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x58, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x6f, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x66, + 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x44, 0x72, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x44, 0x72, 0x69, 0x70, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x44, 0x72, 0x69, 0x70, + 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x72, 0x69, 0x70, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, + 0x72, 0x69, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x44, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, + 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x44, 0x72, + 0x69, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x54, 0x77, 0x65, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, + 0x2d, 0x0a, 0x13, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x54, 0x77, 0x65, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x1a, + 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x19, 0x47, 0x65, + 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x6c, 0x69, 0x6e, 0x6b, 0x65, + 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, + 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x50, 0x61, 0x69, 0x72, 0x52, 0x0e, 0x6c, 0x69, 0x6e, 0x6b, + 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x0a, 0x1e, 0x4c, 0x69, + 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x3d, 0x0a, 0x1f, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, + 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x1e, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x1f, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x32, 0x97, 0x03, 0x0a, 0x0d, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x54, 0x77, 0x65, 0x65, + 0x74, 0x12, 0x1a, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x54, 0x77, 0x65, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, + 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x54, 0x77, 0x65, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x20, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, + 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x47, 0x65, 0x74, + 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4c, + 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x26, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, + 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x6f, 0x72, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x54, 0x77, + 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x1a, 0x47, 0x65, 0x74, + 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x6f, 0x72, + 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, + 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x6f, + 0x72, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x27, 0x2e, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x14, 0x5a, 0x12, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_faucet_proto_rawDescOnce sync.Once + file_proto_faucet_proto_rawDescData = file_proto_faucet_proto_rawDesc +) + +func file_proto_faucet_proto_rawDescGZIP() []byte { + file_proto_faucet_proto_rawDescOnce.Do(func() { + file_proto_faucet_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_faucet_proto_rawDescData) + }) + return file_proto_faucet_proto_rawDescData +} + +var file_proto_faucet_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_proto_faucet_proto_goTypes = []interface{}{ + (*LinkedTwitterPair)(nil), // 0: faucet.LinkedTwitterPair + (*FaucetStore)(nil), // 1: faucet.FaucetStore + (*VerifyTweetRequest)(nil), // 2: faucet.VerifyTweetRequest + (*VerifyTweetResponse)(nil), // 3: faucet.VerifyTweetResponse + (*GetLinkedTwittersRequest)(nil), // 4: faucet.GetLinkedTwittersRequest + (*GetLinkedTwittersResponse)(nil), // 5: faucet.GetLinkedTwittersResponse + (*LinkedTwitterForAddressRequest)(nil), // 6: faucet.LinkedTwitterForAddressRequest + (*LinkedTwitterForAddressResponse)(nil), // 7: faucet.LinkedTwitterForAddressResponse + (*LinkedAddressForTwitterRequest)(nil), // 8: faucet.LinkedAddressForTwitterRequest + (*LinkedAddressForTwitterResponse)(nil), // 9: faucet.LinkedAddressForTwitterResponse + nil, // 10: faucet.FaucetStore.AddressToUsernameEntry + nil, // 11: faucet.FaucetStore.UsernameToAddressEntry + nil, // 12: faucet.FaucetStore.LatestDripEntry +} +var file_proto_faucet_proto_depIdxs = []int32{ + 10, // 0: faucet.FaucetStore.addressToUsername:type_name -> faucet.FaucetStore.AddressToUsernameEntry + 11, // 1: faucet.FaucetStore.usernameToAddress:type_name -> faucet.FaucetStore.UsernameToAddressEntry + 12, // 2: faucet.FaucetStore.latestDrip:type_name -> faucet.FaucetStore.LatestDripEntry + 0, // 3: faucet.GetLinkedTwittersResponse.linkedTwitters:type_name -> faucet.LinkedTwitterPair + 2, // 4: faucet.FaucetService.VerifyTweet:input_type -> faucet.VerifyTweetRequest + 4, // 5: faucet.FaucetService.GetLinkedTwitters:input_type -> faucet.GetLinkedTwittersRequest + 6, // 6: faucet.FaucetService.GetLinkedTwitterForAddress:input_type -> faucet.LinkedTwitterForAddressRequest + 8, // 7: faucet.FaucetService.GetLinkedAddressForTwitter:input_type -> faucet.LinkedAddressForTwitterRequest + 3, // 8: faucet.FaucetService.VerifyTweet:output_type -> faucet.VerifyTweetResponse + 5, // 9: faucet.FaucetService.GetLinkedTwitters:output_type -> faucet.GetLinkedTwittersResponse + 7, // 10: faucet.FaucetService.GetLinkedTwitterForAddress:output_type -> faucet.LinkedTwitterForAddressResponse + 9, // 11: faucet.FaucetService.GetLinkedAddressForTwitter:output_type -> faucet.LinkedAddressForTwitterResponse + 8, // [8:12] is the sub-list for method output_type + 4, // [4:8] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_proto_faucet_proto_init() } +func file_proto_faucet_proto_init() { + if File_proto_faucet_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_faucet_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkedTwitterPair); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FaucetStore); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyTweetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyTweetResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLinkedTwittersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLinkedTwittersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkedTwitterForAddressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkedTwitterForAddressResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkedAddressForTwitterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_faucet_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkedAddressForTwitterResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_faucet_proto_rawDesc, + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_faucet_proto_goTypes, + DependencyIndexes: file_proto_faucet_proto_depIdxs, + MessageInfos: file_proto_faucet_proto_msgTypes, + }.Build() + File_proto_faucet_proto = out.File + file_proto_faucet_proto_rawDesc = nil + file_proto_faucet_proto_goTypes = nil + file_proto_faucet_proto_depIdxs = nil +} diff --git a/packages/services/protobuf/go/faucet/faucet_grpc.pb.go b/packages/services/protobuf/go/faucet/faucet_grpc.pb.go new file mode 100644 index 0000000000..16b73044e5 --- /dev/null +++ b/packages/services/protobuf/go/faucet/faucet_grpc.pb.go @@ -0,0 +1,213 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.3 +// source: proto/faucet.proto + +package faucet + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// FaucetServiceClient is the client API for FaucetService 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 FaucetServiceClient interface { + VerifyTweet(ctx context.Context, in *VerifyTweetRequest, opts ...grpc.CallOption) (*VerifyTweetResponse, error) + GetLinkedTwitters(ctx context.Context, in *GetLinkedTwittersRequest, opts ...grpc.CallOption) (*GetLinkedTwittersResponse, error) + GetLinkedTwitterForAddress(ctx context.Context, in *LinkedTwitterForAddressRequest, opts ...grpc.CallOption) (*LinkedTwitterForAddressResponse, error) + GetLinkedAddressForTwitter(ctx context.Context, in *LinkedAddressForTwitterRequest, opts ...grpc.CallOption) (*LinkedAddressForTwitterResponse, error) +} + +type faucetServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewFaucetServiceClient(cc grpc.ClientConnInterface) FaucetServiceClient { + return &faucetServiceClient{cc} +} + +func (c *faucetServiceClient) VerifyTweet(ctx context.Context, in *VerifyTweetRequest, opts ...grpc.CallOption) (*VerifyTweetResponse, error) { + out := new(VerifyTweetResponse) + err := c.cc.Invoke(ctx, "/faucet.FaucetService/VerifyTweet", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *faucetServiceClient) GetLinkedTwitters(ctx context.Context, in *GetLinkedTwittersRequest, opts ...grpc.CallOption) (*GetLinkedTwittersResponse, error) { + out := new(GetLinkedTwittersResponse) + err := c.cc.Invoke(ctx, "/faucet.FaucetService/GetLinkedTwitters", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *faucetServiceClient) GetLinkedTwitterForAddress(ctx context.Context, in *LinkedTwitterForAddressRequest, opts ...grpc.CallOption) (*LinkedTwitterForAddressResponse, error) { + out := new(LinkedTwitterForAddressResponse) + err := c.cc.Invoke(ctx, "/faucet.FaucetService/GetLinkedTwitterForAddress", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *faucetServiceClient) GetLinkedAddressForTwitter(ctx context.Context, in *LinkedAddressForTwitterRequest, opts ...grpc.CallOption) (*LinkedAddressForTwitterResponse, error) { + out := new(LinkedAddressForTwitterResponse) + err := c.cc.Invoke(ctx, "/faucet.FaucetService/GetLinkedAddressForTwitter", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// FaucetServiceServer is the server API for FaucetService service. +// All implementations must embed UnimplementedFaucetServiceServer +// for forward compatibility +type FaucetServiceServer interface { + VerifyTweet(context.Context, *VerifyTweetRequest) (*VerifyTweetResponse, error) + GetLinkedTwitters(context.Context, *GetLinkedTwittersRequest) (*GetLinkedTwittersResponse, error) + GetLinkedTwitterForAddress(context.Context, *LinkedTwitterForAddressRequest) (*LinkedTwitterForAddressResponse, error) + GetLinkedAddressForTwitter(context.Context, *LinkedAddressForTwitterRequest) (*LinkedAddressForTwitterResponse, error) + mustEmbedUnimplementedFaucetServiceServer() +} + +// UnimplementedFaucetServiceServer must be embedded to have forward compatible implementations. +type UnimplementedFaucetServiceServer struct { +} + +func (UnimplementedFaucetServiceServer) VerifyTweet(context.Context, *VerifyTweetRequest) (*VerifyTweetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VerifyTweet not implemented") +} +func (UnimplementedFaucetServiceServer) GetLinkedTwitters(context.Context, *GetLinkedTwittersRequest) (*GetLinkedTwittersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLinkedTwitters not implemented") +} +func (UnimplementedFaucetServiceServer) GetLinkedTwitterForAddress(context.Context, *LinkedTwitterForAddressRequest) (*LinkedTwitterForAddressResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLinkedTwitterForAddress not implemented") +} +func (UnimplementedFaucetServiceServer) GetLinkedAddressForTwitter(context.Context, *LinkedAddressForTwitterRequest) (*LinkedAddressForTwitterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLinkedAddressForTwitter not implemented") +} +func (UnimplementedFaucetServiceServer) mustEmbedUnimplementedFaucetServiceServer() {} + +// UnsafeFaucetServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to FaucetServiceServer will +// result in compilation errors. +type UnsafeFaucetServiceServer interface { + mustEmbedUnimplementedFaucetServiceServer() +} + +func RegisterFaucetServiceServer(s grpc.ServiceRegistrar, srv FaucetServiceServer) { + s.RegisterService(&FaucetService_ServiceDesc, srv) +} + +func _FaucetService_VerifyTweet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyTweetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FaucetServiceServer).VerifyTweet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/faucet.FaucetService/VerifyTweet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FaucetServiceServer).VerifyTweet(ctx, req.(*VerifyTweetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FaucetService_GetLinkedTwitters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLinkedTwittersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FaucetServiceServer).GetLinkedTwitters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/faucet.FaucetService/GetLinkedTwitters", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FaucetServiceServer).GetLinkedTwitters(ctx, req.(*GetLinkedTwittersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FaucetService_GetLinkedTwitterForAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LinkedTwitterForAddressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FaucetServiceServer).GetLinkedTwitterForAddress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/faucet.FaucetService/GetLinkedTwitterForAddress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FaucetServiceServer).GetLinkedTwitterForAddress(ctx, req.(*LinkedTwitterForAddressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FaucetService_GetLinkedAddressForTwitter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LinkedAddressForTwitterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FaucetServiceServer).GetLinkedAddressForTwitter(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/faucet.FaucetService/GetLinkedAddressForTwitter", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FaucetServiceServer).GetLinkedAddressForTwitter(ctx, req.(*LinkedAddressForTwitterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// FaucetService_ServiceDesc is the grpc.ServiceDesc for FaucetService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var FaucetService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "faucet.FaucetService", + HandlerType: (*FaucetServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "VerifyTweet", + Handler: _FaucetService_VerifyTweet_Handler, + }, + { + MethodName: "GetLinkedTwitters", + Handler: _FaucetService_GetLinkedTwitters_Handler, + }, + { + MethodName: "GetLinkedTwitterForAddress", + Handler: _FaucetService_GetLinkedTwitterForAddress_Handler, + }, + { + MethodName: "GetLinkedAddressForTwitter", + Handler: _FaucetService_GetLinkedAddressForTwitter_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/faucet.proto", +} diff --git a/packages/services/protobuf/ts/faucet/faucet.client.ts b/packages/services/protobuf/ts/faucet/faucet.client.ts new file mode 100644 index 0000000000..a0f2ed0549 --- /dev/null +++ b/packages/services/protobuf/ts/faucet/faucet.client.ts @@ -0,0 +1,120 @@ +/* eslint-disable */ +// @generated by protobuf-ts 2.8.1 with parameter eslint_disable +// @generated from protobuf file "faucet.proto" (package "faucet", syntax proto3) +// tslint:disable +import type { RpcTransport } from "@protobuf-ts/runtime-rpc"; +import type { ServiceInfo } from "@protobuf-ts/runtime-rpc"; +import { FaucetService } from "./faucet"; +import type { LinkedAddressForTwitterResponse } from "./faucet"; +import type { LinkedAddressForTwitterRequest } from "./faucet"; +import type { LinkedTwitterForAddressResponse } from "./faucet"; +import type { LinkedTwitterForAddressRequest } from "./faucet"; +import type { GetLinkedTwittersResponse } from "./faucet"; +import type { GetLinkedTwittersRequest } from "./faucet"; +import { stackIntercept } from "@protobuf-ts/runtime-rpc"; +import type { VerifyTweetResponse } from "./faucet"; +import type { VerifyTweetRequest } from "./faucet"; +import type { UnaryCall } from "@protobuf-ts/runtime-rpc"; +import type { RpcOptions } from "@protobuf-ts/runtime-rpc"; +/** + * The Faucet Service definition. + * + * @generated from protobuf service faucet.FaucetService + */ +export interface IFaucetServiceClient { + /** + * @generated from protobuf rpc: VerifyTweet(faucet.VerifyTweetRequest) returns (faucet.VerifyTweetResponse); + */ + verifyTweet(input: VerifyTweetRequest, options?: RpcOptions): UnaryCall; + /** + * @generated from protobuf rpc: GetLinkedTwitters(faucet.GetLinkedTwittersRequest) returns (faucet.GetLinkedTwittersResponse); + */ + getLinkedTwitters( + input: GetLinkedTwittersRequest, + options?: RpcOptions + ): UnaryCall; + /** + * @generated from protobuf rpc: GetLinkedTwitterForAddress(faucet.LinkedTwitterForAddressRequest) returns (faucet.LinkedTwitterForAddressResponse); + */ + getLinkedTwitterForAddress( + input: LinkedTwitterForAddressRequest, + options?: RpcOptions + ): UnaryCall; + /** + * @generated from protobuf rpc: GetLinkedAddressForTwitter(faucet.LinkedAddressForTwitterRequest) returns (faucet.LinkedAddressForTwitterResponse); + */ + getLinkedAddressForTwitter( + input: LinkedAddressForTwitterRequest, + options?: RpcOptions + ): UnaryCall; +} +/** + * The Faucet Service definition. + * + * @generated from protobuf service faucet.FaucetService + */ +export class FaucetServiceClient implements IFaucetServiceClient, ServiceInfo { + typeName = FaucetService.typeName; + methods = FaucetService.methods; + options = FaucetService.options; + constructor(private readonly _transport: RpcTransport) {} + /** + * @generated from protobuf rpc: VerifyTweet(faucet.VerifyTweetRequest) returns (faucet.VerifyTweetResponse); + */ + verifyTweet(input: VerifyTweetRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[0], + opt = this._transport.mergeOptions(options); + return stackIntercept("unary", this._transport, method, opt, input); + } + /** + * @generated from protobuf rpc: GetLinkedTwitters(faucet.GetLinkedTwittersRequest) returns (faucet.GetLinkedTwittersResponse); + */ + getLinkedTwitters( + input: GetLinkedTwittersRequest, + options?: RpcOptions + ): UnaryCall { + const method = this.methods[1], + opt = this._transport.mergeOptions(options); + return stackIntercept( + "unary", + this._transport, + method, + opt, + input + ); + } + /** + * @generated from protobuf rpc: GetLinkedTwitterForAddress(faucet.LinkedTwitterForAddressRequest) returns (faucet.LinkedTwitterForAddressResponse); + */ + getLinkedTwitterForAddress( + input: LinkedTwitterForAddressRequest, + options?: RpcOptions + ): UnaryCall { + const method = this.methods[2], + opt = this._transport.mergeOptions(options); + return stackIntercept( + "unary", + this._transport, + method, + opt, + input + ); + } + /** + * @generated from protobuf rpc: GetLinkedAddressForTwitter(faucet.LinkedAddressForTwitterRequest) returns (faucet.LinkedAddressForTwitterResponse); + */ + getLinkedAddressForTwitter( + input: LinkedAddressForTwitterRequest, + options?: RpcOptions + ): UnaryCall { + const method = this.methods[3], + opt = this._transport.mergeOptions(options); + return stackIntercept( + "unary", + this._transport, + method, + opt, + input + ); + } +} diff --git a/packages/services/protobuf/ts/faucet/faucet.ts b/packages/services/protobuf/ts/faucet/faucet.ts new file mode 100644 index 0000000000..280b6fff71 --- /dev/null +++ b/packages/services/protobuf/ts/faucet/faucet.ts @@ -0,0 +1,786 @@ +/* eslint-disable */ +// @generated by protobuf-ts 2.8.1 with parameter eslint_disable +// @generated from protobuf file "faucet.proto" (package "faucet", syntax proto3) +// tslint:disable +import { ServiceType } from "@protobuf-ts/runtime-rpc"; +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { MESSAGE_TYPE } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +/** + * @generated from protobuf message faucet.LinkedTwitterPair + */ +export interface LinkedTwitterPair { + /** + * @generated from protobuf field: string username = 1; + */ + username: string; + /** + * @generated from protobuf field: string address = 2; + */ + address: string; +} +/** + * @generated from protobuf message faucet.FaucetStore + */ +export interface FaucetStore { + /** + * @generated from protobuf field: map addressToUsername = 1; + */ + addressToUsername: { + [key: string]: string; + }; + /** + * @generated from protobuf field: map usernameToAddress = 2; + */ + usernameToAddress: { + [key: string]: string; + }; + /** + * Username to timestamp of latest drip. + * + * @generated from protobuf field: map latestDrip = 3; + */ + latestDrip: { + [key: string]: bigint; + }; + /** + * Global drip counter. + * + * @generated from protobuf field: uint64 totalDripCount = 4; + */ + totalDripCount: bigint; +} +/** + * @generated from protobuf message faucet.VerifyTweetRequest + */ +export interface VerifyTweetRequest { + /** + * @generated from protobuf field: string username = 1; + */ + username: string; + /** + * @generated from protobuf field: string address = 2; + */ + address: string; +} +/** + * @generated from protobuf message faucet.VerifyTweetResponse + */ +export interface VerifyTweetResponse { + /** + * @generated from protobuf field: string txHash = 1; + */ + txHash: string; +} +/** + * @generated from protobuf message faucet.GetLinkedTwittersRequest + */ +export interface GetLinkedTwittersRequest {} +/** + * @generated from protobuf message faucet.GetLinkedTwittersResponse + */ +export interface GetLinkedTwittersResponse { + /** + * @generated from protobuf field: repeated faucet.LinkedTwitterPair linkedTwitters = 1; + */ + linkedTwitters: LinkedTwitterPair[]; +} +/** + * @generated from protobuf message faucet.LinkedTwitterForAddressRequest + */ +export interface LinkedTwitterForAddressRequest { + /** + * @generated from protobuf field: string address = 1; + */ + address: string; +} +/** + * @generated from protobuf message faucet.LinkedTwitterForAddressResponse + */ +export interface LinkedTwitterForAddressResponse { + /** + * @generated from protobuf field: string username = 1; + */ + username: string; +} +/** + * @generated from protobuf message faucet.LinkedAddressForTwitterRequest + */ +export interface LinkedAddressForTwitterRequest { + /** + * @generated from protobuf field: string username = 1; + */ + username: string; +} +/** + * @generated from protobuf message faucet.LinkedAddressForTwitterResponse + */ +export interface LinkedAddressForTwitterResponse { + /** + * @generated from protobuf field: string address = 1; + */ + address: string; +} +// @generated message type with reflection information, may provide speed optimized methods +class LinkedTwitterPair$Type extends MessageType { + constructor() { + super("faucet.LinkedTwitterPair", [ + { no: 1, name: "username", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "address", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): LinkedTwitterPair { + const message = { username: "", address: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: LinkedTwitterPair + ): LinkedTwitterPair { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string username */ 1: + message.username = reader.string(); + break; + case /* string address */ 2: + message.address = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LinkedTwitterPair, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string username = 1; */ + if (message.username !== "") writer.tag(1, WireType.LengthDelimited).string(message.username); + /* string address = 2; */ + if (message.address !== "") writer.tag(2, WireType.LengthDelimited).string(message.address); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.LinkedTwitterPair + */ +export const LinkedTwitterPair = new LinkedTwitterPair$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class FaucetStore$Type extends MessageType { + constructor() { + super("faucet.FaucetStore", [ + { + no: 1, + name: "addressToUsername", + kind: "map", + K: 9 /*ScalarType.STRING*/, + V: { kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + }, + { + no: 2, + name: "usernameToAddress", + kind: "map", + K: 9 /*ScalarType.STRING*/, + V: { kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + }, + { + no: 3, + name: "latestDrip", + kind: "map", + K: 9 /*ScalarType.STRING*/, + V: { kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, + }, + { no: 4, name: "totalDripCount", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ }, + ]); + } + create(value?: PartialMessage): FaucetStore { + const message = { addressToUsername: {}, usernameToAddress: {}, latestDrip: {}, totalDripCount: 0n }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: FaucetStore + ): FaucetStore { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* map addressToUsername */ 1: + this.binaryReadMap1(message.addressToUsername, reader, options); + break; + case /* map usernameToAddress */ 2: + this.binaryReadMap2(message.usernameToAddress, reader, options); + break; + case /* map latestDrip */ 3: + this.binaryReadMap3(message.latestDrip, reader, options); + break; + case /* uint64 totalDripCount */ 4: + message.totalDripCount = reader.uint64().toBigInt(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + private binaryReadMap1( + map: FaucetStore["addressToUsername"], + reader: IBinaryReader, + options: BinaryReadOptions + ): void { + let len = reader.uint32(), + end = reader.pos + len, + key: keyof FaucetStore["addressToUsername"] | undefined, + val: FaucetStore["addressToUsername"][any] | undefined; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case 1: + key = reader.string(); + break; + case 2: + val = reader.string(); + break; + default: + throw new globalThis.Error("unknown map entry field for field faucet.FaucetStore.addressToUsername"); + } + } + map[key ?? ""] = val ?? ""; + } + private binaryReadMap2( + map: FaucetStore["usernameToAddress"], + reader: IBinaryReader, + options: BinaryReadOptions + ): void { + let len = reader.uint32(), + end = reader.pos + len, + key: keyof FaucetStore["usernameToAddress"] | undefined, + val: FaucetStore["usernameToAddress"][any] | undefined; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case 1: + key = reader.string(); + break; + case 2: + val = reader.string(); + break; + default: + throw new globalThis.Error("unknown map entry field for field faucet.FaucetStore.usernameToAddress"); + } + } + map[key ?? ""] = val ?? ""; + } + private binaryReadMap3(map: FaucetStore["latestDrip"], reader: IBinaryReader, options: BinaryReadOptions): void { + let len = reader.uint32(), + end = reader.pos + len, + key: keyof FaucetStore["latestDrip"] | undefined, + val: FaucetStore["latestDrip"][any] | undefined; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case 1: + key = reader.string(); + break; + case 2: + val = reader.int64().toBigInt(); + break; + default: + throw new globalThis.Error("unknown map entry field for field faucet.FaucetStore.latestDrip"); + } + } + map[key ?? ""] = val ?? 0n; + } + internalBinaryWrite(message: FaucetStore, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* map addressToUsername = 1; */ + for (let k of Object.keys(message.addressToUsername)) + writer + .tag(1, WireType.LengthDelimited) + .fork() + .tag(1, WireType.LengthDelimited) + .string(k) + .tag(2, WireType.LengthDelimited) + .string(message.addressToUsername[k]) + .join(); + /* map usernameToAddress = 2; */ + for (let k of Object.keys(message.usernameToAddress)) + writer + .tag(2, WireType.LengthDelimited) + .fork() + .tag(1, WireType.LengthDelimited) + .string(k) + .tag(2, WireType.LengthDelimited) + .string(message.usernameToAddress[k]) + .join(); + /* map latestDrip = 3; */ + for (let k of Object.keys(message.latestDrip)) + writer + .tag(3, WireType.LengthDelimited) + .fork() + .tag(1, WireType.LengthDelimited) + .string(k) + .tag(2, WireType.Varint) + .int64(message.latestDrip[k]) + .join(); + /* uint64 totalDripCount = 4; */ + if (message.totalDripCount !== 0n) writer.tag(4, WireType.Varint).uint64(message.totalDripCount); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.FaucetStore + */ +export const FaucetStore = new FaucetStore$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class VerifyTweetRequest$Type extends MessageType { + constructor() { + super("faucet.VerifyTweetRequest", [ + { no: 1, name: "username", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "address", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): VerifyTweetRequest { + const message = { username: "", address: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: VerifyTweetRequest + ): VerifyTweetRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string username */ 1: + message.username = reader.string(); + break; + case /* string address */ 2: + message.address = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: VerifyTweetRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string username = 1; */ + if (message.username !== "") writer.tag(1, WireType.LengthDelimited).string(message.username); + /* string address = 2; */ + if (message.address !== "") writer.tag(2, WireType.LengthDelimited).string(message.address); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.VerifyTweetRequest + */ +export const VerifyTweetRequest = new VerifyTweetRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class VerifyTweetResponse$Type extends MessageType { + constructor() { + super("faucet.VerifyTweetResponse", [{ no: 1, name: "txHash", kind: "scalar", T: 9 /*ScalarType.STRING*/ }]); + } + create(value?: PartialMessage): VerifyTweetResponse { + const message = { txHash: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: VerifyTweetResponse + ): VerifyTweetResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string txHash */ 1: + message.txHash = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: VerifyTweetResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string txHash = 1; */ + if (message.txHash !== "") writer.tag(1, WireType.LengthDelimited).string(message.txHash); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.VerifyTweetResponse + */ +export const VerifyTweetResponse = new VerifyTweetResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetLinkedTwittersRequest$Type extends MessageType { + constructor() { + super("faucet.GetLinkedTwittersRequest", []); + } + create(value?: PartialMessage): GetLinkedTwittersRequest { + const message = {}; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: GetLinkedTwittersRequest + ): GetLinkedTwittersRequest { + return target ?? this.create(); + } + internalBinaryWrite( + message: GetLinkedTwittersRequest, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.GetLinkedTwittersRequest + */ +export const GetLinkedTwittersRequest = new GetLinkedTwittersRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetLinkedTwittersResponse$Type extends MessageType { + constructor() { + super("faucet.GetLinkedTwittersResponse", [ + { no: 1, name: "linkedTwitters", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => LinkedTwitterPair }, + ]); + } + create(value?: PartialMessage): GetLinkedTwittersResponse { + const message = { linkedTwitters: [] }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: GetLinkedTwittersResponse + ): GetLinkedTwittersResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated faucet.LinkedTwitterPair linkedTwitters */ 1: + message.linkedTwitters.push(LinkedTwitterPair.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite( + message: GetLinkedTwittersResponse, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + /* repeated faucet.LinkedTwitterPair linkedTwitters = 1; */ + for (let i = 0; i < message.linkedTwitters.length; i++) + LinkedTwitterPair.internalBinaryWrite( + message.linkedTwitters[i], + writer.tag(1, WireType.LengthDelimited).fork(), + options + ).join(); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.GetLinkedTwittersResponse + */ +export const GetLinkedTwittersResponse = new GetLinkedTwittersResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LinkedTwitterForAddressRequest$Type extends MessageType { + constructor() { + super("faucet.LinkedTwitterForAddressRequest", [ + { no: 1, name: "address", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): LinkedTwitterForAddressRequest { + const message = { address: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: LinkedTwitterForAddressRequest + ): LinkedTwitterForAddressRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string address */ 1: + message.address = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite( + message: LinkedTwitterForAddressRequest, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + /* string address = 1; */ + if (message.address !== "") writer.tag(1, WireType.LengthDelimited).string(message.address); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.LinkedTwitterForAddressRequest + */ +export const LinkedTwitterForAddressRequest = new LinkedTwitterForAddressRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LinkedTwitterForAddressResponse$Type extends MessageType { + constructor() { + super("faucet.LinkedTwitterForAddressResponse", [ + { no: 1, name: "username", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): LinkedTwitterForAddressResponse { + const message = { username: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: LinkedTwitterForAddressResponse + ): LinkedTwitterForAddressResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string username */ 1: + message.username = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite( + message: LinkedTwitterForAddressResponse, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + /* string username = 1; */ + if (message.username !== "") writer.tag(1, WireType.LengthDelimited).string(message.username); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.LinkedTwitterForAddressResponse + */ +export const LinkedTwitterForAddressResponse = new LinkedTwitterForAddressResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LinkedAddressForTwitterRequest$Type extends MessageType { + constructor() { + super("faucet.LinkedAddressForTwitterRequest", [ + { no: 1, name: "username", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): LinkedAddressForTwitterRequest { + const message = { username: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: LinkedAddressForTwitterRequest + ): LinkedAddressForTwitterRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string username */ 1: + message.username = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite( + message: LinkedAddressForTwitterRequest, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + /* string username = 1; */ + if (message.username !== "") writer.tag(1, WireType.LengthDelimited).string(message.username); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.LinkedAddressForTwitterRequest + */ +export const LinkedAddressForTwitterRequest = new LinkedAddressForTwitterRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LinkedAddressForTwitterResponse$Type extends MessageType { + constructor() { + super("faucet.LinkedAddressForTwitterResponse", [ + { no: 1, name: "address", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): LinkedAddressForTwitterResponse { + const message = { address: "" }; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: LinkedAddressForTwitterResponse + ): LinkedAddressForTwitterResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string address */ 1: + message.address = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite( + message: LinkedAddressForTwitterResponse, + writer: IBinaryWriter, + options: BinaryWriteOptions + ): IBinaryWriter { + /* string address = 1; */ + if (message.address !== "") writer.tag(1, WireType.LengthDelimited).string(message.address); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message faucet.LinkedAddressForTwitterResponse + */ +export const LinkedAddressForTwitterResponse = new LinkedAddressForTwitterResponse$Type(); +/** + * @generated ServiceType for protobuf service faucet.FaucetService + */ +export const FaucetService = new ServiceType("faucet.FaucetService", [ + { name: "VerifyTweet", options: {}, I: VerifyTweetRequest, O: VerifyTweetResponse }, + { name: "GetLinkedTwitters", options: {}, I: GetLinkedTwittersRequest, O: GetLinkedTwittersResponse }, + { + name: "GetLinkedTwitterForAddress", + options: {}, + I: LinkedTwitterForAddressRequest, + O: LinkedTwitterForAddressResponse, + }, + { + name: "GetLinkedAddressForTwitter", + options: {}, + I: LinkedAddressForTwitterRequest, + O: LinkedAddressForTwitterResponse, + }, +]);