diff --git a/crypto/examples.json b/crypto/examples.json index 0dda205..1273432 100644 --- a/crypto/examples.json +++ b/crypto/examples.json @@ -72,5 +72,29 @@ "date": "2021-06-20" } } + ], + "symbols": [ + { + "title": "Get list of all supported symbols", + "description": "Returns the full list of supported crypto symbols", + "request": { + }, + "response": { + "symbols": [ + { + "symbol": "BTCUSD", + "name": "Bitcoin - United States Dollar" + }, + { + "symbol": "DOGEEUR", + "name": "Dogecoin - Euro" + }, + { + "symbol": "ETHBTC", + "name": "Ethereum - Bitcoin" + } + ] + } + } ] } diff --git a/crypto/handler/crypto.go b/crypto/handler/crypto.go index 0128aee..8c7cd04 100644 --- a/crypto/handler/crypto.go +++ b/crypto/handler/crypto.go @@ -131,12 +131,12 @@ func (c *Crypto) News(ctx context.Context, req *pb.NewsRequest, rsp *pb.NewsResp return nil } -func (s *Crypto) History(ctx context.Context, req *pb.HistoryRequest, rsp *pb.HistoryResponse) error { +func (c *Crypto) History(ctx context.Context, req *pb.HistoryRequest, rsp *pb.HistoryResponse) error { if len(req.Symbol) <= 0 { return errors.BadRequest("crypto.history", "invalid symbol") } - uri := fmt.Sprintf("%sagg/crypto/prev-close/%s?apikey=%s", s.Api, req.Symbol, s.Key) + uri := fmt.Sprintf("%sagg/crypto/prev-close/%s?apikey=%s", c.Api, req.Symbol, c.Key) resp, err := http.Get(uri) if err != nil { @@ -174,12 +174,12 @@ func (s *Crypto) History(ctx context.Context, req *pb.HistoryRequest, rsp *pb.Hi return nil } -func (s *Crypto) Quote(ctx context.Context, req *pb.QuoteRequest, rsp *pb.QuoteResponse) error { +func (c *Crypto) Quote(ctx context.Context, req *pb.QuoteRequest, rsp *pb.QuoteResponse) error { if len(req.Symbol) <= 0 { return errors.BadRequest("crypto.quote", "invalid symbol") } - uri := fmt.Sprintf("%slast/quote/crypto/%s?apikey=%s", s.Api, req.Symbol, s.Key) + uri := fmt.Sprintf("%slast/quote/crypto/%s?apikey=%s", c.Api, req.Symbol, c.Key) resp, err := http.Get(uri) if err != nil { @@ -212,12 +212,12 @@ func (s *Crypto) Quote(ctx context.Context, req *pb.QuoteRequest, rsp *pb.QuoteR return nil } -func (s *Crypto) Price(ctx context.Context, req *pb.PriceRequest, rsp *pb.PriceResponse) error { +func (c *Crypto) Price(ctx context.Context, req *pb.PriceRequest, rsp *pb.PriceResponse) error { if len(req.Symbol) <= 0 { return errors.BadRequest("crypto.price", "invalid symbol") } - uri := fmt.Sprintf("%slast/crypto/%s?apikey=%s", s.Api, req.Symbol, s.Key) + uri := fmt.Sprintf("%slast/crypto/%s?apikey=%s", c.Api, req.Symbol, c.Key) resp, err := http.Get(uri) if err != nil { @@ -245,3 +245,60 @@ func (s *Crypto) Price(ctx context.Context, req *pb.PriceRequest, rsp *pb.PriceR return nil } + +func (c *Crypto) Symbols(ctx context.Context, req *pb.SymbolsRequest, rsp *pb.SymbolsResponse) error { + cached, ok := c.Cache.Get("symbolsCache") + if ok { + rsp.Symbols, _ = cached.([]*pb.Symbol) + return nil + } + + toCache := []*pb.Symbol{} + page := 1 + for { + var symbolsRsp struct { + Page int32 `json:"page"` + TotalPage int32 `json:"totalPage"` + Symbols []struct { + Symbol string `json:"symbol"` + Name string `json:"name"` + } `json:"symbols"` + } + + uri := fmt.Sprintf("%ssymbol-list/crypto?page=%d&apikey=%s", c.Api, page, c.Key) + + resp, err := http.Get(uri) + if err != nil { + logger.Errorf("Failed to get price: %v\n", err) + return errors.InternalServerError("crypto.trade", "failed to get price") + } + defer resp.Body.Close() + + b, _ := ioutil.ReadAll(resp.Body) + if resp.StatusCode != 200 { + logger.Errorf("Failed to load symbol list (non 200): %d %v\n", resp.StatusCode, string(b)) + return errors.InternalServerError("crypto.symbols", "failed to get symbols") + } + + if err := json.Unmarshal(b, &symbolsRsp); err != nil { + logger.Errorf("Error unmarshalling cyrpto symbols: %v\n", err) + return errors.InternalServerError("crypto.symbols", "failed to get symbols") + } + + for _, v := range symbolsRsp.Symbols { + toCache = append(toCache, &pb.Symbol{ + Symbol: v.Symbol, + Name: v.Name, + }) + } + + if symbolsRsp.Page == symbolsRsp.TotalPage { + break + } + page++ + } + c.Cache.Set("symbolsCache", toCache, 24*time.Hour) + rsp.Symbols = toCache + return nil + +} diff --git a/crypto/proto/crypto.pb.go b/crypto/proto/crypto.pb.go index c8c4c6f..429dbac 100644 --- a/crypto/proto/crypto.pb.go +++ b/crypto/proto/crypto.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.15.6 +// protoc v3.15.5 // source: proto/crypto.proto package crypto @@ -110,7 +110,7 @@ type NewsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // cryptocurrency to request news for e.g BTC + // cryptocurrency ticker to request news for e.g BTC Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"` } @@ -216,7 +216,7 @@ type PriceRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // crypto symbol e.g BTCUSD + // the crypto symbol e.g BTCUSD Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"` } @@ -316,7 +316,7 @@ func (x *PriceResponse) GetPrice() float64 { return 0 } -// Get the last quote for the crypto +// Get the last quote for a given crypto ticker type QuoteRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -609,6 +609,147 @@ func (x *HistoryResponse) GetDate() string { return "" } +// Returns the full list of supported symbols +type SymbolsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SymbolsRequest) Reset() { + *x = SymbolsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_crypto_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SymbolsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SymbolsRequest) ProtoMessage() {} + +func (x *SymbolsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_crypto_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 SymbolsRequest.ProtoReflect.Descriptor instead. +func (*SymbolsRequest) Descriptor() ([]byte, []int) { + return file_proto_crypto_proto_rawDescGZIP(), []int{9} +} + +type SymbolsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Symbols []*Symbol `protobuf:"bytes,1,rep,name=symbols,proto3" json:"symbols,omitempty"` +} + +func (x *SymbolsResponse) Reset() { + *x = SymbolsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_crypto_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SymbolsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SymbolsResponse) ProtoMessage() {} + +func (x *SymbolsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_crypto_proto_msgTypes[10] + 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 SymbolsResponse.ProtoReflect.Descriptor instead. +func (*SymbolsResponse) Descriptor() ([]byte, []int) { + return file_proto_crypto_proto_rawDescGZIP(), []int{10} +} + +func (x *SymbolsResponse) GetSymbols() []*Symbol { + if x != nil { + return x.Symbols + } + return nil +} + +type Symbol struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Symbol) Reset() { + *x = Symbol{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_crypto_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Symbol) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Symbol) ProtoMessage() {} + +func (x *Symbol) ProtoReflect() protoreflect.Message { + mi := &file_proto_crypto_proto_msgTypes[11] + 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 Symbol.ProtoReflect.Descriptor instead. +func (*Symbol) Descriptor() ([]byte, []int) { + return file_proto_crypto_proto_rawDescGZIP(), []int{11} +} + +func (x *Symbol) GetSymbol() string { + if x != nil { + return x.Symbol + } + return "" +} + +func (x *Symbol) GetName() string { + if x != nil { + return x.Name + } + return "" +} + var File_proto_crypto_proto protoreflect.FileDescriptor var file_proto_crypto_proto_rawDesc = []byte{ @@ -663,23 +804,35 @@ var file_proto_crypto_proto_rawDesc = []byte{ 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x65, 0x32, 0xeb, 0x01, 0x0a, 0x06, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x12, 0x33, 0x0a, - 0x04, 0x4e, 0x65, 0x77, 0x73, 0x12, 0x13, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x4e, - 0x65, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, - 0x69, 0x63, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x2e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x07, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x6f, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x52, 0x07, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0xa9, 0x02, 0x0a, 0x06, 0x43, 0x72, 0x79, 0x70, + 0x74, 0x6f, 0x12, 0x33, 0x0a, 0x04, 0x4e, 0x65, 0x77, 0x73, 0x12, 0x13, 0x2e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x12, 0x14, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, + 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x36, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x6f, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, + 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x16, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, + 0x12, 0x16, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x6f, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -694,7 +847,7 @@ func file_proto_crypto_proto_rawDescGZIP() []byte { return file_proto_crypto_proto_rawDescData } -var file_proto_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_proto_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_proto_crypto_proto_goTypes = []interface{}{ (*Article)(nil), // 0: crypto.Article (*NewsRequest)(nil), // 1: crypto.NewsRequest @@ -705,22 +858,28 @@ var file_proto_crypto_proto_goTypes = []interface{}{ (*QuoteResponse)(nil), // 6: crypto.QuoteResponse (*HistoryRequest)(nil), // 7: crypto.HistoryRequest (*HistoryResponse)(nil), // 8: crypto.HistoryResponse + (*SymbolsRequest)(nil), // 9: crypto.SymbolsRequest + (*SymbolsResponse)(nil), // 10: crypto.SymbolsResponse + (*Symbol)(nil), // 11: crypto.Symbol } var file_proto_crypto_proto_depIdxs = []int32{ - 0, // 0: crypto.NewsResponse.articles:type_name -> crypto.Article - 1, // 1: crypto.Crypto.News:input_type -> crypto.NewsRequest - 5, // 2: crypto.Crypto.Quote:input_type -> crypto.QuoteRequest - 3, // 3: crypto.Crypto.Price:input_type -> crypto.PriceRequest - 7, // 4: crypto.Crypto.History:input_type -> crypto.HistoryRequest - 2, // 5: crypto.Crypto.News:output_type -> crypto.NewsResponse - 6, // 6: crypto.Crypto.Quote:output_type -> crypto.QuoteResponse - 4, // 7: crypto.Crypto.Price:output_type -> crypto.PriceResponse - 8, // 8: crypto.Crypto.History:output_type -> crypto.HistoryResponse - 5, // [5:9] is the sub-list for method output_type - 1, // [1:5] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // 0: crypto.NewsResponse.articles:type_name -> crypto.Article + 11, // 1: crypto.SymbolsResponse.symbols:type_name -> crypto.Symbol + 1, // 2: crypto.Crypto.News:input_type -> crypto.NewsRequest + 5, // 3: crypto.Crypto.Quote:input_type -> crypto.QuoteRequest + 3, // 4: crypto.Crypto.Price:input_type -> crypto.PriceRequest + 7, // 5: crypto.Crypto.History:input_type -> crypto.HistoryRequest + 9, // 6: crypto.Crypto.Symbols:input_type -> crypto.SymbolsRequest + 2, // 7: crypto.Crypto.News:output_type -> crypto.NewsResponse + 6, // 8: crypto.Crypto.Quote:output_type -> crypto.QuoteResponse + 4, // 9: crypto.Crypto.Price:output_type -> crypto.PriceResponse + 8, // 10: crypto.Crypto.History:output_type -> crypto.HistoryResponse + 10, // 11: crypto.Crypto.Symbols:output_type -> crypto.SymbolsResponse + 7, // [7:12] is the sub-list for method output_type + 2, // [2:7] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_proto_crypto_proto_init() } @@ -837,6 +996,42 @@ func file_proto_crypto_proto_init() { return nil } } + file_proto_crypto_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SymbolsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_crypto_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SymbolsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_crypto_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Symbol); 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{ @@ -844,7 +1039,7 @@ func file_proto_crypto_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_crypto_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/crypto/proto/crypto.pb.micro.go b/crypto/proto/crypto.pb.micro.go index ebd677f..27d5177 100644 --- a/crypto/proto/crypto.pb.micro.go +++ b/crypto/proto/crypto.pb.micro.go @@ -46,6 +46,7 @@ type CryptoService interface { Quote(ctx context.Context, in *QuoteRequest, opts ...client.CallOption) (*QuoteResponse, error) Price(ctx context.Context, in *PriceRequest, opts ...client.CallOption) (*PriceResponse, error) History(ctx context.Context, in *HistoryRequest, opts ...client.CallOption) (*HistoryResponse, error) + Symbols(ctx context.Context, in *SymbolsRequest, opts ...client.CallOption) (*SymbolsResponse, error) } type cryptoService struct { @@ -100,6 +101,16 @@ func (c *cryptoService) History(ctx context.Context, in *HistoryRequest, opts .. return out, nil } +func (c *cryptoService) Symbols(ctx context.Context, in *SymbolsRequest, opts ...client.CallOption) (*SymbolsResponse, error) { + req := c.c.NewRequest(c.name, "Crypto.Symbols", in) + out := new(SymbolsResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Crypto service type CryptoHandler interface { @@ -107,6 +118,7 @@ type CryptoHandler interface { Quote(context.Context, *QuoteRequest, *QuoteResponse) error Price(context.Context, *PriceRequest, *PriceResponse) error History(context.Context, *HistoryRequest, *HistoryResponse) error + Symbols(context.Context, *SymbolsRequest, *SymbolsResponse) error } func RegisterCryptoHandler(s server.Server, hdlr CryptoHandler, opts ...server.HandlerOption) error { @@ -115,6 +127,7 @@ func RegisterCryptoHandler(s server.Server, hdlr CryptoHandler, opts ...server.H Quote(ctx context.Context, in *QuoteRequest, out *QuoteResponse) error Price(ctx context.Context, in *PriceRequest, out *PriceResponse) error History(ctx context.Context, in *HistoryRequest, out *HistoryResponse) error + Symbols(ctx context.Context, in *SymbolsRequest, out *SymbolsResponse) error } type Crypto struct { crypto @@ -142,3 +155,7 @@ func (h *cryptoHandler) Price(ctx context.Context, in *PriceRequest, out *PriceR func (h *cryptoHandler) History(ctx context.Context, in *HistoryRequest, out *HistoryResponse) error { return h.CryptoHandler.History(ctx, in, out) } + +func (h *cryptoHandler) Symbols(ctx context.Context, in *SymbolsRequest, out *SymbolsResponse) error { + return h.CryptoHandler.Symbols(ctx, in, out) +} diff --git a/crypto/proto/crypto.proto b/crypto/proto/crypto.proto index 9c7a98a..765acdf 100644 --- a/crypto/proto/crypto.proto +++ b/crypto/proto/crypto.proto @@ -9,6 +9,7 @@ service Crypto { rpc Quote(QuoteRequest) returns (QuoteResponse) {} rpc Price(PriceRequest) returns (PriceResponse) {} rpc History(HistoryRequest) returns (HistoryResponse) {} + rpc Symbols(SymbolsRequest) returns (SymbolsResponse) {} } message Article { @@ -94,3 +95,15 @@ message HistoryResponse { // the date string date = 7; } + +// Returns the full list of supported symbols +message SymbolsRequest {} + +message SymbolsResponse { + repeated Symbol symbols = 1; +} + +message Symbol { + string symbol = 1; + string name = 2; +} diff --git a/go.sum b/go.sum index 055dbbf..6ec8ef6 100644 --- a/go.sum +++ b/go.sum @@ -500,10 +500,6 @@ github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KK github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/micro/micro/v3 v3.9.1-0.20220216155053-3f60fc42a827 h1:ri67oBlQBVidHb99aNQFZBsBS5qUNGdUGo1+c0/g9ss= -github.com/micro/micro/v3 v3.9.1-0.20220216155053-3f60fc42a827/go.mod h1:fNx55Nv50LZMgd5Prytro1ZNwXphvVID78R6KJ+xLbQ= -github.com/micro/micro/v3 v3.9.1-0.20220227215143-9815babcb910 h1:xTmlxomMDG3WHSgU5oqO72n9svGJKGimBjoIiZKLswo= -github.com/micro/micro/v3 v3.9.1-0.20220227215143-9815babcb910/go.mod h1:fNx55Nv50LZMgd5Prytro1ZNwXphvVID78R6KJ+xLbQ= github.com/micro/micro/v3 v3.9.1-0.20220227222118-3d0aa50678fe h1:FtAWgT+YjqDg+pdgj1wAgGDi5YTJpBMLE1Chm/H3gi4= github.com/micro/micro/v3 v3.9.1-0.20220227222118-3d0aa50678fe/go.mod h1:fNx55Nv50LZMgd5Prytro1ZNwXphvVID78R6KJ+xLbQ= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=