From 554eaeb4061b42e318fcf137a9343eec1b1e51ae Mon Sep 17 00:00:00 2001 From: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:28:01 +0100 Subject: [PATCH] Add explorer-like endpoint to retrieve spendable vtxos for address (#37) * Add GetSpendableVtxosWithId to repo * Add endpoint to retrieve spendable vtxos --- .../swagger/ark/v1/service.swagger.json | 55 +++ asp/api-spec/protobuf/ark/v1/service.proto | 19 + .../protobuf/gen/ark/v1/service.pb.go | 379 ++++++++++++++---- .../protobuf/gen/ark/v1/service.pb.gw.go | 99 +++++ .../protobuf/gen/ark/v1/service_grpc.pb.go | 36 ++ asp/internal/core/application/service.go | 5 + asp/internal/core/domain/round_repo.go | 1 + .../infrastructure/db/badger/vtxo_repo.go | 21 + .../infrastructure/db/service_test.go | 14 +- .../interface/grpc/handlers/arkservice.go | 36 ++ 10 files changed, 585 insertions(+), 80 deletions(-) diff --git a/asp/api-spec/openapi/swagger/ark/v1/service.swagger.json b/asp/api-spec/openapi/swagger/ark/v1/service.swagger.json index 9225d53..be496d2 100644 --- a/asp/api-spec/openapi/swagger/ark/v1/service.swagger.json +++ b/asp/api-spec/openapi/swagger/ark/v1/service.swagger.json @@ -232,6 +232,36 @@ "ArkService" ] } + }, + "/v1/vtxos/{address}": { + "get": { + "operationId": "ArkService_ListVtxos", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListVtxosResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "address", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "ArkService" + ] + } } }, "definitions": { @@ -333,6 +363,17 @@ } } }, + "v1ListVtxosResponse": { + "type": "object", + "properties": { + "vtxos": { + "type": "array", + "items": { + "$ref": "#/definitions/v1Vtxo" + } + } + } + }, "v1Output": { "type": "object", "properties": { @@ -437,6 +478,20 @@ "type": "string" } } + }, + "v1Vtxo": { + "type": "object", + "properties": { + "outpoint": { + "$ref": "#/definitions/v1Input" + }, + "receiver": { + "$ref": "#/definitions/v1Output" + }, + "spent": { + "type": "boolean" + } + } } } } diff --git a/asp/api-spec/protobuf/ark/v1/service.proto b/asp/api-spec/protobuf/ark/v1/service.proto index cfe8901..76ffedb 100755 --- a/asp/api-spec/protobuf/ark/v1/service.proto +++ b/asp/api-spec/protobuf/ark/v1/service.proto @@ -43,6 +43,11 @@ service ArkService { post: "/v1/faucet/{address}" }; } + rpc ListVtxos(ListVtxosRequest) returns (ListVtxosResponse) { + option (google.api.http) = { + get: "/v1/vtxos/{address}" + }; + } } message RegisterPaymentRequest { @@ -131,3 +136,17 @@ message FaucetRequest { message FaucetResponse {} +message ListVtxosRequest { + string address = 1; +} + +message ListVtxosResponse { + repeated Vtxo vtxos = 1; +} + +message Vtxo { + Input outpoint = 1; + Output receiver = 2; + bool spent = 3; +} + diff --git a/asp/api-spec/protobuf/gen/ark/v1/service.pb.go b/asp/api-spec/protobuf/gen/ark/v1/service.pb.go index 6047b58..de5f15f 100644 --- a/asp/api-spec/protobuf/gen/ark/v1/service.pb.go +++ b/asp/api-spec/protobuf/gen/ark/v1/service.pb.go @@ -1063,6 +1063,163 @@ func (*FaucetResponse) Descriptor() ([]byte, []int) { return file_ark_v1_service_proto_rawDescGZIP(), []int{19} } +type ListVtxosRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *ListVtxosRequest) Reset() { + *x = ListVtxosRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVtxosRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVtxosRequest) ProtoMessage() {} + +func (x *ListVtxosRequest) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_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 ListVtxosRequest.ProtoReflect.Descriptor instead. +func (*ListVtxosRequest) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{20} +} + +func (x *ListVtxosRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type ListVtxosResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vtxos []*Vtxo `protobuf:"bytes,1,rep,name=vtxos,proto3" json:"vtxos,omitempty"` +} + +func (x *ListVtxosResponse) Reset() { + *x = ListVtxosResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVtxosResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVtxosResponse) ProtoMessage() {} + +func (x *ListVtxosResponse) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_service_proto_msgTypes[21] + 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 ListVtxosResponse.ProtoReflect.Descriptor instead. +func (*ListVtxosResponse) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{21} +} + +func (x *ListVtxosResponse) GetVtxos() []*Vtxo { + if x != nil { + return x.Vtxos + } + return nil +} + +type Vtxo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Outpoint *Input `protobuf:"bytes,1,opt,name=outpoint,proto3" json:"outpoint,omitempty"` + Receiver *Output `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"` + Spent bool `protobuf:"varint,3,opt,name=spent,proto3" json:"spent,omitempty"` +} + +func (x *Vtxo) Reset() { + *x = Vtxo{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Vtxo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Vtxo) ProtoMessage() {} + +func (x *Vtxo) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_service_proto_msgTypes[22] + 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 Vtxo.ProtoReflect.Descriptor instead. +func (*Vtxo) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{22} +} + +func (x *Vtxo) GetOutpoint() *Input { + if x != nil { + return x.Outpoint + } + return nil +} + +func (x *Vtxo) GetReceiver() *Output { + if x != nil { + return x.Receiver + } + return nil +} + +func (x *Vtxo) GetSpent() bool { + if x != nil { + return x.Spent + } + return false +} + var File_ark_v1_service_proto protoreflect.FileDescriptor var file_ark_v1_service_proto_rawDesc = []byte{ @@ -1158,62 +1315,82 @@ var file_ark_v1_service_proto_rawDesc = []byte{ 0x73, 0x65, 0x22, 0x29, 0x0a, 0x0d, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 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, 0x10, 0x0a, - 0x0e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, - 0xc8, 0x05, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, - 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, - 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, - 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x73, 0x0a, 0x0f, - 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, - 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, - 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x17, 0x2e, - 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, - 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x65, 0x0a, 0x0e, 0x47, 0x65, - 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e, 0x61, - 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x72, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, - 0x01, 0x12, 0x50, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, - 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x55, 0x0a, 0x06, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x12, 0x15, 0x2e, - 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x61, - 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, - 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, - 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, - 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2c, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 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, 0x37, 0x0a, + 0x11, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x22, 0x0a, 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52, + 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x73, 0x0a, 0x04, 0x56, 0x74, 0x78, 0x6f, 0x12, 0x29, + 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, + 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x72, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x32, 0xa7, 0x06, 0x0a, 0x0a, + 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0f, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, + 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, + 0x67, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, + 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x73, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x57, 0x0a, + 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, + 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x65, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, + 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01, 0x12, 0x50, 0x0a, + 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, + 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, + 0x55, 0x0a, 0x06, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x12, 0x15, 0x2e, 0x61, 0x72, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, + 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x61, 0x75, 0x63, 0x65, 0x74, 0x2f, 0x7b, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x5d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, + 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, + 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x7d, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, + 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x61, 0x72, 0x6b, + 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x72, + 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x72, + 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1228,7 +1405,7 @@ func file_ark_v1_service_proto_rawDescGZIP() []byte { return file_ark_v1_service_proto_rawDescData } -var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_ark_v1_service_proto_goTypes = []interface{}{ (*RegisterPaymentRequest)(nil), // 0: ark.v1.RegisterPaymentRequest (*RegisterPaymentResponse)(nil), // 1: ark.v1.RegisterPaymentResponse @@ -1250,35 +1427,43 @@ var file_ark_v1_service_proto_goTypes = []interface{}{ (*PingResponse)(nil), // 17: ark.v1.PingResponse (*FaucetRequest)(nil), // 18: ark.v1.FaucetRequest (*FaucetResponse)(nil), // 19: ark.v1.FaucetResponse - nil, // 20: ark.v1.RoundFinalizationEvent.ForfeitTxsEntry + (*ListVtxosRequest)(nil), // 20: ark.v1.ListVtxosRequest + (*ListVtxosResponse)(nil), // 21: ark.v1.ListVtxosResponse + (*Vtxo)(nil), // 22: ark.v1.Vtxo + nil, // 23: ark.v1.RoundFinalizationEvent.ForfeitTxsEntry } var file_ark_v1_service_proto_depIdxs = []int32{ 9, // 0: ark.v1.RegisterPaymentRequest.inputs:type_name -> ark.v1.Input 10, // 1: ark.v1.ClaimPaymentRequest.outputs:type_name -> ark.v1.Output 8, // 2: ark.v1.GetRoundResponse.round:type_name -> ark.v1.Round - 20, // 3: ark.v1.RoundFinalizationEvent.forfeit_txs:type_name -> ark.v1.RoundFinalizationEvent.ForfeitTxsEntry + 23, // 3: ark.v1.RoundFinalizationEvent.forfeit_txs:type_name -> ark.v1.RoundFinalizationEvent.ForfeitTxsEntry 11, // 4: ark.v1.GetEventStreamResponse.round_finalization:type_name -> ark.v1.RoundFinalizationEvent 12, // 5: ark.v1.GetEventStreamResponse.round_finalized:type_name -> ark.v1.RoundFinalizedEvent 13, // 6: ark.v1.GetEventStreamResponse.round_failed:type_name -> ark.v1.RoundFailed - 0, // 7: ark.v1.ArkService.RegisterPayment:input_type -> ark.v1.RegisterPaymentRequest - 2, // 8: ark.v1.ArkService.ClaimPayment:input_type -> ark.v1.ClaimPaymentRequest - 4, // 9: ark.v1.ArkService.FinalizePayment:input_type -> ark.v1.FinalizePaymentRequest - 6, // 10: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest - 14, // 11: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest - 16, // 12: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest - 18, // 13: ark.v1.ArkService.Faucet:input_type -> ark.v1.FaucetRequest - 1, // 14: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse - 3, // 15: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse - 5, // 16: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse - 7, // 17: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse - 15, // 18: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse - 17, // 19: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse - 19, // 20: ark.v1.ArkService.Faucet:output_type -> ark.v1.FaucetResponse - 14, // [14:21] is the sub-list for method output_type - 7, // [7:14] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 22, // 7: ark.v1.ListVtxosResponse.vtxos:type_name -> ark.v1.Vtxo + 9, // 8: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Input + 10, // 9: ark.v1.Vtxo.receiver:type_name -> ark.v1.Output + 0, // 10: ark.v1.ArkService.RegisterPayment:input_type -> ark.v1.RegisterPaymentRequest + 2, // 11: ark.v1.ArkService.ClaimPayment:input_type -> ark.v1.ClaimPaymentRequest + 4, // 12: ark.v1.ArkService.FinalizePayment:input_type -> ark.v1.FinalizePaymentRequest + 6, // 13: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest + 14, // 14: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest + 16, // 15: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest + 18, // 16: ark.v1.ArkService.Faucet:input_type -> ark.v1.FaucetRequest + 20, // 17: ark.v1.ArkService.ListVtxos:input_type -> ark.v1.ListVtxosRequest + 1, // 18: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse + 3, // 19: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse + 5, // 20: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse + 7, // 21: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse + 15, // 22: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse + 17, // 23: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse + 19, // 24: ark.v1.ArkService.Faucet:output_type -> ark.v1.FaucetResponse + 21, // 25: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse + 18, // [18:26] is the sub-list for method output_type + 10, // [10:18] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_ark_v1_service_proto_init() } @@ -1527,6 +1712,42 @@ func file_ark_v1_service_proto_init() { return nil } } + file_ark_v1_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVtxosRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ark_v1_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVtxosResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ark_v1_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Vtxo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_ark_v1_service_proto_msgTypes[15].OneofWrappers = []interface{}{ (*GetEventStreamResponse_RoundFinalization)(nil), @@ -1539,7 +1760,7 @@ func file_ark_v1_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ark_v1_service_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 24, NumExtensions: 0, NumServices: 1, }, diff --git a/asp/api-spec/protobuf/gen/ark/v1/service.pb.gw.go b/asp/api-spec/protobuf/gen/ark/v1/service.pb.gw.go index 14fbbd5..7cc5ec2 100644 --- a/asp/api-spec/protobuf/gen/ark/v1/service.pb.gw.go +++ b/asp/api-spec/protobuf/gen/ark/v1/service.pb.gw.go @@ -306,6 +306,58 @@ func local_request_ArkService_Faucet_0(ctx context.Context, marshaler runtime.Ma } +func request_ArkService_ListVtxos_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListVtxosRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.ListVtxos(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArkService_ListVtxos_0(ctx context.Context, marshaler runtime.Marshaler, server ArkServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListVtxosRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.ListVtxos(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterArkServiceHandlerServer registers the http handlers for service ArkService to "mux". // UnaryRPC :call ArkServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -457,6 +509,29 @@ func RegisterArkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("GET", pattern_ArkService_ListVtxos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.ArkService/ListVtxos", runtime.WithHTTPPathPattern("/v1/vtxos/{address}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArkService_ListVtxos_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_ListVtxos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -638,6 +713,26 @@ func RegisterArkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("GET", pattern_ArkService_ListVtxos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ark.v1.ArkService/ListVtxos", runtime.WithHTTPPathPattern("/v1/vtxos/{address}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArkService_ListVtxos_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_ListVtxos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -655,6 +750,8 @@ var ( pattern_ArkService_Ping_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "ping", "payment_id"}, "")) pattern_ArkService_Faucet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "faucet", "address"}, "")) + + pattern_ArkService_ListVtxos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "vtxos", "address"}, "")) ) var ( @@ -671,4 +768,6 @@ var ( forward_ArkService_Ping_0 = runtime.ForwardResponseMessage forward_ArkService_Faucet_0 = runtime.ForwardResponseMessage + + forward_ArkService_ListVtxos_0 = runtime.ForwardResponseMessage ) diff --git a/asp/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go b/asp/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go index 406443b..2117469 100644 --- a/asp/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go +++ b/asp/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go @@ -25,6 +25,7 @@ type ArkServiceClient interface { GetEventStream(ctx context.Context, in *GetEventStreamRequest, opts ...grpc.CallOption) (ArkService_GetEventStreamClient, error) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) Faucet(ctx context.Context, in *FaucetRequest, opts ...grpc.CallOption) (*FaucetResponse, error) + ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) } type arkServiceClient struct { @@ -121,6 +122,15 @@ func (c *arkServiceClient) Faucet(ctx context.Context, in *FaucetRequest, opts . return out, nil } +func (c *arkServiceClient) ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) { + out := new(ListVtxosResponse) + err := c.cc.Invoke(ctx, "/ark.v1.ArkService/ListVtxos", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ArkServiceServer is the server API for ArkService service. // All implementations should embed UnimplementedArkServiceServer // for forward compatibility @@ -132,6 +142,7 @@ type ArkServiceServer interface { GetEventStream(*GetEventStreamRequest, ArkService_GetEventStreamServer) error Ping(context.Context, *PingRequest) (*PingResponse, error) Faucet(context.Context, *FaucetRequest) (*FaucetResponse, error) + ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) } // UnimplementedArkServiceServer should be embedded to have forward compatible implementations. @@ -159,6 +170,9 @@ func (UnimplementedArkServiceServer) Ping(context.Context, *PingRequest) (*PingR func (UnimplementedArkServiceServer) Faucet(context.Context, *FaucetRequest) (*FaucetResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Faucet not implemented") } +func (UnimplementedArkServiceServer) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVtxos not implemented") +} // UnsafeArkServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ArkServiceServer will @@ -300,6 +314,24 @@ func _ArkService_Faucet_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _ArkService_ListVtxos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListVtxosRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArkServiceServer).ListVtxos(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ark.v1.ArkService/ListVtxos", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArkServiceServer).ListVtxos(ctx, req.(*ListVtxosRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ArkService_ServiceDesc is the grpc.ServiceDesc for ArkService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -331,6 +363,10 @@ var ArkService_ServiceDesc = grpc.ServiceDesc{ MethodName: "Faucet", Handler: _ArkService_Faucet_Handler, }, + { + MethodName: "ListVtxos", + Handler: _ArkService_ListVtxos_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/asp/internal/core/application/service.go b/asp/internal/core/application/service.go index 268db82..33263e6 100644 --- a/asp/internal/core/application/service.go +++ b/asp/internal/core/application/service.go @@ -36,6 +36,7 @@ type Service interface { GetRoundByTxid(ctx context.Context, poolTxid string) (*domain.Round, error) GetEventsChannel(ctx context.Context) <-chan domain.RoundEvent UpdatePaymentStatus(ctx context.Context, id string) error + ListVtxos(ctx context.Context, pubkey string) ([]domain.Vtxo, error) } type service struct { @@ -158,6 +159,10 @@ func (s *service) SignVtxos(ctx context.Context, forfeitTxs []string) error { return nil } +func (s *service) ListVtxos(ctx context.Context, pubkey string) ([]domain.Vtxo, error) { + return s.repoManager.Vtxos().GetSpendableVtxosWithPubkey(ctx, pubkey) +} + func (s *service) GetEventsChannel(ctx context.Context) <-chan domain.RoundEvent { return s.eventsCh } diff --git a/asp/internal/core/domain/round_repo.go b/asp/internal/core/domain/round_repo.go index 5b82322..cd05c05 100644 --- a/asp/internal/core/domain/round_repo.go +++ b/asp/internal/core/domain/round_repo.go @@ -18,4 +18,5 @@ type VtxoRepository interface { AddVtxos(ctx context.Context, vtxos []Vtxo) error SpendVtxos(ctx context.Context, vtxos []VtxoKey) error GetVtxos(ctx context.Context, vtxos []VtxoKey) ([]Vtxo, error) + GetSpendableVtxosWithPubkey(ctx context.Context, pubkey string) ([]Vtxo, error) } diff --git a/asp/internal/infrastructure/db/badger/vtxo_repo.go b/asp/internal/infrastructure/db/badger/vtxo_repo.go index 312ab3f..0b14fed 100644 --- a/asp/internal/infrastructure/db/badger/vtxo_repo.go +++ b/asp/internal/infrastructure/db/badger/vtxo_repo.go @@ -74,6 +74,13 @@ func (r *vtxoRepository) GetVtxos( return vtxos, nil } +func (r *vtxoRepository) GetSpendableVtxosWithPubkey( + ctx context.Context, pubkey string, +) ([]domain.Vtxo, error) { + query := badgerhold.Where("Pubkey").Eq(pubkey).And("Spent").Eq(false) + return r.findVtxos(ctx, query) +} + func (r *vtxoRepository) Close() { r.store.Close() } @@ -132,3 +139,17 @@ func (r *vtxoRepository) spendVtxo(ctx context.Context, vtxoKey domain.VtxoKey) } return err } + +func (r *vtxoRepository) findVtxos(ctx context.Context, query *badgerhold.Query) ([]domain.Vtxo, error) { + var vtxos []domain.Vtxo + var err error + + if ctx.Value("tx") != nil { + tx := ctx.Value("tx").(*badger.Txn) + err = r.store.TxFind(tx, &vtxos, query) + } else { + err = r.store.Find(&vtxos, query) + } + + return vtxos, err +} diff --git a/asp/internal/infrastructure/db/service_test.go b/asp/internal/infrastructure/db/service_test.go index 2a7cbf7..467c61c 100644 --- a/asp/internal/infrastructure/db/service_test.go +++ b/asp/internal/infrastructure/db/service_test.go @@ -280,12 +280,20 @@ func testVtxoRepository(t *testing.T, svc ports.RepoManager) { require.Error(t, err) require.Empty(t, vtxos) + spendableVtxos, err := svc.Vtxos().GetSpendableVtxosWithPubkey(ctx, pubkey) + require.NoError(t, err) + require.Empty(t, spendableVtxos) + err = svc.Vtxos().AddVtxos(ctx, newVtxos) require.NoError(t, err) vtxos, err = svc.Vtxos().GetVtxos(ctx, vtxoKeys) require.NoError(t, err) - require.Exactly(t, newVtxos, vtxos) + require.Exactly(t, vtxos, newVtxos) + + spendableVtxos, err = svc.Vtxos().GetSpendableVtxosWithPubkey(ctx, pubkey) + require.NoError(t, err) + require.Exactly(t, vtxos, spendableVtxos) err = svc.Vtxos().SpendVtxos(ctx, vtxoKeys[:1]) require.NoError(t, err) @@ -296,6 +304,10 @@ func testVtxoRepository(t *testing.T, svc ports.RepoManager) { for _, v := range spentVtxos { require.True(t, v.Spent) } + + spendableVtxos, err = svc.Vtxos().GetSpendableVtxosWithPubkey(ctx, pubkey) + require.NoError(t, err) + require.Exactly(t, vtxos[1:], spendableVtxos) }) } diff --git a/asp/internal/interface/grpc/handlers/arkservice.go b/asp/internal/interface/grpc/handlers/arkservice.go index 762b579..b044d15 100644 --- a/asp/internal/interface/grpc/handlers/arkservice.go +++ b/asp/internal/interface/grpc/handlers/arkservice.go @@ -160,6 +160,22 @@ func (h *handler) GetEventStream(_ *arkv1.GetEventStreamRequest, stream arkv1.Ar } } +func (h *handler) ListVtxos(ctx context.Context, req *arkv1.ListVtxosRequest) (*arkv1.ListVtxosResponse, error) { + pubkey, err := parseAddress(req.GetAddress()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + vtxos, err := h.svc.ListVtxos(ctx, pubkey) + if err != nil { + return nil, err + } + + return &arkv1.ListVtxosResponse{ + Vtxos: vtxoList(vtxos).toProto(), + }, nil +} + func (h *handler) pushListener(l *listener) { h.listenersLock.Lock() defer h.listenersLock.Unlock() @@ -224,3 +240,23 @@ func (h *handler) listenToEvents() { } } } + +type vtxoList []domain.Vtxo + +func (v vtxoList) toProto() []*arkv1.Vtxo { + list := make([]*arkv1.Vtxo, 0, len(v)) + for _, vv := range v { + list = append(list, &arkv1.Vtxo{ + Outpoint: &arkv1.Input{ + Txid: vv.Txid, + Vout: vv.VOut, + }, + Receiver: &arkv1.Output{ + Pubkey: vv.Pubkey, + Amount: vv.Amount, + }, + Spent: vv.Spent, + }) + } + return list +}