* Prices API

* Add current prices

* Historical prices persist

* Add mutexs

* multiple providers

* Handle startup

* Edge case where historical price is requested for current

* fix median edge case

* Don't return too old last price

* bug fixes

* price metrics and logging

* warnings
This commit is contained in:
adityapk00 2021-05-18 09:26:55 -07:00 committed by GitHub
parent d5ca359418
commit 41ebe0e04b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 851 additions and 125 deletions

View File

@ -126,6 +126,9 @@ func startServer(opts *common.Options) error {
promRegistry.MustRegister(common.Metrics.SendTransactionsCounter)
promRegistry.MustRegister(common.Metrics.TotalSaplingParamsCounter)
promRegistry.MustRegister(common.Metrics.TotalSproutParamsCounter)
promRegistry.MustRegister(common.Metrics.ZecPriceGauge)
promRegistry.MustRegister(common.Metrics.ZecPriceHistoryWebAPICounter)
promRegistry.MustRegister(common.Metrics.ZecPriceHistoryErrors)
logger.SetLevel(logrus.Level(opts.LogLevel))
@ -279,6 +282,9 @@ func startServer(opts *common.Options) error {
walletrpc.RegisterDarksideStreamerServer(server, service)
}
// Initialize price fetcher
common.StartPriceFetcher(dbPath, chainName)
// Start listening
listener, err := net.Listen("tcp", opts.GRPCBindAddr)
if err != nil {

View File

@ -16,7 +16,7 @@ func ParamsHandler(w http.ResponseWriter, req *http.Request) {
"param": "sapling-output",
}).Info("ParamsHandler")
http.Redirect(w, req, "https://z.cash/downloads/sapling-output.params", 301)
http.Redirect(w, req, "https://z.cash/downloads/sapling-output.params", http.StatusMovedPermanently)
return
}
@ -26,7 +26,7 @@ func ParamsHandler(w http.ResponseWriter, req *http.Request) {
"param": "sapling-spend",
}).Info("ParamsHandler")
http.Redirect(w, req, "https://z.cash/downloads/sapling-spend.params", 301)
http.Redirect(w, req, "https://z.cash/downloads/sapling-spend.params", http.StatusMovedPermanently)
return
}
@ -37,7 +37,7 @@ func ParamsHandler(w http.ResponseWriter, req *http.Request) {
}).Info("ParamsHandler")
Metrics.TotalSproutParamsCounter.Inc()
http.Redirect(w, req, "https://z.cash/downloads/sprout-groth16.params", 301)
http.Redirect(w, req, "https://z.cash/downloads/sprout-groth16.params", http.StatusMovedPermanently)
return
}

387
common/prices.go Normal file
View File

@ -0,0 +1,387 @@
package common
import (
"encoding/gob"
"encoding/json"
"errors"
"fmt"
"io"
"math"
"net/http"
"os"
"path/filepath"
"reflect"
"runtime"
"sort"
"strconv"
"sync"
"time"
"github.com/sirupsen/logrus"
)
var (
// Map of all historical prices. Date as "yyyy-mm-dd" to price in cents
historicalPrices map[string]float64 = make(map[string]float64)
// The latest price
latestPrice float64 = -1
// Latest price was fetched at
latestPriceAt time.Time
// Mutex to control both historical and latest price
pricesRwMutex sync.RWMutex
// Full path of the persistence file
pricesFileName string
)
func fetchAPIPrice(url string, resultPath []string) (float64, error) {
resp, err := http.Get(url)
if err != nil {
return -1, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return -1, err
}
var priceJSON map[string]interface{}
json.Unmarshal(body, &priceJSON)
for i := 0; i < len(resultPath); i++ {
d, ok := priceJSON[resultPath[i]]
if !ok {
return -1, fmt.Errorf("API error: couldn't find '%s'", resultPath[i])
}
switch v := d.(type) {
case float64:
return v, nil
case string:
{
price, err := strconv.ParseFloat(v, 64)
return price, err
}
case map[string]interface{}:
priceJSON = v
}
}
return -1, errors.New("path didn't result in lookup")
}
func fetchCoinbasePrice() (float64, error) {
return fetchAPIPrice("https://api.coinbase.com/v2/exchange-rates?currency=ZEC", []string{"data", "rates", "USD"})
}
func fetchCoinCapPrice() (float64, error) {
return fetchAPIPrice("https://api.coincap.io/v2/rates/zcash", []string{"data", "rateUsd"})
}
func fetchBinancePrice() (float64, error) {
return fetchAPIPrice("https://api.binance.com/api/v3/avgPrice?symbol=ZECUSDC", []string{"price"})
}
func fetchHistoricalCoingeckoPrice(ts *time.Time) (float64, error) {
dt := ts.Format("02-01-2006") // dd-mm-yyyy
url := fmt.Sprintf("https://api.coingecko.com/api/v3/coins/zcash/history?date=%s?id=zcash", dt)
return fetchAPIPrice(url, []string{"market_data", "current_price", "usd"})
}
// Median gets the median number in a slice of numbers
func median(inp []float64) (median float64) {
// Start by sorting a copy of the slice
sort.Float64s(inp)
// No math is needed if there are no numbers
// For even numbers we add the two middle numbers
// and divide by two using the mean function above
// For odd numbers we just use the middle number
l := len(inp)
if l == 0 {
return -1
} else if l == 2 {
return (inp[0] + inp[1]) / 2
} else if l%2 == 0 {
return (inp[l/2-1] + inp[l/2+1]) / 2
} else {
return inp[l/2]
}
}
// fetchPriceFromWebAPI will fetch prices from multiple places, discard outliers and return the
// concensus price
func fetchPriceFromWebAPI() (float64, error) {
// We'll fetch prices from all our endpoints, and use the median price from that
priceProviders := []func() (float64, error){fetchBinancePrice, fetchCoinCapPrice, fetchCoinbasePrice}
ch := make(chan float64)
// Get all prices
for _, provider := range priceProviders {
go func(provider func() (float64, error)) {
price, err := provider()
if err != nil {
Log.WithFields(logrus.Fields{
"method": "CurrentPrice",
"provider": runtime.FuncForPC(reflect.ValueOf(provider).Pointer()).Name(),
"error": err,
}).Error("Service")
ch <- -1
} else {
Log.WithFields(logrus.Fields{
"method": "CurrentPrice",
"provider": runtime.FuncForPC(reflect.ValueOf(provider).Pointer()).Name(),
"price": price,
}).Info("Service")
ch <- price
}
}(provider)
}
prices := make([]float64, 0)
for range priceProviders {
price := <-ch
if price > 0 {
prices = append(prices, price)
}
}
// sort
sort.Float64s(prices)
// Get the median price
median1 := median(prices)
// Discard all values that are more than 20% outside the median
validPrices := make([]float64, 0)
for _, price := range prices {
if (math.Abs(price-median1) / median1) > 0.2 {
Log.WithFields(logrus.Fields{
"method": "CurrentPrice",
"error": fmt.Sprintf("Discarding price (%.2f) because too far away from median (%.2f", price, median1),
}).Error("Service")
} else {
validPrices = append(validPrices, price)
}
}
// If we discarded too many, return an error
if len(validPrices) < (len(prices)/2 + 1) {
return -1, errors.New("not enough valid prices")
} else {
return median(validPrices), nil
}
}
func readHistoricalPricesFile() (map[string]float64, error) {
f, err := os.Open(pricesFileName)
if err != nil {
Log.Errorf("Couldn't open file %s for writing: %v", pricesFileName, err)
return nil, err
}
defer f.Close()
j := gob.NewDecoder(f)
var prices map[string]float64
err = j.Decode(&prices)
if err != nil {
Log.Errorf("Couldn't decode historical prices: %v", err)
return nil, err
}
Log.WithFields(logrus.Fields{
"method": "ReadHistoricalPriceFile",
"action": "Read historical prices file",
"records": len(prices),
}).Info("Service")
return prices, nil
}
func writeHistoricalPricesMap() {
// Serialize the map to disk.
f, err := os.OpenFile(pricesFileName, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
Log.Errorf("Couldn't open file %s for writing: %v", pricesFileName, err)
return
}
defer f.Close()
j := gob.NewEncoder(f)
{
// Read lock
pricesRwMutex.RLock()
err = j.Encode(historicalPrices)
pricesRwMutex.RUnlock()
if err != nil {
Log.Errorf("Couldn't encode historical prices: %v", err)
return
}
}
Log.WithFields(logrus.Fields{
"method": "WriteHistoricalPriceFile",
"action": "Wrote historical prices file",
}).Info("Service")
}
func GetCurrentPrice() (float64, error) {
// Read lock
pricesRwMutex.RLock()
defer pricesRwMutex.RUnlock()
// If the current price is too old, don't return it.
if time.Since(latestPriceAt).Hours() > 3 {
return -1, errors.New("price too old")
}
return latestPrice, nil
}
func writeLatestPrice(price float64) {
{
// Read lock
pricesRwMutex.RLock()
// Check if the time has "rolled over", if yes then preserve the last price
// as the previous day's historical price
if latestPrice > 0 && latestPriceAt.Format("2006-01-02") != time.Now().Format("2006-01-02") {
// update the historical price.
// First, make a copy of the time
t := time.Unix(latestPriceAt.Unix(), 0)
go addHistoricalPrice(latestPrice, &t)
}
pricesRwMutex.RUnlock()
}
// Write lock
pricesRwMutex.Lock()
latestPrice = price
latestPriceAt = time.Now()
pricesRwMutex.Unlock()
}
func GetHistoricalPrice(ts *time.Time) (float64, *time.Time, error) {
dt := ts.Format("2006-01-02")
canonicalTime, err := time.Parse("2006-01-02", dt)
if err != nil {
return -1, nil, err
}
{
// Read lock
pricesRwMutex.RLock()
val, ok := historicalPrices[dt]
pricesRwMutex.RUnlock()
if ok {
return val, &canonicalTime, nil
}
}
{
// Check if this is the same as the current latest price
// Read lock
pricesRwMutex.RLock()
var price = latestPrice
var returnPrice = price > 0 && latestPriceAt.Format("2006-01-02") == dt
pricesRwMutex.RUnlock()
if returnPrice {
return price, &canonicalTime, nil
}
}
// Fetch price from web API
price, err := fetchHistoricalCoingeckoPrice(ts)
if err != nil {
Log.Errorf("Couldn't read historical prices from Coingecko: %v", err)
return -1, nil, err
}
go addHistoricalPrice(price, ts)
return price, &canonicalTime, err
}
func addHistoricalPrice(price float64, ts *time.Time) {
if price <= 0 {
return
}
dt := ts.Format("2006-01-02")
// Read Lock
pricesRwMutex.RLock()
_, ok := historicalPrices[dt]
pricesRwMutex.RUnlock()
if !ok {
// Write lock
pricesRwMutex.Lock()
historicalPrices[dt] = price
defer pricesRwMutex.Unlock()
// Increment success counter
Metrics.ZecPriceHistoryWebAPICounter.Inc()
go Log.WithFields(logrus.Fields{
"method": "HistoricalPrice",
"action": "Add",
"date": dt,
"price": price,
}).Info("Service")
go writeHistoricalPricesMap()
}
}
// StartPriceFetcher starts a new thread that will fetch historical and current prices
func StartPriceFetcher(dbPath string, chainName string) {
// Set the prices file name
pricesFileName = filepath.Join(dbPath, chainName, "prices")
// Read the historical prices if available
if prices, err := readHistoricalPricesFile(); err != nil {
Log.Errorf("Couldn't read historical prices, starting with empty map")
} else {
// Write lock
pricesRwMutex.Lock()
historicalPrices = prices
pricesRwMutex.Unlock()
}
// Fetch the current price every hour
go func() {
for {
price, err := fetchPriceFromWebAPI()
if err != nil {
Log.Errorf("Error getting prices from web APIs: %v", err)
} else {
Log.WithFields(logrus.Fields{
"method": "SetCurrentPrice",
"price": price,
}).Info("Service")
writeLatestPrice(price)
}
// Refresh every
time.Sleep(15 * time.Minute)
}
}()
}

View File

@ -4,12 +4,15 @@ import "github.com/prometheus/client_golang/prometheus"
// PrometheusMetrics is a list of collected Prometheus Counters and Guages that will be exported
type PrometheusMetrics struct {
LatestBlockCounter prometheus.Counter
TotalBlocksServedConter prometheus.Counter
SendTransactionsCounter prometheus.Counter
TotalErrors prometheus.Counter
TotalSaplingParamsCounter prometheus.Counter
TotalSproutParamsCounter prometheus.Counter
LatestBlockCounter prometheus.Counter
TotalBlocksServedConter prometheus.Counter
SendTransactionsCounter prometheus.Counter
TotalErrors prometheus.Counter
TotalSaplingParamsCounter prometheus.Counter
TotalSproutParamsCounter prometheus.Counter
ZecPriceGauge prometheus.Gauge
ZecPriceHistoryWebAPICounter prometheus.Counter
ZecPriceHistoryErrors prometheus.Counter
}
func GetPrometheusMetrics() *PrometheusMetrics {
@ -49,5 +52,20 @@ func GetPrometheusMetrics() *PrometheusMetrics {
Help: "Total number of params downloasd for sprout params",
})
m.ZecPriceGauge = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "zec_price",
Help: "Current price of Zec",
})
m.ZecPriceHistoryWebAPICounter = prometheus.NewCounter(prometheus.CounterOpts{
Name: "zec_price_history_api_counter",
Help: "Counter of number of successful API calls to history API",
})
m.ZecPriceHistoryErrors = prometheus.NewCounter(prometheus.CounterOpts{
Name: "zec_price_history_errors",
Help: "Counter for number of errors seen in the history price API",
})
return m
}

View File

@ -97,6 +97,46 @@ func (s *lwdStreamer) dailyActiveBlock(height uint64, peerip string) {
}
}
func (s *lwdStreamer) GetZECPrice(ctx context.Context, in *walletrpc.PriceRequest) (*walletrpc.PriceResponse, error) {
// Check for prices before zcash was born
if in == nil || in.Timestamp <= 1477551600 /* Zcash birthday: 2016-10-28*/ {
common.Metrics.ZecPriceHistoryErrors.Inc()
return nil, errors.New("incorrect Timestamp")
}
if in.Currency != "USD" {
common.Metrics.ZecPriceHistoryErrors.Inc()
return nil, errors.New("unsupported currency")
}
ts := time.Unix(int64(in.Timestamp), 0)
price, timeFetched, err := common.GetHistoricalPrice(&ts)
if err != nil {
common.Metrics.ZecPriceHistoryErrors.Inc()
return nil, err
}
return &walletrpc.PriceResponse{Timestamp: timeFetched.Unix(), Price: price, Currency: "USD"}, nil
}
func (s *lwdStreamer) GetCurrentZECPrice(ctx context.Context, in *walletrpc.Empty) (*walletrpc.PriceResponse, error) {
price, err := common.GetCurrentPrice()
if err != nil {
common.Metrics.ZecPriceGauge.Set(0)
return nil, err
}
if price <= 0 {
common.Metrics.ZecPriceGauge.Set(0)
return nil, errors.New("no price available")
}
resp := &walletrpc.PriceResponse{Timestamp: time.Now().Unix(), Currency: "USD", Price: price}
common.Metrics.ZecPriceGauge.Set(price)
return resp, nil
}
// GetLatestBlock returns the height of the best chain, according to zcashd.
func (s *lwdStreamer) GetLatestBlock(ctx context.Context, placeholder *walletrpc.ChainSpec) (*walletrpc.BlockID, error) {
result, rpcErr := common.RawRequest("getblockchaininfo", []json.RawMessage{})

View File

@ -5,7 +5,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// protoc v3.6.1
// source: compact_formats.proto
package walletrpc

View File

@ -3,5 +3,5 @@
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
package walletrpc
//go:generate protoc -I . ./compact_formats.proto --go_out=plugins=grpc:.
//go:generate protoc -I . ./service.proto --go_out=plugins=grpc:.
//go:generate protoc -I . --go_out=:../.. --go-grpc_out=:../.. ./compact_formats.proto
//go:generate protoc -I . --go_out=:../.. --go-grpc_out=:../.. ./service.proto

View File

@ -5,7 +5,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// protoc v3.6.1
// source: service.proto
package walletrpc
@ -1182,6 +1182,130 @@ func (x *GetAddressUtxosReplyList) GetAddressUtxos() []*GetAddressUtxosReply {
return nil
}
type PriceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// List of timestamps(in sec) at which the price is being requested
Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// 3 letter currency-code
Currency string `protobuf:"bytes,2,opt,name=currency,proto3" json:"currency,omitempty"`
}
func (x *PriceRequest) Reset() {
*x = PriceRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_service_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PriceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PriceRequest) ProtoMessage() {}
func (x *PriceRequest) ProtoReflect() protoreflect.Message {
mi := &file_service_proto_msgTypes[19]
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 PriceRequest.ProtoReflect.Descriptor instead.
func (*PriceRequest) Descriptor() ([]byte, []int) {
return file_service_proto_rawDescGZIP(), []int{19}
}
func (x *PriceRequest) GetTimestamp() uint64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *PriceRequest) GetCurrency() string {
if x != nil {
return x.Currency
}
return ""
}
type PriceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Timestamp at which this price quote was fetched. Note, this may not be the same
// as the request timestamp, but the server will respond with the closest timestamp that it has/can fetch
Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// 3-letter currency code, matching the request
Currency string `protobuf:"bytes,2,opt,name=currency,proto3" json:"currency,omitempty"`
// price of ZEC
Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"`
}
func (x *PriceResponse) Reset() {
*x = PriceResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_service_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PriceResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PriceResponse) ProtoMessage() {}
func (x *PriceResponse) ProtoReflect() protoreflect.Message {
mi := &file_service_proto_msgTypes[20]
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 PriceResponse.ProtoReflect.Descriptor instead.
func (*PriceResponse) Descriptor() ([]byte, []int) {
return file_service_proto_rawDescGZIP(), []int{20}
}
func (x *PriceResponse) GetTimestamp() int64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *PriceResponse) GetCurrency() string {
if x != nil {
return x.Currency
}
return ""
}
func (x *PriceResponse) GetPrice() float64 {
if x != nil {
return x.Price
}
return 0
}
var File_service_proto protoreflect.FileDescriptor
var file_service_proto_rawDesc = []byte{
@ -1303,93 +1427,116 @@ var file_service_proto_rawDesc = []byte{
0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x52, 0x0c,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x32, 0xbb, 0x0a, 0x0a,
0x11, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x65, 0x72, 0x12, 0x54, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61,
0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f,
0x63, 0x6b, 0x49, 0x44, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d,
0x70, 0x61, 0x63, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0d, 0x47,
0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x21, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x1a,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x48, 0x0a, 0x0c,
0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x5f, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01,
0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x32, 0xf3, 0x0b, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70,
0x61, 0x63, 0x74, 0x54, 0x78, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x72, 0x12, 0x54, 0x0a,
0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12,
0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65,
0x63, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49,
0x44, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12,
0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x1a,
0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x54, 0x78, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x25, 0x2e, 0x63, 0x61,
0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e,
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f,
0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x21, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x23,
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x5a, 0x45, 0x43, 0x50, 0x72, 0x69,
0x63, 0x65, 0x12, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x5a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5a, 0x45, 0x43,
0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x1a, 0x24, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x69, 0x63,
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0e, 0x47,
0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e,
0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64,
0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x78, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x25,
0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x54, 0x78, 0x69, 0x64, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x61, 0x73, 0x68,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x78, 0x69, 0x64, 0x73, 0x12, 0x34, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x74,
0x65, 0x72, 0x1a, 0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a,
0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61,
0x6e, 0x63, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x18, 0x47, 0x65, 0x74,
0x54, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x53,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61,
0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x54, 0x0a, 0x0c, 0x47, 0x65, 0x74,
0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68,
0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a,
0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x12, 0x47, 0x65,
0x74, 0x54, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x12, 0x22, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x4c, 0x69, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c,
0x61, 0x6e, 0x63, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x54, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d,
0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45,
0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x1a, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x0c,
0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x1a, 0x20, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x00,
0x12, 0x6f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74,
0x78, 0x6f, 0x73, 0x12, 0x29, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x41, 0x72, 0x67, 0x1a, 0x2f,
0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x22,
0x00, 0x12, 0x73, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55,
0x74, 0x78, 0x6f, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x29, 0x2e, 0x63, 0x61, 0x73,
0x63, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x1a, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68,
0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x22, 0x00, 0x30, 0x01, 0x12,
0x52, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x1a,
0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74,
0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x29, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47,
0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x41, 0x72,
0x67, 0x1a, 0x2f, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4c, 0x69,
0x73, 0x74, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x29, 0x2e,
0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64,
0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x55, 0x74, 0x78, 0x6f, 0x73, 0x41, 0x72, 0x67, 0x1a, 0x2b, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e,
0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73,
0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x47, 0x65, 0x74,
0x4c, 0x69, 0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78,
0x6f, 0x73, 0x41, 0x72, 0x67, 0x1a, 0x2b, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x70,
0x6c, 0x79, 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x67,
0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x04, 0x50, 0x69,
0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x69, 0x6e, 0x67,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1b, 0x5a, 0x16, 0x6c, 0x69,
0x67, 0x68, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x72, 0x70, 0x63, 0xba, 0x02, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e,
0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x4e, 0x0a,
0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x75,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50,
0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1b, 0x5a,
0x16, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2f, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x72, 0x70, 0x63, 0xba, 0x02, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
@ -1404,7 +1551,7 @@ func file_service_proto_rawDescGZIP() []byte {
return file_service_proto_rawDescData
}
var file_service_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
var file_service_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
var file_service_proto_goTypes = []interface{}{
(*BlockID)(nil), // 0: cash.z.wallet.sdk.rpc.BlockID
(*BlockRange)(nil), // 1: cash.z.wallet.sdk.rpc.BlockRange
@ -1425,8 +1572,10 @@ var file_service_proto_goTypes = []interface{}{
(*GetAddressUtxosArg)(nil), // 16: cash.z.wallet.sdk.rpc.GetAddressUtxosArg
(*GetAddressUtxosReply)(nil), // 17: cash.z.wallet.sdk.rpc.GetAddressUtxosReply
(*GetAddressUtxosReplyList)(nil), // 18: cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList
(*CompactBlock)(nil), // 19: cash.z.wallet.sdk.rpc.CompactBlock
(*CompactTx)(nil), // 20: cash.z.wallet.sdk.rpc.CompactTx
(*PriceRequest)(nil), // 19: cash.z.wallet.sdk.rpc.PriceRequest
(*PriceResponse)(nil), // 20: cash.z.wallet.sdk.rpc.PriceResponse
(*CompactBlock)(nil), // 21: cash.z.wallet.sdk.rpc.CompactBlock
(*CompactTx)(nil), // 22: cash.z.wallet.sdk.rpc.CompactTx
}
var file_service_proto_depIdxs = []int32{
0, // 0: cash.z.wallet.sdk.rpc.BlockRange.start:type_name -> cash.z.wallet.sdk.rpc.BlockID
@ -1437,33 +1586,37 @@ var file_service_proto_depIdxs = []int32{
5, // 5: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLatestBlock:input_type -> cash.z.wallet.sdk.rpc.ChainSpec
0, // 6: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlock:input_type -> cash.z.wallet.sdk.rpc.BlockID
1, // 7: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlockRange:input_type -> cash.z.wallet.sdk.rpc.BlockRange
2, // 8: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:input_type -> cash.z.wallet.sdk.rpc.TxFilter
3, // 9: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:input_type -> cash.z.wallet.sdk.rpc.RawTransaction
8, // 10: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:input_type -> cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter
12, // 11: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:input_type -> cash.z.wallet.sdk.rpc.AddressList
11, // 12: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:input_type -> cash.z.wallet.sdk.rpc.Address
14, // 13: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:input_type -> cash.z.wallet.sdk.rpc.Exclude
0, // 14: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTreeState:input_type -> cash.z.wallet.sdk.rpc.BlockID
16, // 15: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxos:input_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosArg
16, // 16: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxosStream:input_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosArg
6, // 17: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:input_type -> cash.z.wallet.sdk.rpc.Empty
9, // 18: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:input_type -> cash.z.wallet.sdk.rpc.Duration
0, // 19: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLatestBlock:output_type -> cash.z.wallet.sdk.rpc.BlockID
19, // 20: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlock:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
19, // 21: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlockRange:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
3, // 22: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
4, // 23: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:output_type -> cash.z.wallet.sdk.rpc.SendResponse
3, // 24: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
13, // 25: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:output_type -> cash.z.wallet.sdk.rpc.Balance
13, // 26: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:output_type -> cash.z.wallet.sdk.rpc.Balance
20, // 27: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:output_type -> cash.z.wallet.sdk.rpc.CompactTx
15, // 28: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTreeState:output_type -> cash.z.wallet.sdk.rpc.TreeState
18, // 29: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxos:output_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList
17, // 30: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxosStream:output_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosReply
7, // 31: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:output_type -> cash.z.wallet.sdk.rpc.LightdInfo
10, // 32: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:output_type -> cash.z.wallet.sdk.rpc.PingResponse
19, // [19:33] is the sub-list for method output_type
5, // [5:19] is the sub-list for method input_type
19, // 8: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetZECPrice:input_type -> cash.z.wallet.sdk.rpc.PriceRequest
6, // 9: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetCurrentZECPrice:input_type -> cash.z.wallet.sdk.rpc.Empty
2, // 10: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:input_type -> cash.z.wallet.sdk.rpc.TxFilter
3, // 11: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:input_type -> cash.z.wallet.sdk.rpc.RawTransaction
8, // 12: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:input_type -> cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter
12, // 13: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:input_type -> cash.z.wallet.sdk.rpc.AddressList
11, // 14: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:input_type -> cash.z.wallet.sdk.rpc.Address
14, // 15: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:input_type -> cash.z.wallet.sdk.rpc.Exclude
0, // 16: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTreeState:input_type -> cash.z.wallet.sdk.rpc.BlockID
16, // 17: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxos:input_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosArg
16, // 18: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxosStream:input_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosArg
6, // 19: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:input_type -> cash.z.wallet.sdk.rpc.Empty
9, // 20: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:input_type -> cash.z.wallet.sdk.rpc.Duration
0, // 21: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLatestBlock:output_type -> cash.z.wallet.sdk.rpc.BlockID
21, // 22: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlock:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
21, // 23: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlockRange:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
20, // 24: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetZECPrice:output_type -> cash.z.wallet.sdk.rpc.PriceResponse
20, // 25: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetCurrentZECPrice:output_type -> cash.z.wallet.sdk.rpc.PriceResponse
3, // 26: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
4, // 27: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:output_type -> cash.z.wallet.sdk.rpc.SendResponse
3, // 28: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
13, // 29: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:output_type -> cash.z.wallet.sdk.rpc.Balance
13, // 30: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:output_type -> cash.z.wallet.sdk.rpc.Balance
22, // 31: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:output_type -> cash.z.wallet.sdk.rpc.CompactTx
15, // 32: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTreeState:output_type -> cash.z.wallet.sdk.rpc.TreeState
18, // 33: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxos:output_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList
17, // 34: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetAddressUtxosStream:output_type -> cash.z.wallet.sdk.rpc.GetAddressUtxosReply
7, // 35: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:output_type -> cash.z.wallet.sdk.rpc.LightdInfo
10, // 36: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:output_type -> cash.z.wallet.sdk.rpc.PingResponse
21, // [21:37] is the sub-list for method output_type
5, // [5:21] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
@ -1704,6 +1857,30 @@ func file_service_proto_init() {
return nil
}
}
file_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PriceRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PriceResponse); 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{
@ -1711,7 +1888,7 @@ func file_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_service_proto_rawDesc,
NumEnums: 0,
NumMessages: 19,
NumMessages: 21,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -135,6 +135,26 @@ message GetAddressUtxosReplyList {
repeated GetAddressUtxosReply addressUtxos = 1;
}
message PriceRequest {
// List of timestamps(in sec) at which the price is being requested
uint64 timestamp = 1;
// 3 letter currency-code
string currency = 2;
}
message PriceResponse {
// Timestamp at which this price quote was fetched. Note, this may not be the same
// as the request timestamp, but the server will respond with the closest timestamp that it has/can fetch
int64 timestamp = 1;
// 3-letter currency code, matching the request
string currency = 2;
// price of ZEC
double price = 3;
}
service CompactTxStreamer {
// Return the height of the tip of the best chain
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
@ -143,6 +163,10 @@ service CompactTxStreamer {
// Return a list of consecutive compact blocks
rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}
// Get the historical and current prices
rpc GetZECPrice(PriceRequest) returns (PriceResponse) {}
rpc GetCurrentZECPrice(Empty) returns (PriceResponse) {}
// Return the requested full (not compact) transaction (as from zcashd)
rpc GetTransaction(TxFilter) returns (RawTransaction) {}
// Submit the given transaction to the Zcash network

View File

@ -24,6 +24,9 @@ type CompactTxStreamerClient interface {
GetBlock(ctx context.Context, in *BlockID, opts ...grpc.CallOption) (*CompactBlock, error)
// Return a list of consecutive compact blocks
GetBlockRange(ctx context.Context, in *BlockRange, opts ...grpc.CallOption) (CompactTxStreamer_GetBlockRangeClient, error)
// Get the historical and current prices
GetZECPrice(ctx context.Context, in *PriceRequest, opts ...grpc.CallOption) (*PriceResponse, error)
GetCurrentZECPrice(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PriceResponse, error)
// Return the requested full (not compact) transaction (as from zcashd)
GetTransaction(ctx context.Context, in *TxFilter, opts ...grpc.CallOption) (*RawTransaction, error)
// Submit the given transaction to the Zcash network
@ -113,6 +116,24 @@ func (x *compactTxStreamerGetBlockRangeClient) Recv() (*CompactBlock, error) {
return m, nil
}
func (c *compactTxStreamerClient) GetZECPrice(ctx context.Context, in *PriceRequest, opts ...grpc.CallOption) (*PriceResponse, error) {
out := new(PriceResponse)
err := c.cc.Invoke(ctx, "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetZECPrice", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *compactTxStreamerClient) GetCurrentZECPrice(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PriceResponse, error) {
out := new(PriceResponse)
err := c.cc.Invoke(ctx, "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCurrentZECPrice", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *compactTxStreamerClient) GetTransaction(ctx context.Context, in *TxFilter, opts ...grpc.CallOption) (*RawTransaction, error) {
out := new(RawTransaction)
err := c.cc.Invoke(ctx, "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction", in, out, opts...)
@ -316,6 +337,9 @@ type CompactTxStreamerServer interface {
GetBlock(context.Context, *BlockID) (*CompactBlock, error)
// Return a list of consecutive compact blocks
GetBlockRange(*BlockRange, CompactTxStreamer_GetBlockRangeServer) error
// Get the historical and current prices
GetZECPrice(context.Context, *PriceRequest) (*PriceResponse, error)
GetCurrentZECPrice(context.Context, *Empty) (*PriceResponse, error)
// Return the requested full (not compact) transaction (as from zcashd)
GetTransaction(context.Context, *TxFilter) (*RawTransaction, error)
// Submit the given transaction to the Zcash network
@ -361,6 +385,12 @@ func (UnimplementedCompactTxStreamerServer) GetBlock(context.Context, *BlockID)
func (UnimplementedCompactTxStreamerServer) GetBlockRange(*BlockRange, CompactTxStreamer_GetBlockRangeServer) error {
return status.Errorf(codes.Unimplemented, "method GetBlockRange not implemented")
}
func (UnimplementedCompactTxStreamerServer) GetZECPrice(context.Context, *PriceRequest) (*PriceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetZECPrice not implemented")
}
func (UnimplementedCompactTxStreamerServer) GetCurrentZECPrice(context.Context, *Empty) (*PriceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCurrentZECPrice not implemented")
}
func (UnimplementedCompactTxStreamerServer) GetTransaction(context.Context, *TxFilter) (*RawTransaction, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetTransaction not implemented")
}
@ -464,6 +494,42 @@ func (x *compactTxStreamerGetBlockRangeServer) Send(m *CompactBlock) error {
return x.ServerStream.SendMsg(m)
}
func _CompactTxStreamer_GetZECPrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PriceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CompactTxStreamerServer).GetZECPrice(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetZECPrice",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CompactTxStreamerServer).GetZECPrice(ctx, req.(*PriceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CompactTxStreamer_GetCurrentZECPrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CompactTxStreamerServer).GetCurrentZECPrice(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCurrentZECPrice",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CompactTxStreamerServer).GetCurrentZECPrice(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _CompactTxStreamer_GetTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TxFilter)
if err := dec(in); err != nil {
@ -694,6 +760,14 @@ var CompactTxStreamer_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetBlock",
Handler: _CompactTxStreamer_GetBlock_Handler,
},
{
MethodName: "GetZECPrice",
Handler: _CompactTxStreamer_GetZECPrice_Handler,
},
{
MethodName: "GetCurrentZECPrice",
Handler: _CompactTxStreamer_GetCurrentZECPrice_Handler,
},
{
MethodName: "GetTransaction",
Handler: _CompactTxStreamer_GetTransaction_Handler,