From 740d4fb7b1ea518a96d3ea01ece99854211d71c9 Mon Sep 17 00:00:00 2001 From: Louis Singer <41042567+louisinger@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:54:27 +0200 Subject: [PATCH] Add `TrustedOnboarding` RPC (#138) * add CreateOnboardingAddress rpc * add TrustedOnboarding rpc * remove log.Info in notifications.go --- client/onboard.go | 45 +- .../swagger/ark/v1/service.swagger.json | 56 ++ server/api-spec/protobuf/ark/v1/service.proto | 15 + .../protobuf/gen/ark/v1/service.pb.go | 587 +++++++++++------- .../protobuf/gen/ark/v1/service.pb.gw.go | 77 +++ .../protobuf/gen/ark/v1/service_grpc.pb.go | 36 ++ server/internal/core/application/service.go | 125 +++- server/internal/core/ports/scanner.go | 7 +- .../ocean-wallet/notification.go | 4 +- .../infrastructure/ocean-wallet/service.go | 22 +- .../interface/grpc/handlers/arkservice.go | 35 ++ 11 files changed, 760 insertions(+), 249 deletions(-) diff --git a/client/onboard.go b/client/onboard.go index c1862c1..d0deacc 100644 --- a/client/onboard.go +++ b/client/onboard.go @@ -21,16 +21,22 @@ var ( Usage: "amount to onboard in sats", Required: true, } + trustedOnboardFlag = cli.BoolFlag{ + Name: "trusted", + Usage: "trusted onboard", + } ) var onboardCommand = cli.Command{ Name: "onboard", Usage: "Onboard the Ark by lifting your funds", Action: onboardAction, - Flags: []cli.Flag{&amountOnboardFlag, &passwordFlag}, + Flags: []cli.Flag{&amountOnboardFlag, &trustedOnboardFlag, &passwordFlag}, } func onboardAction(ctx *cli.Context) error { + isTrusted := ctx.Bool("trusted") + amount := ctx.Uint64("amount") if amount <= 0 { @@ -39,6 +45,32 @@ func onboardAction(ctx *cli.Context) error { _, net := getNetwork() + userPubKey, err := getWalletPublicKey() + if err != nil { + return err + } + + client, cancel, err := getClientFromState() + if err != nil { + return err + } + defer cancel() + + if isTrusted { + resp, err := client.TrustedOnboarding(ctx.Context, &arkv1.TrustedOnboardingRequest{ + UserPubkey: hex.EncodeToString(userPubKey.SerializeCompressed()), + Amount: amount, + }) + if err != nil { + return err + } + + fmt.Println("onboard_address :", resp.Address) + fmt.Println("onboard_amount :", resp.ExpectedAmount) + + return nil + } + aspPubkey, err := getAspPublicKey() if err != nil { return err @@ -54,11 +86,6 @@ func onboardAction(ctx *cli.Context) error { return err } - userPubKey, err := getWalletPublicKey() - if err != nil { - return err - } - congestionTreeLeaf := tree.Receiver{ Pubkey: hex.EncodeToString(userPubKey.SerializeCompressed()), Amount: amount, @@ -105,12 +132,6 @@ func onboardAction(ctx *cli.Context) error { return err } - client, cancel, err := getClientFromState() - if err != nil { - return err - } - defer cancel() - _, err = client.Onboard(ctx.Context, &arkv1.OnboardRequest{ BoardingTx: pset, CongestionTree: castCongestionTree(congestionTree), diff --git a/server/api-spec/openapi/swagger/ark/v1/service.swagger.json b/server/api-spec/openapi/swagger/ark/v1/service.swagger.json index 3bc666c..4574816 100644 --- a/server/api-spec/openapi/swagger/ark/v1/service.swagger.json +++ b/server/api-spec/openapi/swagger/ark/v1/service.swagger.json @@ -101,6 +101,38 @@ ] } }, + "/v1/onboard/address": { + "post": { + "operationId": "ArkService_TrustedOnboarding", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1TrustedOnboardingResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1TrustedOnboardingRequest" + } + } + ], + "tags": [ + "ArkService" + ] + } + }, "/v1/payment/claim": { "post": { "operationId": "ArkService_ClaimPayment", @@ -577,6 +609,30 @@ } } }, + "v1TrustedOnboardingRequest": { + "type": "object", + "properties": { + "userPubkey": { + "type": "string" + }, + "amount": { + "type": "string", + "format": "uint64" + } + } + }, + "v1TrustedOnboardingResponse": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "expectedAmount": { + "type": "string", + "format": "uint64" + } + } + }, "v1Vtxo": { "type": "object", "properties": { diff --git a/server/api-spec/protobuf/ark/v1/service.proto b/server/api-spec/protobuf/ark/v1/service.proto index b1391e4..95be301 100755 --- a/server/api-spec/protobuf/ark/v1/service.proto +++ b/server/api-spec/protobuf/ark/v1/service.proto @@ -54,6 +54,12 @@ service ArkService { body: "*" }; } + rpc TrustedOnboarding(TrustedOnboardingRequest) returns (TrustedOnboardingResponse) { + option (google.api.http) = { + post: "/v1/onboard/address" + body: "*" + }; + } } message RegisterPaymentRequest { @@ -121,6 +127,15 @@ message OnboardRequest { message OnboardResponse { } +message TrustedOnboardingRequest { + string user_pubkey = 1; + uint64 amount = 2; +} +message TrustedOnboardingResponse { + string address = 1; + uint64 expected_amount = 2; +} + // EVENT TYPES message RoundFinalizationEvent { diff --git a/server/api-spec/protobuf/gen/ark/v1/service.pb.go b/server/api-spec/protobuf/gen/ark/v1/service.pb.go index 44fdf4f..75dc335 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service.pb.go +++ b/server/api-spec/protobuf/gen/ark/v1/service.pb.go @@ -905,6 +905,116 @@ func (*OnboardResponse) Descriptor() ([]byte, []int) { return file_ark_v1_service_proto_rawDescGZIP(), []int{17} } +type TrustedOnboardingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserPubkey string `protobuf:"bytes,1,opt,name=user_pubkey,json=userPubkey,proto3" json:"user_pubkey,omitempty"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (x *TrustedOnboardingRequest) Reset() { + *x = TrustedOnboardingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrustedOnboardingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrustedOnboardingRequest) ProtoMessage() {} + +func (x *TrustedOnboardingRequest) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_service_proto_msgTypes[18] + 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 TrustedOnboardingRequest.ProtoReflect.Descriptor instead. +func (*TrustedOnboardingRequest) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{18} +} + +func (x *TrustedOnboardingRequest) GetUserPubkey() string { + if x != nil { + return x.UserPubkey + } + return "" +} + +func (x *TrustedOnboardingRequest) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +type TrustedOnboardingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + ExpectedAmount uint64 `protobuf:"varint,2,opt,name=expected_amount,json=expectedAmount,proto3" json:"expected_amount,omitempty"` +} + +func (x *TrustedOnboardingResponse) Reset() { + *x = TrustedOnboardingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrustedOnboardingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrustedOnboardingResponse) ProtoMessage() {} + +func (x *TrustedOnboardingResponse) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_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 TrustedOnboardingResponse.ProtoReflect.Descriptor instead. +func (*TrustedOnboardingResponse) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{19} +} + +func (x *TrustedOnboardingResponse) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *TrustedOnboardingResponse) GetExpectedAmount() uint64 { + if x != nil { + return x.ExpectedAmount + } + return 0 +} + type RoundFinalizationEvent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -920,7 +1030,7 @@ type RoundFinalizationEvent struct { func (x *RoundFinalizationEvent) Reset() { *x = RoundFinalizationEvent{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[18] + mi := &file_ark_v1_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -933,7 +1043,7 @@ func (x *RoundFinalizationEvent) String() string { func (*RoundFinalizationEvent) ProtoMessage() {} func (x *RoundFinalizationEvent) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[18] + mi := &file_ark_v1_service_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -946,7 +1056,7 @@ func (x *RoundFinalizationEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFinalizationEvent.ProtoReflect.Descriptor instead. func (*RoundFinalizationEvent) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{18} + return file_ark_v1_service_proto_rawDescGZIP(), []int{20} } func (x *RoundFinalizationEvent) GetId() string { @@ -996,7 +1106,7 @@ type RoundFinalizedEvent struct { func (x *RoundFinalizedEvent) Reset() { *x = RoundFinalizedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[19] + mi := &file_ark_v1_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1009,7 +1119,7 @@ func (x *RoundFinalizedEvent) String() string { func (*RoundFinalizedEvent) ProtoMessage() {} func (x *RoundFinalizedEvent) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[19] + mi := &file_ark_v1_service_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1022,7 +1132,7 @@ func (x *RoundFinalizedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFinalizedEvent.ProtoReflect.Descriptor instead. func (*RoundFinalizedEvent) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{19} + return file_ark_v1_service_proto_rawDescGZIP(), []int{21} } func (x *RoundFinalizedEvent) GetId() string { @@ -1051,7 +1161,7 @@ type RoundFailed struct { func (x *RoundFailed) Reset() { *x = RoundFailed{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[20] + mi := &file_ark_v1_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1064,7 +1174,7 @@ func (x *RoundFailed) String() string { func (*RoundFailed) ProtoMessage() {} func (x *RoundFailed) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[20] + mi := &file_ark_v1_service_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1077,7 +1187,7 @@ func (x *RoundFailed) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFailed.ProtoReflect.Descriptor instead. func (*RoundFailed) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{20} + return file_ark_v1_service_proto_rawDescGZIP(), []int{22} } func (x *RoundFailed) GetId() string { @@ -1109,7 +1219,7 @@ type Round struct { func (x *Round) Reset() { *x = Round{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[21] + mi := &file_ark_v1_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1232,7 @@ func (x *Round) String() string { func (*Round) ProtoMessage() {} func (x *Round) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[21] + mi := &file_ark_v1_service_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,7 +1245,7 @@ func (x *Round) ProtoReflect() protoreflect.Message { // Deprecated: Use Round.ProtoReflect.Descriptor instead. func (*Round) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{21} + return file_ark_v1_service_proto_rawDescGZIP(), []int{23} } func (x *Round) GetId() string { @@ -1185,7 +1295,7 @@ type Input struct { func (x *Input) Reset() { *x = Input{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[22] + mi := &file_ark_v1_service_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1198,7 +1308,7 @@ func (x *Input) String() string { func (*Input) ProtoMessage() {} func (x *Input) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[22] + mi := &file_ark_v1_service_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1211,7 +1321,7 @@ func (x *Input) ProtoReflect() protoreflect.Message { // Deprecated: Use Input.ProtoReflect.Descriptor instead. func (*Input) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{22} + return file_ark_v1_service_proto_rawDescGZIP(), []int{24} } func (x *Input) GetTxid() string { @@ -1242,7 +1352,7 @@ type Output struct { func (x *Output) Reset() { *x = Output{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[23] + mi := &file_ark_v1_service_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1255,7 +1365,7 @@ func (x *Output) String() string { func (*Output) ProtoMessage() {} func (x *Output) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[23] + mi := &file_ark_v1_service_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1268,7 +1378,7 @@ func (x *Output) ProtoReflect() protoreflect.Message { // Deprecated: Use Output.ProtoReflect.Descriptor instead. func (*Output) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{23} + return file_ark_v1_service_proto_rawDescGZIP(), []int{25} } func (x *Output) GetAddress() string { @@ -1296,7 +1406,7 @@ type Tree struct { func (x *Tree) Reset() { *x = Tree{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[24] + mi := &file_ark_v1_service_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1309,7 +1419,7 @@ func (x *Tree) String() string { func (*Tree) ProtoMessage() {} func (x *Tree) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[24] + mi := &file_ark_v1_service_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1322,7 +1432,7 @@ func (x *Tree) ProtoReflect() protoreflect.Message { // Deprecated: Use Tree.ProtoReflect.Descriptor instead. func (*Tree) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{24} + return file_ark_v1_service_proto_rawDescGZIP(), []int{26} } func (x *Tree) GetLevels() []*TreeLevel { @@ -1343,7 +1453,7 @@ type TreeLevel struct { func (x *TreeLevel) Reset() { *x = TreeLevel{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[25] + mi := &file_ark_v1_service_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1356,7 +1466,7 @@ func (x *TreeLevel) String() string { func (*TreeLevel) ProtoMessage() {} func (x *TreeLevel) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[25] + mi := &file_ark_v1_service_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1369,7 +1479,7 @@ func (x *TreeLevel) ProtoReflect() protoreflect.Message { // Deprecated: Use TreeLevel.ProtoReflect.Descriptor instead. func (*TreeLevel) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{25} + return file_ark_v1_service_proto_rawDescGZIP(), []int{27} } func (x *TreeLevel) GetNodes() []*Node { @@ -1392,7 +1502,7 @@ type Node struct { func (x *Node) Reset() { *x = Node{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[26] + mi := &file_ark_v1_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1405,7 +1515,7 @@ func (x *Node) String() string { func (*Node) ProtoMessage() {} func (x *Node) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[26] + mi := &file_ark_v1_service_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1418,7 +1528,7 @@ func (x *Node) ProtoReflect() protoreflect.Message { // Deprecated: Use Node.ProtoReflect.Descriptor instead. func (*Node) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{26} + return file_ark_v1_service_proto_rawDescGZIP(), []int{28} } func (x *Node) GetTxid() string { @@ -1456,7 +1566,7 @@ type Vtxo struct { func (x *Vtxo) Reset() { *x = Vtxo{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[27] + mi := &file_ark_v1_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1469,7 +1579,7 @@ func (x *Vtxo) String() string { func (*Vtxo) ProtoMessage() {} func (x *Vtxo) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[27] + mi := &file_ark_v1_service_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1482,7 +1592,7 @@ func (x *Vtxo) ProtoReflect() protoreflect.Message { // Deprecated: Use Vtxo.ProtoReflect.Descriptor instead. func (*Vtxo) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{27} + return file_ark_v1_service_proto_rawDescGZIP(), []int{29} } func (x *Vtxo) GetOutpoint() *Input { @@ -1592,127 +1702,146 @@ var file_ark_v1_service_proto_rawDesc = []byte{ 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x11, 0x0a, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xb9, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, - 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, - 0x5f, 0x74, 0x78, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x72, 0x66, - 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, - 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, 0x12, 0x1e, 0x0a, - 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x42, 0x0a, - 0x13, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, - 0x64, 0x22, 0x35, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x8a, 0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, - 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x35, - 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x65, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x72, 0x65, 0x65, 0x22, 0x2f, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x22, 0x3a, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 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, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x31, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x72, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x06, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x73, 0x22, 0x2f, 0x0a, 0x09, 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, - 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, - 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x74, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, - 0x78, 0x69, 0x64, 0x22, 0x90, 0x01, 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, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, - 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, - 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x32, 0xf2, 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, 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, 0x12, 0x4c, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, - 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, - 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x07, 0x4f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, - 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 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, + 0x65, 0x22, 0x53, 0x0a, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x5e, 0x0a, 0x19, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, + 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x6e, 0x64, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, + 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, + 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, + 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, + 0x65, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x22, 0x42, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, + 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, + 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x22, 0x35, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x8a, 0x01, + 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x78, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, + 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, 0x22, 0x2f, 0x0a, 0x05, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x22, 0x3a, 0x0a, 0x06, 0x4f, + 0x75, 0x74, 0x70, 0x75, 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, 0x12, + 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x31, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, 0x12, + 0x29, 0x0a, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x22, 0x2f, 0x0a, 0x09, 0x54, 0x72, + 0x65, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x04, 0x4e, + 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x54, 0x78, 0x69, 0x64, 0x22, 0x90, 0x01, 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, 0x12, 0x1b, + 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x32, 0xec, 0x07, 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, + 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, 0x12, 0x4c, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x07, + 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, + 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x12, 0x78, 0x0a, 0x11, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 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 ( @@ -1727,52 +1856,54 @@ 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, 28) +var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_ark_v1_service_proto_goTypes = []interface{}{ - (*RegisterPaymentRequest)(nil), // 0: ark.v1.RegisterPaymentRequest - (*RegisterPaymentResponse)(nil), // 1: ark.v1.RegisterPaymentResponse - (*ClaimPaymentRequest)(nil), // 2: ark.v1.ClaimPaymentRequest - (*ClaimPaymentResponse)(nil), // 3: ark.v1.ClaimPaymentResponse - (*FinalizePaymentRequest)(nil), // 4: ark.v1.FinalizePaymentRequest - (*FinalizePaymentResponse)(nil), // 5: ark.v1.FinalizePaymentResponse - (*GetRoundRequest)(nil), // 6: ark.v1.GetRoundRequest - (*GetRoundResponse)(nil), // 7: ark.v1.GetRoundResponse - (*GetEventStreamRequest)(nil), // 8: ark.v1.GetEventStreamRequest - (*GetEventStreamResponse)(nil), // 9: ark.v1.GetEventStreamResponse - (*PingRequest)(nil), // 10: ark.v1.PingRequest - (*PingResponse)(nil), // 11: ark.v1.PingResponse - (*ListVtxosRequest)(nil), // 12: ark.v1.ListVtxosRequest - (*ListVtxosResponse)(nil), // 13: ark.v1.ListVtxosResponse - (*GetInfoRequest)(nil), // 14: ark.v1.GetInfoRequest - (*GetInfoResponse)(nil), // 15: ark.v1.GetInfoResponse - (*OnboardRequest)(nil), // 16: ark.v1.OnboardRequest - (*OnboardResponse)(nil), // 17: ark.v1.OnboardResponse - (*RoundFinalizationEvent)(nil), // 18: ark.v1.RoundFinalizationEvent - (*RoundFinalizedEvent)(nil), // 19: ark.v1.RoundFinalizedEvent - (*RoundFailed)(nil), // 20: ark.v1.RoundFailed - (*Round)(nil), // 21: ark.v1.Round - (*Input)(nil), // 22: ark.v1.Input - (*Output)(nil), // 23: ark.v1.Output - (*Tree)(nil), // 24: ark.v1.Tree - (*TreeLevel)(nil), // 25: ark.v1.TreeLevel - (*Node)(nil), // 26: ark.v1.Node - (*Vtxo)(nil), // 27: ark.v1.Vtxo + (*RegisterPaymentRequest)(nil), // 0: ark.v1.RegisterPaymentRequest + (*RegisterPaymentResponse)(nil), // 1: ark.v1.RegisterPaymentResponse + (*ClaimPaymentRequest)(nil), // 2: ark.v1.ClaimPaymentRequest + (*ClaimPaymentResponse)(nil), // 3: ark.v1.ClaimPaymentResponse + (*FinalizePaymentRequest)(nil), // 4: ark.v1.FinalizePaymentRequest + (*FinalizePaymentResponse)(nil), // 5: ark.v1.FinalizePaymentResponse + (*GetRoundRequest)(nil), // 6: ark.v1.GetRoundRequest + (*GetRoundResponse)(nil), // 7: ark.v1.GetRoundResponse + (*GetEventStreamRequest)(nil), // 8: ark.v1.GetEventStreamRequest + (*GetEventStreamResponse)(nil), // 9: ark.v1.GetEventStreamResponse + (*PingRequest)(nil), // 10: ark.v1.PingRequest + (*PingResponse)(nil), // 11: ark.v1.PingResponse + (*ListVtxosRequest)(nil), // 12: ark.v1.ListVtxosRequest + (*ListVtxosResponse)(nil), // 13: ark.v1.ListVtxosResponse + (*GetInfoRequest)(nil), // 14: ark.v1.GetInfoRequest + (*GetInfoResponse)(nil), // 15: ark.v1.GetInfoResponse + (*OnboardRequest)(nil), // 16: ark.v1.OnboardRequest + (*OnboardResponse)(nil), // 17: ark.v1.OnboardResponse + (*TrustedOnboardingRequest)(nil), // 18: ark.v1.TrustedOnboardingRequest + (*TrustedOnboardingResponse)(nil), // 19: ark.v1.TrustedOnboardingResponse + (*RoundFinalizationEvent)(nil), // 20: ark.v1.RoundFinalizationEvent + (*RoundFinalizedEvent)(nil), // 21: ark.v1.RoundFinalizedEvent + (*RoundFailed)(nil), // 22: ark.v1.RoundFailed + (*Round)(nil), // 23: ark.v1.Round + (*Input)(nil), // 24: ark.v1.Input + (*Output)(nil), // 25: ark.v1.Output + (*Tree)(nil), // 26: ark.v1.Tree + (*TreeLevel)(nil), // 27: ark.v1.TreeLevel + (*Node)(nil), // 28: ark.v1.Node + (*Vtxo)(nil), // 29: ark.v1.Vtxo } var file_ark_v1_service_proto_depIdxs = []int32{ - 22, // 0: ark.v1.RegisterPaymentRequest.inputs:type_name -> ark.v1.Input - 23, // 1: ark.v1.ClaimPaymentRequest.outputs:type_name -> ark.v1.Output - 21, // 2: ark.v1.GetRoundResponse.round:type_name -> ark.v1.Round - 18, // 3: ark.v1.GetEventStreamResponse.round_finalization:type_name -> ark.v1.RoundFinalizationEvent - 19, // 4: ark.v1.GetEventStreamResponse.round_finalized:type_name -> ark.v1.RoundFinalizedEvent - 20, // 5: ark.v1.GetEventStreamResponse.round_failed:type_name -> ark.v1.RoundFailed - 27, // 6: ark.v1.ListVtxosResponse.vtxos:type_name -> ark.v1.Vtxo - 24, // 7: ark.v1.OnboardRequest.congestion_tree:type_name -> ark.v1.Tree - 24, // 8: ark.v1.RoundFinalizationEvent.congestion_tree:type_name -> ark.v1.Tree - 24, // 9: ark.v1.Round.congestion_tree:type_name -> ark.v1.Tree - 25, // 10: ark.v1.Tree.levels:type_name -> ark.v1.TreeLevel - 26, // 11: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node - 22, // 12: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Input - 23, // 13: ark.v1.Vtxo.receiver:type_name -> ark.v1.Output + 24, // 0: ark.v1.RegisterPaymentRequest.inputs:type_name -> ark.v1.Input + 25, // 1: ark.v1.ClaimPaymentRequest.outputs:type_name -> ark.v1.Output + 23, // 2: ark.v1.GetRoundResponse.round:type_name -> ark.v1.Round + 20, // 3: ark.v1.GetEventStreamResponse.round_finalization:type_name -> ark.v1.RoundFinalizationEvent + 21, // 4: ark.v1.GetEventStreamResponse.round_finalized:type_name -> ark.v1.RoundFinalizedEvent + 22, // 5: ark.v1.GetEventStreamResponse.round_failed:type_name -> ark.v1.RoundFailed + 29, // 6: ark.v1.ListVtxosResponse.vtxos:type_name -> ark.v1.Vtxo + 26, // 7: ark.v1.OnboardRequest.congestion_tree:type_name -> ark.v1.Tree + 26, // 8: ark.v1.RoundFinalizationEvent.congestion_tree:type_name -> ark.v1.Tree + 26, // 9: ark.v1.Round.congestion_tree:type_name -> ark.v1.Tree + 27, // 10: ark.v1.Tree.levels:type_name -> ark.v1.TreeLevel + 28, // 11: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node + 24, // 12: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Input + 25, // 13: ark.v1.Vtxo.receiver:type_name -> ark.v1.Output 0, // 14: ark.v1.ArkService.RegisterPayment:input_type -> ark.v1.RegisterPaymentRequest 2, // 15: ark.v1.ArkService.ClaimPayment:input_type -> ark.v1.ClaimPaymentRequest 4, // 16: ark.v1.ArkService.FinalizePayment:input_type -> ark.v1.FinalizePaymentRequest @@ -1782,17 +1913,19 @@ var file_ark_v1_service_proto_depIdxs = []int32{ 12, // 20: ark.v1.ArkService.ListVtxos:input_type -> ark.v1.ListVtxosRequest 14, // 21: ark.v1.ArkService.GetInfo:input_type -> ark.v1.GetInfoRequest 16, // 22: ark.v1.ArkService.Onboard:input_type -> ark.v1.OnboardRequest - 1, // 23: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse - 3, // 24: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse - 5, // 25: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse - 7, // 26: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse - 9, // 27: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse - 11, // 28: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse - 13, // 29: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse - 15, // 30: ark.v1.ArkService.GetInfo:output_type -> ark.v1.GetInfoResponse - 17, // 31: ark.v1.ArkService.Onboard:output_type -> ark.v1.OnboardResponse - 23, // [23:32] is the sub-list for method output_type - 14, // [14:23] is the sub-list for method input_type + 18, // 23: ark.v1.ArkService.TrustedOnboarding:input_type -> ark.v1.TrustedOnboardingRequest + 1, // 24: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse + 3, // 25: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse + 5, // 26: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse + 7, // 27: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse + 9, // 28: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse + 11, // 29: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse + 13, // 30: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse + 15, // 31: ark.v1.ArkService.GetInfo:output_type -> ark.v1.GetInfoResponse + 17, // 32: ark.v1.ArkService.Onboard:output_type -> ark.v1.OnboardResponse + 19, // 33: ark.v1.ArkService.TrustedOnboarding:output_type -> ark.v1.TrustedOnboardingResponse + 24, // [24:34] is the sub-list for method output_type + 14, // [14:24] is the sub-list for method input_type 14, // [14:14] is the sub-list for extension type_name 14, // [14:14] is the sub-list for extension extendee 0, // [0:14] is the sub-list for field type_name @@ -2021,7 +2154,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFinalizationEvent); i { + switch v := v.(*TrustedOnboardingRequest); i { case 0: return &v.state case 1: @@ -2033,7 +2166,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFinalizedEvent); i { + switch v := v.(*TrustedOnboardingResponse); i { case 0: return &v.state case 1: @@ -2045,7 +2178,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFailed); i { + switch v := v.(*RoundFinalizationEvent); i { case 0: return &v.state case 1: @@ -2057,7 +2190,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Round); i { + switch v := v.(*RoundFinalizedEvent); i { case 0: return &v.state case 1: @@ -2069,7 +2202,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Input); i { + switch v := v.(*RoundFailed); i { case 0: return &v.state case 1: @@ -2081,7 +2214,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Output); i { + switch v := v.(*Round); i { case 0: return &v.state case 1: @@ -2093,7 +2226,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Tree); i { + switch v := v.(*Input); i { case 0: return &v.state case 1: @@ -2105,7 +2238,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TreeLevel); i { + switch v := v.(*Output); i { case 0: return &v.state case 1: @@ -2117,7 +2250,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Node); i { + switch v := v.(*Tree); i { case 0: return &v.state case 1: @@ -2129,6 +2262,30 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TreeLevel); 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[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Node); 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[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Vtxo); i { case 0: return &v.state @@ -2152,7 +2309,7 @@ func file_ark_v1_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ark_v1_service_proto_rawDesc, NumEnums: 0, - NumMessages: 28, + NumMessages: 30, NumExtensions: 0, NumServices: 1, }, diff --git a/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go b/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go index c981689..b78d9d1 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go +++ b/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go @@ -326,6 +326,32 @@ func local_request_ArkService_Onboard_0(ctx context.Context, marshaler runtime.M } +func request_ArkService_TrustedOnboarding_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq TrustedOnboardingRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.TrustedOnboarding(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArkService_TrustedOnboarding_0(ctx context.Context, marshaler runtime.Marshaler, server ArkServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq TrustedOnboardingRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.TrustedOnboarding(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. @@ -539,6 +565,31 @@ func RegisterArkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_ArkService_TrustedOnboarding_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.ArkService/TrustedOnboarding", runtime.WithHTTPPathPattern("/v1/onboard/address")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArkService_TrustedOnboarding_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_TrustedOnboarding_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -778,6 +829,28 @@ func RegisterArkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_ArkService_TrustedOnboarding_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ark.v1.ArkService/TrustedOnboarding", runtime.WithHTTPPathPattern("/v1/onboard/address")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArkService_TrustedOnboarding_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_TrustedOnboarding_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -799,6 +872,8 @@ var ( pattern_ArkService_GetInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "info"}, "")) pattern_ArkService_Onboard_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "onboard"}, "")) + + pattern_ArkService_TrustedOnboarding_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "onboard", "address"}, "")) ) var ( @@ -819,4 +894,6 @@ var ( forward_ArkService_GetInfo_0 = runtime.ForwardResponseMessage forward_ArkService_Onboard_0 = runtime.ForwardResponseMessage + + forward_ArkService_TrustedOnboarding_0 = runtime.ForwardResponseMessage ) diff --git a/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go b/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go index 12d9057..bbd0ba8 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go +++ b/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go @@ -27,6 +27,7 @@ type ArkServiceClient interface { ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) Onboard(ctx context.Context, in *OnboardRequest, opts ...grpc.CallOption) (*OnboardResponse, error) + TrustedOnboarding(ctx context.Context, in *TrustedOnboardingRequest, opts ...grpc.CallOption) (*TrustedOnboardingResponse, error) } type arkServiceClient struct { @@ -141,6 +142,15 @@ func (c *arkServiceClient) Onboard(ctx context.Context, in *OnboardRequest, opts return out, nil } +func (c *arkServiceClient) TrustedOnboarding(ctx context.Context, in *TrustedOnboardingRequest, opts ...grpc.CallOption) (*TrustedOnboardingResponse, error) { + out := new(TrustedOnboardingResponse) + err := c.cc.Invoke(ctx, "/ark.v1.ArkService/TrustedOnboarding", 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 @@ -154,6 +164,7 @@ type ArkServiceServer interface { ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) Onboard(context.Context, *OnboardRequest) (*OnboardResponse, error) + TrustedOnboarding(context.Context, *TrustedOnboardingRequest) (*TrustedOnboardingResponse, error) } // UnimplementedArkServiceServer should be embedded to have forward compatible implementations. @@ -187,6 +198,9 @@ func (UnimplementedArkServiceServer) GetInfo(context.Context, *GetInfoRequest) ( func (UnimplementedArkServiceServer) Onboard(context.Context, *OnboardRequest) (*OnboardResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Onboard not implemented") } +func (UnimplementedArkServiceServer) TrustedOnboarding(context.Context, *TrustedOnboardingRequest) (*TrustedOnboardingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TrustedOnboarding 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 @@ -364,6 +378,24 @@ func _ArkService_Onboard_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _ArkService_TrustedOnboarding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TrustedOnboardingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArkServiceServer).TrustedOnboarding(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ark.v1.ArkService/TrustedOnboarding", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArkServiceServer).TrustedOnboarding(ctx, req.(*TrustedOnboardingRequest)) + } + 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) @@ -403,6 +435,10 @@ var ArkService_ServiceDesc = grpc.ServiceDesc{ MethodName: "Onboard", Handler: _ArkService_Onboard_Handler, }, + { + MethodName: "TrustedOnboarding", + Handler: _ArkService_TrustedOnboarding_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/server/internal/core/application/service.go b/server/internal/core/application/service.go index f41c68b..45857c7 100644 --- a/server/internal/core/application/service.go +++ b/server/internal/core/application/service.go @@ -16,6 +16,7 @@ import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" log "github.com/sirupsen/logrus" "github.com/vulpemventures/go-elements/network" + "github.com/vulpemventures/go-elements/payment" "github.com/vulpemventures/go-elements/psetv2" ) @@ -36,6 +37,7 @@ type Service interface { ListVtxos(ctx context.Context, pubkey *secp256k1.PublicKey) ([]domain.Vtxo, error) GetInfo(ctx context.Context) (string, int64, int64, error) Onboard(ctx context.Context, boardingTx string, congestionTree tree.CongestionTree, userPubkey *secp256k1.PublicKey) error + TrustedOnboarding(ctx context.Context, userPubKey *secp256k1.PublicKey, onboardingAmount uint64) (string, uint64, error) } type onboarding struct { @@ -64,6 +66,9 @@ type service struct { eventsCh chan domain.RoundEvent onboardingCh chan onboarding + + trustedOnboardingScriptLock *sync.Mutex + trustedOnboardingScripts map[string]*secp256k1.PublicKey } func NewService( @@ -91,6 +96,7 @@ func NewService( roundLifetime, roundInterval, unilateralExitDelay, minRelayFee, walletSvc, repoManager, builder, scanner, sweeper, paymentRequests, forfeitTxs, eventsCh, onboardingCh, + &sync.Mutex{}, make(map[string]*secp256k1.PublicKey), } repoManager.RegisterEventsHandler( func(round *domain.Round) { @@ -103,7 +109,7 @@ func NewService( if err := svc.restoreWatchingVtxos(); err != nil { return nil, fmt.Errorf("failed to restore watching vtxos: %s", err) } - go svc.listenToRedemptions() + go svc.listenToScannerNotifications() go svc.listenToOnboarding() return svc, nil } @@ -201,15 +207,16 @@ func (s *service) Onboard( ctx context.Context, boardingTx string, congestionTree tree.CongestionTree, userPubkey *secp256k1.PublicKey, ) error { + ptx, err := psetv2.NewPsetFromBase64(boardingTx) + if err != nil { + return fmt.Errorf("failed to parse boarding tx: %s", err) + } + if err := tree.ValidateCongestionTree( congestionTree, boardingTx, s.pubkey, s.roundLifetime, ); err != nil { return err } - ptx, err := psetv2.NewPsetFromBase64(boardingTx) - if err != nil { - return fmt.Errorf("failed to parse boarding tx: %s", err) - } extracted, err := psetv2.Extract(ptx) if err != nil { @@ -237,6 +244,46 @@ func (s *service) Onboard( return nil } +func (s *service) TrustedOnboarding( + ctx context.Context, userPubKey *secp256k1.PublicKey, onboardingAmount uint64, +) (string, uint64, error) { + congestionTreeLeaf := tree.Receiver{ + Pubkey: hex.EncodeToString(userPubKey.SerializeCompressed()), + Amount: onboardingAmount, + } + + _, sharedOutputScript, sharedOutputAmount, err := tree.CraftCongestionTree( + s.onchainNework.AssetID, s.pubkey, []tree.Receiver{congestionTreeLeaf}, + s.minRelayFee, s.roundLifetime, s.unilateralExitDelay, + ) + if err != nil { + return "", 0, err + } + + pay, err := payment.FromScript(sharedOutputScript, &s.onchainNework, nil) + if err != nil { + return "", 0, err + } + + address, err := pay.TaprootAddress() + if err != nil { + return "", 0, err + } + + s.trustedOnboardingScriptLock.Lock() + + script := hex.EncodeToString(sharedOutputScript) + s.trustedOnboardingScripts[script] = userPubKey + + s.trustedOnboardingScriptLock.Unlock() + + if err := s.scanner.WatchScripts(ctx, []string{script}); err != nil { + return "", 0, err + } + + return address, sharedOutputAmount, nil +} + func (s *service) start() { s.startRound() } @@ -392,6 +439,7 @@ func (s *service) listenToOnboarding() { func (s *service) handleOnboarding(onboarding onboarding) { ctx := context.Background() + ptx, _ := psetv2.NewPsetFromBase64(onboarding.tx) utx, _ := psetv2.Extract(ptx) txid := utx.TxHash().String() @@ -431,18 +479,77 @@ func (s *service) handleOnboarding(onboarding onboarding) { } } -func (s *service) listenToRedemptions() { +func (s *service) listenToScannerNotifications() { ctx := context.Background() chVtxos := s.scanner.GetNotificationChannel(ctx) mutx := &sync.Mutex{} for vtxoKeys := range chVtxos { - go func(vtxoKeys []domain.VtxoKey) { + go func(vtxoKeys map[string]ports.VtxoWithValue) { vtxosRepo := s.repoManager.Vtxos() roundRepo := s.repoManager.Rounds() - for _, v := range vtxoKeys { - vtxos, err := vtxosRepo.GetVtxos(ctx, []domain.VtxoKey{v}) + for script, v := range vtxoKeys { + if userPubkey, ok := s.trustedOnboardingScripts[script]; ok { + // onboarding + defer func() { + s.trustedOnboardingScriptLock.Lock() + delete(s.trustedOnboardingScripts, script) + s.trustedOnboardingScriptLock.Unlock() + }() + + congestionTreeLeaf := tree.Receiver{ + Pubkey: hex.EncodeToString(userPubkey.SerializeCompressed()), + Amount: v.Value - s.minRelayFee, + } + + treeFactoryFn, sharedOutputScript, sharedOutputAmount, err := tree.CraftCongestionTree( + s.onchainNework.AssetID, s.pubkey, []tree.Receiver{congestionTreeLeaf}, + s.minRelayFee, s.roundLifetime, s.unilateralExitDelay, + ) + if err != nil { + log.WithError(err).Warn("failed to craft onboarding congestion tree") + return + } + + congestionTree, err := treeFactoryFn( + psetv2.InputArgs{ + Txid: v.Txid, + TxIndex: v.VOut, + }, + ) + if err != nil { + log.WithError(err).Warn("failed to build onboarding congestion tree") + return + } + + if sharedOutputAmount != v.Value { + log.Errorf("shared output amount mismatch, expected %d, got %d", sharedOutputAmount, v.Value) + return + } + + precomputedScript, _ := hex.DecodeString(script) + + if !bytes.Equal(sharedOutputScript, precomputedScript) { + log.Errorf("shared output script mismatch, expected %x, got %x", sharedOutputScript, precomputedScript) + return + } + + pubkey := hex.EncodeToString(userPubkey.SerializeCompressed()) + payments := getPaymentsFromOnboarding(congestionTree, pubkey) + round := domain.NewFinalizedRound( + dustAmount, pubkey, v.Txid, "", congestionTree, payments, + ) + if err := s.saveEvents(ctx, round.Id, round.Events()); err != nil { + log.WithError(err).Warn("failed to store new round events") + return + } + + return + } + + // redeem + vtxos, err := vtxosRepo.GetVtxos(ctx, []domain.VtxoKey{v.VtxoKey}) if err != nil { log.WithError(err).Warn("failed to retrieve vtxos, skipping...") continue diff --git a/server/internal/core/ports/scanner.go b/server/internal/core/ports/scanner.go index 6cd2080..835bbda 100644 --- a/server/internal/core/ports/scanner.go +++ b/server/internal/core/ports/scanner.go @@ -5,8 +5,13 @@ import ( "golang.org/x/net/context" ) +type VtxoWithValue struct { + domain.VtxoKey + Value uint64 +} + type BlockchainScanner interface { WatchScripts(ctx context.Context, scripts []string) error UnwatchScripts(ctx context.Context, scripts []string) error - GetNotificationChannel(ctx context.Context) chan []domain.VtxoKey + GetNotificationChannel(ctx context.Context) <-chan map[string]VtxoWithValue } diff --git a/server/internal/infrastructure/ocean-wallet/notification.go b/server/internal/infrastructure/ocean-wallet/notification.go index 43d6075..b42f50d 100644 --- a/server/internal/infrastructure/ocean-wallet/notification.go +++ b/server/internal/infrastructure/ocean-wallet/notification.go @@ -6,7 +6,7 @@ import ( "encoding/hex" pb "github.com/ark-network/ark/api-spec/protobuf/gen/ocean/v1" - "github.com/ark-network/ark/internal/core/domain" + "github.com/ark-network/ark/internal/core/ports" "github.com/btcsuite/btcd/chaincfg/chainhash" ) @@ -35,7 +35,7 @@ func (s *service) UnwatchScripts(ctx context.Context, scripts []string) error { return nil } -func (s *service) GetNotificationChannel(ctx context.Context) chan []domain.VtxoKey { +func (s *service) GetNotificationChannel(ctx context.Context) <-chan map[string]ports.VtxoWithValue { return s.chVtxos } diff --git a/server/internal/infrastructure/ocean-wallet/service.go b/server/internal/infrastructure/ocean-wallet/service.go index 94eda1f..5720732 100644 --- a/server/internal/infrastructure/ocean-wallet/service.go +++ b/server/internal/infrastructure/ocean-wallet/service.go @@ -23,7 +23,7 @@ type service struct { accountClient pb.AccountServiceClient txClient pb.TransactionServiceClient notifyClient pb.NotificationServiceClient - chVtxos chan []domain.VtxoKey + chVtxos chan map[string]ports.VtxoWithValue } func NewService(addr string) (ports.WalletService, error) { @@ -35,7 +35,7 @@ func NewService(addr string) (ports.WalletService, error) { accountClient := pb.NewAccountServiceClient(conn) txClient := pb.NewTransactionServiceClient(conn) notifyClient := pb.NewNotificationServiceClient(conn) - chVtxos := make(chan []domain.VtxoKey) + chVtxos := make(chan map[string]ports.VtxoWithValue) svc := &service{ addr: addr, conn: conn, @@ -105,7 +105,7 @@ func NewService(addr string) (ports.WalletService, error) { } } - go svc.listenToNotificaitons() + go svc.listenToNotifications() return svc, nil } @@ -115,7 +115,7 @@ func (s *service) Close() { s.conn.Close() } -func (s *service) listenToNotificaitons() { +func (s *service) listenToNotifications() { var stream pb.NotificationService_UtxosNotificationsClient var err error for { @@ -147,8 +147,8 @@ func (s *service) listenToNotificaitons() { } } -func toVtxos(utxos []*pb.Utxo) []domain.VtxoKey { - vtxos := make([]domain.VtxoKey, 0, len(utxos)) +func toVtxos(utxos []*pb.Utxo) map[string]ports.VtxoWithValue { + vtxos := make(map[string]ports.VtxoWithValue, len(utxos)) for _, utxo := range utxos { // We want to notify for activity related to vtxos owner, therefore we skip // returning anything related to the internal accounts of the wallet, like @@ -157,10 +157,12 @@ func toVtxos(utxos []*pb.Utxo) []domain.VtxoKey { continue } - vtxos = append(vtxos, domain.VtxoKey{ - Txid: utxo.GetTxid(), - VOut: utxo.GetIndex(), - }) + vtxos[utxo.Script] = ports.VtxoWithValue{ + VtxoKey: domain.VtxoKey{Txid: utxo.GetTxid(), + VOut: utxo.GetIndex(), + }, + Value: utxo.GetValue(), + } } return vtxos } diff --git a/server/internal/interface/grpc/handlers/arkservice.go b/server/internal/interface/grpc/handlers/arkservice.go index 86cb682..42484de 100644 --- a/server/internal/interface/grpc/handlers/arkservice.go +++ b/server/internal/interface/grpc/handlers/arkservice.go @@ -40,6 +40,37 @@ func NewHandler(service application.Service) arkv1.ArkServiceServer { return h } +func (h *handler) TrustedOnboarding(ctx context.Context, req *arkv1.TrustedOnboardingRequest) (*arkv1.TrustedOnboardingResponse, error) { + if req.GetUserPubkey() == "" { + return nil, status.Error(codes.InvalidArgument, "missing user pubkey") + } + + pubKey, err := hex.DecodeString(req.GetUserPubkey()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid user pubkey") + } + + decodedPubKey, err := secp256k1.ParsePubKey(pubKey) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid user pubkey") + } + + amount := req.GetAmount() + if amount <= 0 { + return nil, status.Error(codes.InvalidArgument, "invalid amount") + } + + address, expectedAmount, err := h.svc.TrustedOnboarding(ctx, decodedPubKey, amount) + if err != nil { + return nil, err + } + + return &arkv1.TrustedOnboardingResponse{ + Address: address, + ExpectedAmount: expectedAmount, + }, nil +} + func (h *handler) Onboard(ctx context.Context, req *arkv1.OnboardRequest) (*arkv1.OnboardResponse, error) { if req.GetUserPubkey() == "" { return nil, status.Error(codes.InvalidArgument, "missing user pubkey") @@ -326,6 +357,10 @@ func castCongestionTree(congestionTree tree.CongestionTree) *arkv1.Tree { } func toCongestionTree(treeFromProto *arkv1.Tree) (tree.CongestionTree, error) { + if treeFromProto == nil { + return nil, nil + } + levels := make(tree.CongestionTree, 0, len(treeFromProto.Levels)) for _, level := range treeFromProto.Levels {