diff --git a/api/proto/user/v1/host.pb.go b/api/proto/user/v1/host.pb.go index 551a27b8..ab9a80b1 100644 --- a/api/proto/user/v1/host.pb.go +++ b/api/proto/user/v1/host.pb.go @@ -6663,6 +6663,321 @@ func (x *UpdateAgencyProfileResponse) GetAgency() *Agency { return nil } +// HostEngagementStats 是 Fami 等公会中心使用的用户侧统计聚合;金额/礼物流水由 wallet-service 单独拥有。 +type HostEngagementStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OnlineDurationMs int64 `protobuf:"varint,1,opt,name=online_duration_ms,json=onlineDurationMs,proto3" json:"online_duration_ms,omitempty"` + ValidMicDurationMs int64 `protobuf:"varint,2,opt,name=valid_mic_duration_ms,json=validMicDurationMs,proto3" json:"valid_mic_duration_ms,omitempty"` + ValidMicDays int64 `protobuf:"varint,3,opt,name=valid_mic_days,json=validMicDays,proto3" json:"valid_mic_days,omitempty"` + PrivateMessageSenders int64 `protobuf:"varint,4,opt,name=private_message_senders,json=privateMessageSenders,proto3" json:"private_message_senders,omitempty"` + NewFollowers int64 `protobuf:"varint,5,opt,name=new_followers,json=newFollowers,proto3" json:"new_followers,omitempty"` +} + +func (x *HostEngagementStats) Reset() { + *x = HostEngagementStats{} + mi := &file_proto_user_v1_host_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HostEngagementStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HostEngagementStats) ProtoMessage() {} + +func (x *HostEngagementStats) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_host_proto_msgTypes[97] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HostEngagementStats.ProtoReflect.Descriptor instead. +func (*HostEngagementStats) Descriptor() ([]byte, []int) { + return file_proto_user_v1_host_proto_rawDescGZIP(), []int{97} +} + +func (x *HostEngagementStats) GetOnlineDurationMs() int64 { + if x != nil { + return x.OnlineDurationMs + } + return 0 +} + +func (x *HostEngagementStats) GetValidMicDurationMs() int64 { + if x != nil { + return x.ValidMicDurationMs + } + return 0 +} + +func (x *HostEngagementStats) GetValidMicDays() int64 { + if x != nil { + return x.ValidMicDays + } + return 0 +} + +func (x *HostEngagementStats) GetPrivateMessageSenders() int64 { + if x != nil { + return x.PrivateMessageSenders + } + return 0 +} + +func (x *HostEngagementStats) GetNewFollowers() int64 { + if x != nil { + return x.NewFollowers + } + return 0 +} + +type GetHostEngagementStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + HostUserId int64 `protobuf:"varint,2,opt,name=host_user_id,json=hostUserId,proto3" json:"host_user_id,omitempty"` + StartAtMs int64 `protobuf:"varint,3,opt,name=start_at_ms,json=startAtMs,proto3" json:"start_at_ms,omitempty"` + EndAtMs int64 `protobuf:"varint,4,opt,name=end_at_ms,json=endAtMs,proto3" json:"end_at_ms,omitempty"` +} + +func (x *GetHostEngagementStatsRequest) Reset() { + *x = GetHostEngagementStatsRequest{} + mi := &file_proto_user_v1_host_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetHostEngagementStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetHostEngagementStatsRequest) ProtoMessage() {} + +func (x *GetHostEngagementStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_host_proto_msgTypes[98] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetHostEngagementStatsRequest.ProtoReflect.Descriptor instead. +func (*GetHostEngagementStatsRequest) Descriptor() ([]byte, []int) { + return file_proto_user_v1_host_proto_rawDescGZIP(), []int{98} +} + +func (x *GetHostEngagementStatsRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *GetHostEngagementStatsRequest) GetHostUserId() int64 { + if x != nil { + return x.HostUserId + } + return 0 +} + +func (x *GetHostEngagementStatsRequest) GetStartAtMs() int64 { + if x != nil { + return x.StartAtMs + } + return 0 +} + +func (x *GetHostEngagementStatsRequest) GetEndAtMs() int64 { + if x != nil { + return x.EndAtMs + } + return 0 +} + +type GetHostEngagementStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stats *HostEngagementStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` +} + +func (x *GetHostEngagementStatsResponse) Reset() { + *x = GetHostEngagementStatsResponse{} + mi := &file_proto_user_v1_host_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetHostEngagementStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetHostEngagementStatsResponse) ProtoMessage() {} + +func (x *GetHostEngagementStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_host_proto_msgTypes[99] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetHostEngagementStatsResponse.ProtoReflect.Descriptor instead. +func (*GetHostEngagementStatsResponse) Descriptor() ([]byte, []int) { + return file_proto_user_v1_host_proto_rawDescGZIP(), []int{99} +} + +func (x *GetHostEngagementStatsResponse) GetStats() *HostEngagementStats { + if x != nil { + return x.Stats + } + return nil +} + +// RecordPrivateMessageEvent 由经过腾讯回调鉴权的 gateway 写入私信事实;重复 event_id 必须幂等。 +type RecordPrivateMessageEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + EventId string `protobuf:"bytes,2,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + SenderUserId int64 `protobuf:"varint,3,opt,name=sender_user_id,json=senderUserId,proto3" json:"sender_user_id,omitempty"` + TargetUserId int64 `protobuf:"varint,4,opt,name=target_user_id,json=targetUserId,proto3" json:"target_user_id,omitempty"` + OccurredAtMs int64 `protobuf:"varint,5,opt,name=occurred_at_ms,json=occurredAtMs,proto3" json:"occurred_at_ms,omitempty"` +} + +func (x *RecordPrivateMessageEventRequest) Reset() { + *x = RecordPrivateMessageEventRequest{} + mi := &file_proto_user_v1_host_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecordPrivateMessageEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordPrivateMessageEventRequest) ProtoMessage() {} + +func (x *RecordPrivateMessageEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_host_proto_msgTypes[100] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RecordPrivateMessageEventRequest.ProtoReflect.Descriptor instead. +func (*RecordPrivateMessageEventRequest) Descriptor() ([]byte, []int) { + return file_proto_user_v1_host_proto_rawDescGZIP(), []int{100} +} + +func (x *RecordPrivateMessageEventRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *RecordPrivateMessageEventRequest) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + +func (x *RecordPrivateMessageEventRequest) GetSenderUserId() int64 { + if x != nil { + return x.SenderUserId + } + return 0 +} + +func (x *RecordPrivateMessageEventRequest) GetTargetUserId() int64 { + if x != nil { + return x.TargetUserId + } + return 0 +} + +func (x *RecordPrivateMessageEventRequest) GetOccurredAtMs() int64 { + if x != nil { + return x.OccurredAtMs + } + return 0 +} + +type RecordPrivateMessageEventResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Created bool `protobuf:"varint,1,opt,name=created,proto3" json:"created,omitempty"` +} + +func (x *RecordPrivateMessageEventResponse) Reset() { + *x = RecordPrivateMessageEventResponse{} + mi := &file_proto_user_v1_host_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecordPrivateMessageEventResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordPrivateMessageEventResponse) ProtoMessage() {} + +func (x *RecordPrivateMessageEventResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_host_proto_msgTypes[101] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RecordPrivateMessageEventResponse.ProtoReflect.Descriptor instead. +func (*RecordPrivateMessageEventResponse) Descriptor() ([]byte, []int) { + return file_proto_user_v1_host_proto_rawDescGZIP(), []int{101} +} + +func (x *RecordPrivateMessageEventResponse) GetCreated() bool { + if x != nil { + return x.Created + } + return false +} + var File_proto_user_v1_host_proto protoreflect.FileDescriptor var file_proto_user_v1_host_proto_rawDesc = []byte{ @@ -7775,208 +8090,274 @@ var file_proto_user_v1_host_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x06, 0x61, - 0x67, 0x65, 0x6e, 0x63, 0x79, 0x32, 0x95, 0x19, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x48, 0x6f, - 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, - 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, - 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, - 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, - 0x0a, 0x0e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, - 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, - 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, - 0x0c, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x42, 0x44, 0x12, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, - 0x74, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, - 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xf9, 0x01, 0x0a, 0x13, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, + 0x67, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2c, 0x0a, + 0x12, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, + 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x6d, 0x69, 0x63, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x4d, 0x69, 0x63, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x12, 0x24, + 0x0a, 0x0e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x6d, 0x69, 0x63, 0x5f, 0x64, 0x61, 0x79, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x69, 0x63, + 0x44, 0x61, 0x79, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, + 0x6e, 0x65, 0x77, 0x5f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, + 0x73, 0x22, 0xad, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x67, + 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0c, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x61, + 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x1a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x5f, + 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x4d, + 0x73, 0x22, 0x5a, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x67, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0xdf, 0x01, + 0x0a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, + 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x63, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0c, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, + 0x3d, 0x0a, 0x21, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x32, 0x8c, + 0x1b, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x5a, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, + 0x63, 0x79, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, + 0x17, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, + 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x4b, 0x69, 0x63, 0x6b, 0x41, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, + 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4b, 0x0a, 0x08, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x12, 0x1e, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0a, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, + 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x60, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, + 0x44, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, + 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, - 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, - 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, + 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, + 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x78, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x54, 0x65, 0x61, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68, 0x79, + 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x67, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x63, - 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x54, - 0x65, 0x61, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x54, 0x65, - 0x61, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, - 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x66, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, - 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, - 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, - 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, + 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x72, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, - 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x90, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, - 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, + 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, + 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, + 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, + 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x90, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, - 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e, - 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, - 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, - 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x1e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x41, - 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, - 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, - 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x28, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x43, - 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x69, 0x6e, - 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x75, 0x62, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, - 0x72, 0x53, 0x75, 0x62, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, - 0x6c, 0x65, 0x72, 0x53, 0x75, 0x62, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x28, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x78, 0x0a, 0x17, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, - 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x68, + 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x43, + 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x8d, 0x01, 0x0a, 0x1e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, + 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x69, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, + 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1a, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, + 0x75, 0x62, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x75, 0x62, 0x52, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, - 0x6f, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, - 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, + 0x63, 0x6b, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x75, 0x62, 0x52, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x69, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x47, 0x65, + 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, + 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, - 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x47, - 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6c, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, - 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc1, 0x09, + 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, + 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, + 0x74, 0x45, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, + 0x19, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc1, 0x09, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, @@ -8071,7 +8452,7 @@ func file_proto_user_v1_host_proto_rawDescGZIP() []byte { return file_proto_user_v1_host_proto_rawDescData } -var file_proto_user_v1_host_proto_msgTypes = make([]protoimpl.MessageInfo, 98) +var file_proto_user_v1_host_proto_msgTypes = make([]protoimpl.MessageInfo, 103) var file_proto_user_v1_host_proto_goTypes = []any{ (*HostProfile)(nil), // 0: hyapp.user.v1.HostProfile (*Agency)(nil), // 1: hyapp.user.v1.Agency @@ -8170,197 +8551,209 @@ var file_proto_user_v1_host_proto_goTypes = []any{ (*SetAgencyJoinEnabledResponse)(nil), // 94: hyapp.user.v1.SetAgencyJoinEnabledResponse (*UpdateAgencyProfileRequest)(nil), // 95: hyapp.user.v1.UpdateAgencyProfileRequest (*UpdateAgencyProfileResponse)(nil), // 96: hyapp.user.v1.UpdateAgencyProfileResponse - nil, // 97: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry - (*RequestMeta)(nil), // 98: hyapp.user.v1.RequestMeta + (*HostEngagementStats)(nil), // 97: hyapp.user.v1.HostEngagementStats + (*GetHostEngagementStatsRequest)(nil), // 98: hyapp.user.v1.GetHostEngagementStatsRequest + (*GetHostEngagementStatsResponse)(nil), // 99: hyapp.user.v1.GetHostEngagementStatsResponse + (*RecordPrivateMessageEventRequest)(nil), // 100: hyapp.user.v1.RecordPrivateMessageEventRequest + (*RecordPrivateMessageEventResponse)(nil), // 101: hyapp.user.v1.RecordPrivateMessageEventResponse + nil, // 102: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry + (*RequestMeta)(nil), // 103: hyapp.user.v1.RequestMeta } var file_proto_user_v1_host_proto_depIdxs = []int32{ - 98, // 0: hyapp.user.v1.SearchAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 0: hyapp.user.v1.SearchAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 1: hyapp.user.v1.SearchAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency - 98, // 2: hyapp.user.v1.ApplyToAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 2: hyapp.user.v1.ApplyToAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 9, // 3: hyapp.user.v1.ApplyToAgencyResponse.application:type_name -> hyapp.user.v1.AgencyApplication - 98, // 4: hyapp.user.v1.ReviewAgencyApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 4: hyapp.user.v1.ReviewAgencyApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 9, // 5: hyapp.user.v1.ReviewAgencyApplicationResponse.application:type_name -> hyapp.user.v1.AgencyApplication 0, // 6: hyapp.user.v1.ReviewAgencyApplicationResponse.host_profile:type_name -> hyapp.user.v1.HostProfile 8, // 7: hyapp.user.v1.ReviewAgencyApplicationResponse.membership:type_name -> hyapp.user.v1.AgencyMembership - 98, // 8: hyapp.user.v1.KickAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 8: hyapp.user.v1.KickAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta 8, // 9: hyapp.user.v1.KickAgencyHostResponse.membership:type_name -> hyapp.user.v1.AgencyMembership 0, // 10: hyapp.user.v1.KickAgencyHostResponse.host_profile:type_name -> hyapp.user.v1.HostProfile - 98, // 11: hyapp.user.v1.InviteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 11: hyapp.user.v1.InviteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 12: hyapp.user.v1.InviteAgencyResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation - 98, // 13: hyapp.user.v1.InviteBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 13: hyapp.user.v1.InviteBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 14: hyapp.user.v1.InviteBDResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation - 98, // 15: hyapp.user.v1.InviteHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 15: hyapp.user.v1.InviteHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 16: hyapp.user.v1.InviteHostResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation - 98, // 17: hyapp.user.v1.ListBDLeaderBDsRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 17: hyapp.user.v1.ListBDLeaderBDsRequest.meta:type_name -> hyapp.user.v1.RequestMeta 2, // 18: hyapp.user.v1.ListBDLeaderBDsResponse.bd_profiles:type_name -> hyapp.user.v1.BDProfile - 98, // 19: hyapp.user.v1.ListBDLeaderAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 19: hyapp.user.v1.ListBDLeaderAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 20: hyapp.user.v1.ListBDLeaderAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency - 98, // 21: hyapp.user.v1.ListManagerTeamAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 21: hyapp.user.v1.ListManagerTeamAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta 30, // 22: hyapp.user.v1.ListManagerTeamAgenciesResponse.agencies:type_name -> hyapp.user.v1.ManagerTeamAgency - 98, // 23: hyapp.user.v1.ListBDAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 23: hyapp.user.v1.ListBDAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 24: hyapp.user.v1.ListBDAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency - 98, // 25: hyapp.user.v1.ListRoleInvitationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 25: hyapp.user.v1.ListRoleInvitationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 26: hyapp.user.v1.ListRoleInvitationsResponse.invitations:type_name -> hyapp.user.v1.RoleInvitation - 98, // 27: hyapp.user.v1.GetRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 27: hyapp.user.v1.GetRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 28: hyapp.user.v1.GetRoleInvitationResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation - 98, // 29: hyapp.user.v1.ProcessRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 29: hyapp.user.v1.ProcessRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 10, // 30: hyapp.user.v1.ProcessRoleInvitationResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation 0, // 31: hyapp.user.v1.ProcessRoleInvitationResponse.host_profile:type_name -> hyapp.user.v1.HostProfile 1, // 32: hyapp.user.v1.ProcessRoleInvitationResponse.agency:type_name -> hyapp.user.v1.Agency 8, // 33: hyapp.user.v1.ProcessRoleInvitationResponse.membership:type_name -> hyapp.user.v1.AgencyMembership 2, // 34: hyapp.user.v1.ProcessRoleInvitationResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile - 98, // 35: hyapp.user.v1.GetHostProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 35: hyapp.user.v1.GetHostProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta 0, // 36: hyapp.user.v1.GetHostProfileResponse.host_profile:type_name -> hyapp.user.v1.HostProfile - 98, // 37: hyapp.user.v1.BatchGetHostProfilesRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 97, // 38: hyapp.user.v1.BatchGetHostProfilesResponse.host_profiles:type_name -> hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry - 98, // 39: hyapp.user.v1.GetBDProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 37: hyapp.user.v1.BatchGetHostProfilesRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 102, // 38: hyapp.user.v1.BatchGetHostProfilesResponse.host_profiles:type_name -> hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry + 103, // 39: hyapp.user.v1.GetBDProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta 2, // 40: hyapp.user.v1.GetBDProfileResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile - 98, // 41: hyapp.user.v1.GetCoinSellerProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 41: hyapp.user.v1.GetCoinSellerProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta 3, // 42: hyapp.user.v1.GetCoinSellerProfileResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile - 98, // 43: hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 43: hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest.meta:type_name -> hyapp.user.v1.RequestMeta 4, // 44: hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse.coin_sellers:type_name -> hyapp.user.v1.CoinSellerListItem - 98, // 45: hyapp.user.v1.CreateSubCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 45: hyapp.user.v1.CreateSubCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta 5, // 46: hyapp.user.v1.CreateSubCoinSellerResponse.relation:type_name -> hyapp.user.v1.CoinSellerSubRelation 4, // 47: hyapp.user.v1.CreateSubCoinSellerResponse.child:type_name -> hyapp.user.v1.CoinSellerListItem - 98, // 48: hyapp.user.v1.SubmitSubCoinSellerApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 48: hyapp.user.v1.SubmitSubCoinSellerApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 6, // 49: hyapp.user.v1.SubmitSubCoinSellerApplicationResponse.application:type_name -> hyapp.user.v1.CoinSellerSubApplication - 98, // 50: hyapp.user.v1.ListSubCoinSellersRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 50: hyapp.user.v1.ListSubCoinSellersRequest.meta:type_name -> hyapp.user.v1.RequestMeta 4, // 51: hyapp.user.v1.ListSubCoinSellersResponse.children:type_name -> hyapp.user.v1.CoinSellerListItem - 98, // 52: hyapp.user.v1.CheckCoinSellerSubRelationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 52: hyapp.user.v1.CheckCoinSellerSubRelationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 4, // 53: hyapp.user.v1.CheckCoinSellerSubRelationResponse.child:type_name -> hyapp.user.v1.CoinSellerListItem - 98, // 54: hyapp.user.v1.GetUserRoleSummaryRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 54: hyapp.user.v1.GetUserRoleSummaryRequest.meta:type_name -> hyapp.user.v1.RequestMeta 7, // 55: hyapp.user.v1.GetUserRoleSummaryResponse.summary:type_name -> hyapp.user.v1.UserRoleSummary - 98, // 56: hyapp.user.v1.GetAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 56: hyapp.user.v1.GetAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 57: hyapp.user.v1.GetAgencyResponse.agency:type_name -> hyapp.user.v1.Agency - 98, // 58: hyapp.user.v1.CheckBusinessCapabilityRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 98, // 59: hyapp.user.v1.GetRoleScopePolicyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 58: hyapp.user.v1.CheckBusinessCapabilityRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 59: hyapp.user.v1.GetRoleScopePolicyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 64, // 60: hyapp.user.v1.GetRoleScopePolicyResponse.policy:type_name -> hyapp.user.v1.RoleScopePolicy - 98, // 61: hyapp.user.v1.GetAgencyMembersRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 61: hyapp.user.v1.GetAgencyMembersRequest.meta:type_name -> hyapp.user.v1.RequestMeta 8, // 62: hyapp.user.v1.GetAgencyMembersResponse.memberships:type_name -> hyapp.user.v1.AgencyMembership - 98, // 63: hyapp.user.v1.GetAgencyApplicationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 63: hyapp.user.v1.GetAgencyApplicationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta 9, // 64: hyapp.user.v1.GetAgencyApplicationsResponse.applications:type_name -> hyapp.user.v1.AgencyApplication - 98, // 65: hyapp.user.v1.CreateBDLeaderRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 65: hyapp.user.v1.CreateBDLeaderRequest.meta:type_name -> hyapp.user.v1.RequestMeta 2, // 66: hyapp.user.v1.CreateBDLeaderResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile - 98, // 67: hyapp.user.v1.CreateBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 67: hyapp.user.v1.CreateBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta 2, // 68: hyapp.user.v1.CreateBDResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile - 98, // 69: hyapp.user.v1.SetBDStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 69: hyapp.user.v1.SetBDStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta 2, // 70: hyapp.user.v1.SetBDStatusResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile - 98, // 71: hyapp.user.v1.CreateCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 71: hyapp.user.v1.CreateCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta 3, // 72: hyapp.user.v1.CreateCoinSellerResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile - 98, // 73: hyapp.user.v1.SetCoinSellerStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 73: hyapp.user.v1.SetCoinSellerStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta 3, // 74: hyapp.user.v1.SetCoinSellerStatusResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile - 98, // 75: hyapp.user.v1.ReviewSubCoinSellerApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 75: hyapp.user.v1.ReviewSubCoinSellerApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta 6, // 76: hyapp.user.v1.ReviewSubCoinSellerApplicationResponse.application:type_name -> hyapp.user.v1.CoinSellerSubApplication 5, // 77: hyapp.user.v1.ReviewSubCoinSellerApplicationResponse.relation:type_name -> hyapp.user.v1.CoinSellerSubRelation 4, // 78: hyapp.user.v1.ReviewSubCoinSellerApplicationResponse.child:type_name -> hyapp.user.v1.CoinSellerListItem - 98, // 79: hyapp.user.v1.CreateAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 79: hyapp.user.v1.CreateAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 80: hyapp.user.v1.CreateAgencyResponse.agency:type_name -> hyapp.user.v1.Agency 0, // 81: hyapp.user.v1.CreateAgencyResponse.host_profile:type_name -> hyapp.user.v1.HostProfile 8, // 82: hyapp.user.v1.CreateAgencyResponse.membership:type_name -> hyapp.user.v1.AgencyMembership - 98, // 83: hyapp.user.v1.AdminAddAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 83: hyapp.user.v1.AdminAddAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 84: hyapp.user.v1.AdminAddAgencyHostResponse.agency:type_name -> hyapp.user.v1.Agency 0, // 85: hyapp.user.v1.AdminAddAgencyHostResponse.host_profile:type_name -> hyapp.user.v1.HostProfile 8, // 86: hyapp.user.v1.AdminAddAgencyHostResponse.membership:type_name -> hyapp.user.v1.AgencyMembership - 98, // 87: hyapp.user.v1.CloseAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 87: hyapp.user.v1.CloseAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 88: hyapp.user.v1.CloseAgencyResponse.agency:type_name -> hyapp.user.v1.Agency - 98, // 89: hyapp.user.v1.DeleteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 89: hyapp.user.v1.DeleteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 90: hyapp.user.v1.DeleteAgencyResponse.agency:type_name -> hyapp.user.v1.Agency - 98, // 91: hyapp.user.v1.SetAgencyStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 91: hyapp.user.v1.SetAgencyStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 92: hyapp.user.v1.SetAgencyStatusResponse.agency:type_name -> hyapp.user.v1.Agency - 98, // 93: hyapp.user.v1.SetAgencyJoinEnabledRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 93: hyapp.user.v1.SetAgencyJoinEnabledRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 94: hyapp.user.v1.SetAgencyJoinEnabledResponse.agency:type_name -> hyapp.user.v1.Agency - 98, // 95: hyapp.user.v1.UpdateAgencyProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 103, // 95: hyapp.user.v1.UpdateAgencyProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta 1, // 96: hyapp.user.v1.UpdateAgencyProfileResponse.agency:type_name -> hyapp.user.v1.Agency - 0, // 97: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry.value:type_name -> hyapp.user.v1.HostProfile - 11, // 98: hyapp.user.v1.UserHostService.SearchAgencies:input_type -> hyapp.user.v1.SearchAgenciesRequest - 13, // 99: hyapp.user.v1.UserHostService.ApplyToAgency:input_type -> hyapp.user.v1.ApplyToAgencyRequest - 15, // 100: hyapp.user.v1.UserHostService.ReviewAgencyApplication:input_type -> hyapp.user.v1.ReviewAgencyApplicationRequest - 17, // 101: hyapp.user.v1.UserHostService.KickAgencyHost:input_type -> hyapp.user.v1.KickAgencyHostRequest - 19, // 102: hyapp.user.v1.UserHostService.InviteAgency:input_type -> hyapp.user.v1.InviteAgencyRequest - 21, // 103: hyapp.user.v1.UserHostService.InviteBD:input_type -> hyapp.user.v1.InviteBDRequest - 23, // 104: hyapp.user.v1.UserHostService.InviteHost:input_type -> hyapp.user.v1.InviteHostRequest - 25, // 105: hyapp.user.v1.UserHostService.ListBDLeaderBDs:input_type -> hyapp.user.v1.ListBDLeaderBDsRequest - 27, // 106: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:input_type -> hyapp.user.v1.ListBDLeaderAgenciesRequest - 32, // 107: hyapp.user.v1.UserHostService.ListBDAgencies:input_type -> hyapp.user.v1.ListBDAgenciesRequest - 29, // 108: hyapp.user.v1.UserHostService.ListManagerTeamAgencies:input_type -> hyapp.user.v1.ListManagerTeamAgenciesRequest - 34, // 109: hyapp.user.v1.UserHostService.ListRoleInvitations:input_type -> hyapp.user.v1.ListRoleInvitationsRequest - 36, // 110: hyapp.user.v1.UserHostService.GetRoleInvitation:input_type -> hyapp.user.v1.GetRoleInvitationRequest - 38, // 111: hyapp.user.v1.UserHostService.ProcessRoleInvitation:input_type -> hyapp.user.v1.ProcessRoleInvitationRequest - 40, // 112: hyapp.user.v1.UserHostService.GetHostProfile:input_type -> hyapp.user.v1.GetHostProfileRequest - 42, // 113: hyapp.user.v1.UserHostService.BatchGetHostProfiles:input_type -> hyapp.user.v1.BatchGetHostProfilesRequest - 44, // 114: hyapp.user.v1.UserHostService.GetBDProfile:input_type -> hyapp.user.v1.GetBDProfileRequest - 46, // 115: hyapp.user.v1.UserHostService.GetCoinSellerProfile:input_type -> hyapp.user.v1.GetCoinSellerProfileRequest - 48, // 116: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:input_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest - 50, // 117: hyapp.user.v1.UserHostService.CreateSubCoinSeller:input_type -> hyapp.user.v1.CreateSubCoinSellerRequest - 52, // 118: hyapp.user.v1.UserHostService.SubmitSubCoinSellerApplication:input_type -> hyapp.user.v1.SubmitSubCoinSellerApplicationRequest - 54, // 119: hyapp.user.v1.UserHostService.ListSubCoinSellers:input_type -> hyapp.user.v1.ListSubCoinSellersRequest - 56, // 120: hyapp.user.v1.UserHostService.CheckCoinSellerSubRelation:input_type -> hyapp.user.v1.CheckCoinSellerSubRelationRequest - 58, // 121: hyapp.user.v1.UserHostService.GetUserRoleSummary:input_type -> hyapp.user.v1.GetUserRoleSummaryRequest - 60, // 122: hyapp.user.v1.UserHostService.GetAgency:input_type -> hyapp.user.v1.GetAgencyRequest - 62, // 123: hyapp.user.v1.UserHostService.CheckBusinessCapability:input_type -> hyapp.user.v1.CheckBusinessCapabilityRequest - 65, // 124: hyapp.user.v1.UserHostService.GetRoleScopePolicy:input_type -> hyapp.user.v1.GetRoleScopePolicyRequest - 67, // 125: hyapp.user.v1.UserHostService.GetAgencyMembers:input_type -> hyapp.user.v1.GetAgencyMembersRequest - 69, // 126: hyapp.user.v1.UserHostService.GetAgencyApplications:input_type -> hyapp.user.v1.GetAgencyApplicationsRequest - 95, // 127: hyapp.user.v1.UserHostService.UpdateAgencyProfile:input_type -> hyapp.user.v1.UpdateAgencyProfileRequest - 71, // 128: hyapp.user.v1.UserHostAdminService.CreateBDLeader:input_type -> hyapp.user.v1.CreateBDLeaderRequest - 73, // 129: hyapp.user.v1.UserHostAdminService.CreateBD:input_type -> hyapp.user.v1.CreateBDRequest - 75, // 130: hyapp.user.v1.UserHostAdminService.SetBDStatus:input_type -> hyapp.user.v1.SetBDStatusRequest - 77, // 131: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:input_type -> hyapp.user.v1.CreateCoinSellerRequest - 79, // 132: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:input_type -> hyapp.user.v1.SetCoinSellerStatusRequest - 81, // 133: hyapp.user.v1.UserHostAdminService.ReviewSubCoinSellerApplication:input_type -> hyapp.user.v1.ReviewSubCoinSellerApplicationRequest - 83, // 134: hyapp.user.v1.UserHostAdminService.CreateAgency:input_type -> hyapp.user.v1.CreateAgencyRequest - 85, // 135: hyapp.user.v1.UserHostAdminService.AdminAddAgencyHost:input_type -> hyapp.user.v1.AdminAddAgencyHostRequest - 87, // 136: hyapp.user.v1.UserHostAdminService.CloseAgency:input_type -> hyapp.user.v1.CloseAgencyRequest - 89, // 137: hyapp.user.v1.UserHostAdminService.DeleteAgency:input_type -> hyapp.user.v1.DeleteAgencyRequest - 91, // 138: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:input_type -> hyapp.user.v1.SetAgencyStatusRequest - 93, // 139: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:input_type -> hyapp.user.v1.SetAgencyJoinEnabledRequest - 12, // 140: hyapp.user.v1.UserHostService.SearchAgencies:output_type -> hyapp.user.v1.SearchAgenciesResponse - 14, // 141: hyapp.user.v1.UserHostService.ApplyToAgency:output_type -> hyapp.user.v1.ApplyToAgencyResponse - 16, // 142: hyapp.user.v1.UserHostService.ReviewAgencyApplication:output_type -> hyapp.user.v1.ReviewAgencyApplicationResponse - 18, // 143: hyapp.user.v1.UserHostService.KickAgencyHost:output_type -> hyapp.user.v1.KickAgencyHostResponse - 20, // 144: hyapp.user.v1.UserHostService.InviteAgency:output_type -> hyapp.user.v1.InviteAgencyResponse - 22, // 145: hyapp.user.v1.UserHostService.InviteBD:output_type -> hyapp.user.v1.InviteBDResponse - 24, // 146: hyapp.user.v1.UserHostService.InviteHost:output_type -> hyapp.user.v1.InviteHostResponse - 26, // 147: hyapp.user.v1.UserHostService.ListBDLeaderBDs:output_type -> hyapp.user.v1.ListBDLeaderBDsResponse - 28, // 148: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:output_type -> hyapp.user.v1.ListBDLeaderAgenciesResponse - 33, // 149: hyapp.user.v1.UserHostService.ListBDAgencies:output_type -> hyapp.user.v1.ListBDAgenciesResponse - 31, // 150: hyapp.user.v1.UserHostService.ListManagerTeamAgencies:output_type -> hyapp.user.v1.ListManagerTeamAgenciesResponse - 35, // 151: hyapp.user.v1.UserHostService.ListRoleInvitations:output_type -> hyapp.user.v1.ListRoleInvitationsResponse - 37, // 152: hyapp.user.v1.UserHostService.GetRoleInvitation:output_type -> hyapp.user.v1.GetRoleInvitationResponse - 39, // 153: hyapp.user.v1.UserHostService.ProcessRoleInvitation:output_type -> hyapp.user.v1.ProcessRoleInvitationResponse - 41, // 154: hyapp.user.v1.UserHostService.GetHostProfile:output_type -> hyapp.user.v1.GetHostProfileResponse - 43, // 155: hyapp.user.v1.UserHostService.BatchGetHostProfiles:output_type -> hyapp.user.v1.BatchGetHostProfilesResponse - 45, // 156: hyapp.user.v1.UserHostService.GetBDProfile:output_type -> hyapp.user.v1.GetBDProfileResponse - 47, // 157: hyapp.user.v1.UserHostService.GetCoinSellerProfile:output_type -> hyapp.user.v1.GetCoinSellerProfileResponse - 49, // 158: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:output_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse - 51, // 159: hyapp.user.v1.UserHostService.CreateSubCoinSeller:output_type -> hyapp.user.v1.CreateSubCoinSellerResponse - 53, // 160: hyapp.user.v1.UserHostService.SubmitSubCoinSellerApplication:output_type -> hyapp.user.v1.SubmitSubCoinSellerApplicationResponse - 55, // 161: hyapp.user.v1.UserHostService.ListSubCoinSellers:output_type -> hyapp.user.v1.ListSubCoinSellersResponse - 57, // 162: hyapp.user.v1.UserHostService.CheckCoinSellerSubRelation:output_type -> hyapp.user.v1.CheckCoinSellerSubRelationResponse - 59, // 163: hyapp.user.v1.UserHostService.GetUserRoleSummary:output_type -> hyapp.user.v1.GetUserRoleSummaryResponse - 61, // 164: hyapp.user.v1.UserHostService.GetAgency:output_type -> hyapp.user.v1.GetAgencyResponse - 63, // 165: hyapp.user.v1.UserHostService.CheckBusinessCapability:output_type -> hyapp.user.v1.CheckBusinessCapabilityResponse - 66, // 166: hyapp.user.v1.UserHostService.GetRoleScopePolicy:output_type -> hyapp.user.v1.GetRoleScopePolicyResponse - 68, // 167: hyapp.user.v1.UserHostService.GetAgencyMembers:output_type -> hyapp.user.v1.GetAgencyMembersResponse - 70, // 168: hyapp.user.v1.UserHostService.GetAgencyApplications:output_type -> hyapp.user.v1.GetAgencyApplicationsResponse - 96, // 169: hyapp.user.v1.UserHostService.UpdateAgencyProfile:output_type -> hyapp.user.v1.UpdateAgencyProfileResponse - 72, // 170: hyapp.user.v1.UserHostAdminService.CreateBDLeader:output_type -> hyapp.user.v1.CreateBDLeaderResponse - 74, // 171: hyapp.user.v1.UserHostAdminService.CreateBD:output_type -> hyapp.user.v1.CreateBDResponse - 76, // 172: hyapp.user.v1.UserHostAdminService.SetBDStatus:output_type -> hyapp.user.v1.SetBDStatusResponse - 78, // 173: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:output_type -> hyapp.user.v1.CreateCoinSellerResponse - 80, // 174: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:output_type -> hyapp.user.v1.SetCoinSellerStatusResponse - 82, // 175: hyapp.user.v1.UserHostAdminService.ReviewSubCoinSellerApplication:output_type -> hyapp.user.v1.ReviewSubCoinSellerApplicationResponse - 84, // 176: hyapp.user.v1.UserHostAdminService.CreateAgency:output_type -> hyapp.user.v1.CreateAgencyResponse - 86, // 177: hyapp.user.v1.UserHostAdminService.AdminAddAgencyHost:output_type -> hyapp.user.v1.AdminAddAgencyHostResponse - 88, // 178: hyapp.user.v1.UserHostAdminService.CloseAgency:output_type -> hyapp.user.v1.CloseAgencyResponse - 90, // 179: hyapp.user.v1.UserHostAdminService.DeleteAgency:output_type -> hyapp.user.v1.DeleteAgencyResponse - 92, // 180: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:output_type -> hyapp.user.v1.SetAgencyStatusResponse - 94, // 181: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:output_type -> hyapp.user.v1.SetAgencyJoinEnabledResponse - 140, // [140:182] is the sub-list for method output_type - 98, // [98:140] is the sub-list for method input_type - 98, // [98:98] is the sub-list for extension type_name - 98, // [98:98] is the sub-list for extension extendee - 0, // [0:98] is the sub-list for field type_name + 103, // 97: hyapp.user.v1.GetHostEngagementStatsRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 97, // 98: hyapp.user.v1.GetHostEngagementStatsResponse.stats:type_name -> hyapp.user.v1.HostEngagementStats + 103, // 99: hyapp.user.v1.RecordPrivateMessageEventRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 0, // 100: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry.value:type_name -> hyapp.user.v1.HostProfile + 11, // 101: hyapp.user.v1.UserHostService.SearchAgencies:input_type -> hyapp.user.v1.SearchAgenciesRequest + 13, // 102: hyapp.user.v1.UserHostService.ApplyToAgency:input_type -> hyapp.user.v1.ApplyToAgencyRequest + 15, // 103: hyapp.user.v1.UserHostService.ReviewAgencyApplication:input_type -> hyapp.user.v1.ReviewAgencyApplicationRequest + 17, // 104: hyapp.user.v1.UserHostService.KickAgencyHost:input_type -> hyapp.user.v1.KickAgencyHostRequest + 19, // 105: hyapp.user.v1.UserHostService.InviteAgency:input_type -> hyapp.user.v1.InviteAgencyRequest + 21, // 106: hyapp.user.v1.UserHostService.InviteBD:input_type -> hyapp.user.v1.InviteBDRequest + 23, // 107: hyapp.user.v1.UserHostService.InviteHost:input_type -> hyapp.user.v1.InviteHostRequest + 25, // 108: hyapp.user.v1.UserHostService.ListBDLeaderBDs:input_type -> hyapp.user.v1.ListBDLeaderBDsRequest + 27, // 109: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:input_type -> hyapp.user.v1.ListBDLeaderAgenciesRequest + 32, // 110: hyapp.user.v1.UserHostService.ListBDAgencies:input_type -> hyapp.user.v1.ListBDAgenciesRequest + 29, // 111: hyapp.user.v1.UserHostService.ListManagerTeamAgencies:input_type -> hyapp.user.v1.ListManagerTeamAgenciesRequest + 34, // 112: hyapp.user.v1.UserHostService.ListRoleInvitations:input_type -> hyapp.user.v1.ListRoleInvitationsRequest + 36, // 113: hyapp.user.v1.UserHostService.GetRoleInvitation:input_type -> hyapp.user.v1.GetRoleInvitationRequest + 38, // 114: hyapp.user.v1.UserHostService.ProcessRoleInvitation:input_type -> hyapp.user.v1.ProcessRoleInvitationRequest + 40, // 115: hyapp.user.v1.UserHostService.GetHostProfile:input_type -> hyapp.user.v1.GetHostProfileRequest + 42, // 116: hyapp.user.v1.UserHostService.BatchGetHostProfiles:input_type -> hyapp.user.v1.BatchGetHostProfilesRequest + 44, // 117: hyapp.user.v1.UserHostService.GetBDProfile:input_type -> hyapp.user.v1.GetBDProfileRequest + 46, // 118: hyapp.user.v1.UserHostService.GetCoinSellerProfile:input_type -> hyapp.user.v1.GetCoinSellerProfileRequest + 48, // 119: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:input_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest + 50, // 120: hyapp.user.v1.UserHostService.CreateSubCoinSeller:input_type -> hyapp.user.v1.CreateSubCoinSellerRequest + 52, // 121: hyapp.user.v1.UserHostService.SubmitSubCoinSellerApplication:input_type -> hyapp.user.v1.SubmitSubCoinSellerApplicationRequest + 54, // 122: hyapp.user.v1.UserHostService.ListSubCoinSellers:input_type -> hyapp.user.v1.ListSubCoinSellersRequest + 56, // 123: hyapp.user.v1.UserHostService.CheckCoinSellerSubRelation:input_type -> hyapp.user.v1.CheckCoinSellerSubRelationRequest + 58, // 124: hyapp.user.v1.UserHostService.GetUserRoleSummary:input_type -> hyapp.user.v1.GetUserRoleSummaryRequest + 60, // 125: hyapp.user.v1.UserHostService.GetAgency:input_type -> hyapp.user.v1.GetAgencyRequest + 62, // 126: hyapp.user.v1.UserHostService.CheckBusinessCapability:input_type -> hyapp.user.v1.CheckBusinessCapabilityRequest + 65, // 127: hyapp.user.v1.UserHostService.GetRoleScopePolicy:input_type -> hyapp.user.v1.GetRoleScopePolicyRequest + 67, // 128: hyapp.user.v1.UserHostService.GetAgencyMembers:input_type -> hyapp.user.v1.GetAgencyMembersRequest + 69, // 129: hyapp.user.v1.UserHostService.GetAgencyApplications:input_type -> hyapp.user.v1.GetAgencyApplicationsRequest + 95, // 130: hyapp.user.v1.UserHostService.UpdateAgencyProfile:input_type -> hyapp.user.v1.UpdateAgencyProfileRequest + 98, // 131: hyapp.user.v1.UserHostService.GetHostEngagementStats:input_type -> hyapp.user.v1.GetHostEngagementStatsRequest + 100, // 132: hyapp.user.v1.UserHostService.RecordPrivateMessageEvent:input_type -> hyapp.user.v1.RecordPrivateMessageEventRequest + 71, // 133: hyapp.user.v1.UserHostAdminService.CreateBDLeader:input_type -> hyapp.user.v1.CreateBDLeaderRequest + 73, // 134: hyapp.user.v1.UserHostAdminService.CreateBD:input_type -> hyapp.user.v1.CreateBDRequest + 75, // 135: hyapp.user.v1.UserHostAdminService.SetBDStatus:input_type -> hyapp.user.v1.SetBDStatusRequest + 77, // 136: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:input_type -> hyapp.user.v1.CreateCoinSellerRequest + 79, // 137: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:input_type -> hyapp.user.v1.SetCoinSellerStatusRequest + 81, // 138: hyapp.user.v1.UserHostAdminService.ReviewSubCoinSellerApplication:input_type -> hyapp.user.v1.ReviewSubCoinSellerApplicationRequest + 83, // 139: hyapp.user.v1.UserHostAdminService.CreateAgency:input_type -> hyapp.user.v1.CreateAgencyRequest + 85, // 140: hyapp.user.v1.UserHostAdminService.AdminAddAgencyHost:input_type -> hyapp.user.v1.AdminAddAgencyHostRequest + 87, // 141: hyapp.user.v1.UserHostAdminService.CloseAgency:input_type -> hyapp.user.v1.CloseAgencyRequest + 89, // 142: hyapp.user.v1.UserHostAdminService.DeleteAgency:input_type -> hyapp.user.v1.DeleteAgencyRequest + 91, // 143: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:input_type -> hyapp.user.v1.SetAgencyStatusRequest + 93, // 144: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:input_type -> hyapp.user.v1.SetAgencyJoinEnabledRequest + 12, // 145: hyapp.user.v1.UserHostService.SearchAgencies:output_type -> hyapp.user.v1.SearchAgenciesResponse + 14, // 146: hyapp.user.v1.UserHostService.ApplyToAgency:output_type -> hyapp.user.v1.ApplyToAgencyResponse + 16, // 147: hyapp.user.v1.UserHostService.ReviewAgencyApplication:output_type -> hyapp.user.v1.ReviewAgencyApplicationResponse + 18, // 148: hyapp.user.v1.UserHostService.KickAgencyHost:output_type -> hyapp.user.v1.KickAgencyHostResponse + 20, // 149: hyapp.user.v1.UserHostService.InviteAgency:output_type -> hyapp.user.v1.InviteAgencyResponse + 22, // 150: hyapp.user.v1.UserHostService.InviteBD:output_type -> hyapp.user.v1.InviteBDResponse + 24, // 151: hyapp.user.v1.UserHostService.InviteHost:output_type -> hyapp.user.v1.InviteHostResponse + 26, // 152: hyapp.user.v1.UserHostService.ListBDLeaderBDs:output_type -> hyapp.user.v1.ListBDLeaderBDsResponse + 28, // 153: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:output_type -> hyapp.user.v1.ListBDLeaderAgenciesResponse + 33, // 154: hyapp.user.v1.UserHostService.ListBDAgencies:output_type -> hyapp.user.v1.ListBDAgenciesResponse + 31, // 155: hyapp.user.v1.UserHostService.ListManagerTeamAgencies:output_type -> hyapp.user.v1.ListManagerTeamAgenciesResponse + 35, // 156: hyapp.user.v1.UserHostService.ListRoleInvitations:output_type -> hyapp.user.v1.ListRoleInvitationsResponse + 37, // 157: hyapp.user.v1.UserHostService.GetRoleInvitation:output_type -> hyapp.user.v1.GetRoleInvitationResponse + 39, // 158: hyapp.user.v1.UserHostService.ProcessRoleInvitation:output_type -> hyapp.user.v1.ProcessRoleInvitationResponse + 41, // 159: hyapp.user.v1.UserHostService.GetHostProfile:output_type -> hyapp.user.v1.GetHostProfileResponse + 43, // 160: hyapp.user.v1.UserHostService.BatchGetHostProfiles:output_type -> hyapp.user.v1.BatchGetHostProfilesResponse + 45, // 161: hyapp.user.v1.UserHostService.GetBDProfile:output_type -> hyapp.user.v1.GetBDProfileResponse + 47, // 162: hyapp.user.v1.UserHostService.GetCoinSellerProfile:output_type -> hyapp.user.v1.GetCoinSellerProfileResponse + 49, // 163: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:output_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse + 51, // 164: hyapp.user.v1.UserHostService.CreateSubCoinSeller:output_type -> hyapp.user.v1.CreateSubCoinSellerResponse + 53, // 165: hyapp.user.v1.UserHostService.SubmitSubCoinSellerApplication:output_type -> hyapp.user.v1.SubmitSubCoinSellerApplicationResponse + 55, // 166: hyapp.user.v1.UserHostService.ListSubCoinSellers:output_type -> hyapp.user.v1.ListSubCoinSellersResponse + 57, // 167: hyapp.user.v1.UserHostService.CheckCoinSellerSubRelation:output_type -> hyapp.user.v1.CheckCoinSellerSubRelationResponse + 59, // 168: hyapp.user.v1.UserHostService.GetUserRoleSummary:output_type -> hyapp.user.v1.GetUserRoleSummaryResponse + 61, // 169: hyapp.user.v1.UserHostService.GetAgency:output_type -> hyapp.user.v1.GetAgencyResponse + 63, // 170: hyapp.user.v1.UserHostService.CheckBusinessCapability:output_type -> hyapp.user.v1.CheckBusinessCapabilityResponse + 66, // 171: hyapp.user.v1.UserHostService.GetRoleScopePolicy:output_type -> hyapp.user.v1.GetRoleScopePolicyResponse + 68, // 172: hyapp.user.v1.UserHostService.GetAgencyMembers:output_type -> hyapp.user.v1.GetAgencyMembersResponse + 70, // 173: hyapp.user.v1.UserHostService.GetAgencyApplications:output_type -> hyapp.user.v1.GetAgencyApplicationsResponse + 96, // 174: hyapp.user.v1.UserHostService.UpdateAgencyProfile:output_type -> hyapp.user.v1.UpdateAgencyProfileResponse + 99, // 175: hyapp.user.v1.UserHostService.GetHostEngagementStats:output_type -> hyapp.user.v1.GetHostEngagementStatsResponse + 101, // 176: hyapp.user.v1.UserHostService.RecordPrivateMessageEvent:output_type -> hyapp.user.v1.RecordPrivateMessageEventResponse + 72, // 177: hyapp.user.v1.UserHostAdminService.CreateBDLeader:output_type -> hyapp.user.v1.CreateBDLeaderResponse + 74, // 178: hyapp.user.v1.UserHostAdminService.CreateBD:output_type -> hyapp.user.v1.CreateBDResponse + 76, // 179: hyapp.user.v1.UserHostAdminService.SetBDStatus:output_type -> hyapp.user.v1.SetBDStatusResponse + 78, // 180: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:output_type -> hyapp.user.v1.CreateCoinSellerResponse + 80, // 181: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:output_type -> hyapp.user.v1.SetCoinSellerStatusResponse + 82, // 182: hyapp.user.v1.UserHostAdminService.ReviewSubCoinSellerApplication:output_type -> hyapp.user.v1.ReviewSubCoinSellerApplicationResponse + 84, // 183: hyapp.user.v1.UserHostAdminService.CreateAgency:output_type -> hyapp.user.v1.CreateAgencyResponse + 86, // 184: hyapp.user.v1.UserHostAdminService.AdminAddAgencyHost:output_type -> hyapp.user.v1.AdminAddAgencyHostResponse + 88, // 185: hyapp.user.v1.UserHostAdminService.CloseAgency:output_type -> hyapp.user.v1.CloseAgencyResponse + 90, // 186: hyapp.user.v1.UserHostAdminService.DeleteAgency:output_type -> hyapp.user.v1.DeleteAgencyResponse + 92, // 187: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:output_type -> hyapp.user.v1.SetAgencyStatusResponse + 94, // 188: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:output_type -> hyapp.user.v1.SetAgencyJoinEnabledResponse + 145, // [145:189] is the sub-list for method output_type + 101, // [101:145] is the sub-list for method input_type + 101, // [101:101] is the sub-list for extension type_name + 101, // [101:101] is the sub-list for extension extendee + 0, // [0:101] is the sub-list for field type_name } func init() { file_proto_user_v1_host_proto_init() } @@ -8378,7 +8771,7 @@ func file_proto_user_v1_host_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_user_v1_host_proto_rawDesc, NumEnums: 0, - NumMessages: 98, + NumMessages: 103, NumExtensions: 0, NumServices: 2, }, diff --git a/api/proto/user/v1/host.proto b/api/proto/user/v1/host.proto index fd74cd70..aa3d6060 100644 --- a/api/proto/user/v1/host.proto +++ b/api/proto/user/v1/host.proto @@ -698,6 +698,39 @@ message UpdateAgencyProfileResponse { Agency agency = 1; } +// HostEngagementStats 是 Fami 等公会中心使用的用户侧统计聚合;金额/礼物流水由 wallet-service 单独拥有。 +message HostEngagementStats { + int64 online_duration_ms = 1; + int64 valid_mic_duration_ms = 2; + int64 valid_mic_days = 3; + int64 private_message_senders = 4; + int64 new_followers = 5; +} + +message GetHostEngagementStatsRequest { + RequestMeta meta = 1; + int64 host_user_id = 2; + int64 start_at_ms = 3; + int64 end_at_ms = 4; +} + +message GetHostEngagementStatsResponse { + HostEngagementStats stats = 1; +} + +// RecordPrivateMessageEvent 由经过腾讯回调鉴权的 gateway 写入私信事实;重复 event_id 必须幂等。 +message RecordPrivateMessageEventRequest { + RequestMeta meta = 1; + string event_id = 2; + int64 sender_user_id = 3; + int64 target_user_id = 4; + int64 occurred_at_ms = 5; +} + +message RecordPrivateMessageEventResponse { + bool created = 1; +} + // UserHostService 是 user-service 内部 host domain 的 gRPC 面,不是独立微服务。 service UserHostService { rpc SearchAgencies(SearchAgenciesRequest) returns (SearchAgenciesResponse); @@ -731,6 +764,8 @@ service UserHostService { rpc GetAgencyMembers(GetAgencyMembersRequest) returns (GetAgencyMembersResponse); rpc GetAgencyApplications(GetAgencyApplicationsRequest) returns (GetAgencyApplicationsResponse); rpc UpdateAgencyProfile(UpdateAgencyProfileRequest) returns (UpdateAgencyProfileResponse); + rpc GetHostEngagementStats(GetHostEngagementStatsRequest) returns (GetHostEngagementStatsResponse); + rpc RecordPrivateMessageEvent(RecordPrivateMessageEventRequest) returns (RecordPrivateMessageEventResponse); } // UserHostAdminService 是后台关系管理入口;公网 admin 鉴权由 admin-server 承担。 diff --git a/api/proto/user/v1/host_grpc.pb.go b/api/proto/user/v1/host_grpc.pb.go index 7187085b..0eabb231 100644 --- a/api/proto/user/v1/host_grpc.pb.go +++ b/api/proto/user/v1/host_grpc.pb.go @@ -49,6 +49,8 @@ const ( UserHostService_GetAgencyMembers_FullMethodName = "/hyapp.user.v1.UserHostService/GetAgencyMembers" UserHostService_GetAgencyApplications_FullMethodName = "/hyapp.user.v1.UserHostService/GetAgencyApplications" UserHostService_UpdateAgencyProfile_FullMethodName = "/hyapp.user.v1.UserHostService/UpdateAgencyProfile" + UserHostService_GetHostEngagementStats_FullMethodName = "/hyapp.user.v1.UserHostService/GetHostEngagementStats" + UserHostService_RecordPrivateMessageEvent_FullMethodName = "/hyapp.user.v1.UserHostService/RecordPrivateMessageEvent" ) // UserHostServiceClient is the client API for UserHostService service. @@ -88,6 +90,8 @@ type UserHostServiceClient interface { GetAgencyMembers(ctx context.Context, in *GetAgencyMembersRequest, opts ...grpc.CallOption) (*GetAgencyMembersResponse, error) GetAgencyApplications(ctx context.Context, in *GetAgencyApplicationsRequest, opts ...grpc.CallOption) (*GetAgencyApplicationsResponse, error) UpdateAgencyProfile(ctx context.Context, in *UpdateAgencyProfileRequest, opts ...grpc.CallOption) (*UpdateAgencyProfileResponse, error) + GetHostEngagementStats(ctx context.Context, in *GetHostEngagementStatsRequest, opts ...grpc.CallOption) (*GetHostEngagementStatsResponse, error) + RecordPrivateMessageEvent(ctx context.Context, in *RecordPrivateMessageEventRequest, opts ...grpc.CallOption) (*RecordPrivateMessageEventResponse, error) } type userHostServiceClient struct { @@ -398,6 +402,26 @@ func (c *userHostServiceClient) UpdateAgencyProfile(ctx context.Context, in *Upd return out, nil } +func (c *userHostServiceClient) GetHostEngagementStats(ctx context.Context, in *GetHostEngagementStatsRequest, opts ...grpc.CallOption) (*GetHostEngagementStatsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetHostEngagementStatsResponse) + err := c.cc.Invoke(ctx, UserHostService_GetHostEngagementStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userHostServiceClient) RecordPrivateMessageEvent(ctx context.Context, in *RecordPrivateMessageEventRequest, opts ...grpc.CallOption) (*RecordPrivateMessageEventResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RecordPrivateMessageEventResponse) + err := c.cc.Invoke(ctx, UserHostService_RecordPrivateMessageEvent_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // UserHostServiceServer is the server API for UserHostService service. // All implementations must embed UnimplementedUserHostServiceServer // for forward compatibility. @@ -435,6 +459,8 @@ type UserHostServiceServer interface { GetAgencyMembers(context.Context, *GetAgencyMembersRequest) (*GetAgencyMembersResponse, error) GetAgencyApplications(context.Context, *GetAgencyApplicationsRequest) (*GetAgencyApplicationsResponse, error) UpdateAgencyProfile(context.Context, *UpdateAgencyProfileRequest) (*UpdateAgencyProfileResponse, error) + GetHostEngagementStats(context.Context, *GetHostEngagementStatsRequest) (*GetHostEngagementStatsResponse, error) + RecordPrivateMessageEvent(context.Context, *RecordPrivateMessageEventRequest) (*RecordPrivateMessageEventResponse, error) mustEmbedUnimplementedUserHostServiceServer() } @@ -535,6 +561,12 @@ func (UnimplementedUserHostServiceServer) GetAgencyApplications(context.Context, func (UnimplementedUserHostServiceServer) UpdateAgencyProfile(context.Context, *UpdateAgencyProfileRequest) (*UpdateAgencyProfileResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateAgencyProfile not implemented") } +func (UnimplementedUserHostServiceServer) GetHostEngagementStats(context.Context, *GetHostEngagementStatsRequest) (*GetHostEngagementStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetHostEngagementStats not implemented") +} +func (UnimplementedUserHostServiceServer) RecordPrivateMessageEvent(context.Context, *RecordPrivateMessageEventRequest) (*RecordPrivateMessageEventResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RecordPrivateMessageEvent not implemented") +} func (UnimplementedUserHostServiceServer) mustEmbedUnimplementedUserHostServiceServer() {} func (UnimplementedUserHostServiceServer) testEmbeddedByValue() {} @@ -1096,6 +1128,42 @@ func _UserHostService_UpdateAgencyProfile_Handler(srv interface{}, ctx context.C return interceptor(ctx, in, info, handler) } +func _UserHostService_GetHostEngagementStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetHostEngagementStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserHostServiceServer).GetHostEngagementStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserHostService_GetHostEngagementStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserHostServiceServer).GetHostEngagementStats(ctx, req.(*GetHostEngagementStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserHostService_RecordPrivateMessageEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RecordPrivateMessageEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserHostServiceServer).RecordPrivateMessageEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserHostService_RecordPrivateMessageEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserHostServiceServer).RecordPrivateMessageEvent(ctx, req.(*RecordPrivateMessageEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + // UserHostService_ServiceDesc is the grpc.ServiceDesc for UserHostService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1223,6 +1291,14 @@ var UserHostService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateAgencyProfile", Handler: _UserHostService_UpdateAgencyProfile_Handler, }, + { + MethodName: "GetHostEngagementStats", + Handler: _UserHostService_GetHostEngagementStats_Handler, + }, + { + MethodName: "RecordPrivateMessageEvent", + Handler: _UserHostService_RecordPrivateMessageEvent_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "proto/user/v1/host.proto", diff --git a/api/proto/wallet/v1/wallet.pb.go b/api/proto/wallet/v1/wallet.pb.go index 8572d8cf..eb3946a6 100644 --- a/api/proto/wallet/v1/wallet.pb.go +++ b/api/proto/wallet/v1/wallet.pb.go @@ -24547,6 +24547,1100 @@ func (x *GetGiftCatalogVersionResponse) GetVersion() int64 { return 0 } +// HostRevenueStats 聚合主播在自然日区间内的收益 POINT 和送礼用户;gateway 对外仍按产品文案展示为钻石。 +type HostRevenueStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DiamondEarnings int64 `protobuf:"varint,1,opt,name=diamond_earnings,json=diamondEarnings,proto3" json:"diamond_earnings,omitempty"` + DiamondExchanged int64 `protobuf:"varint,2,opt,name=diamond_exchanged,json=diamondExchanged,proto3" json:"diamond_exchanged,omitempty"` + GiftSenders int64 `protobuf:"varint,3,opt,name=gift_senders,json=giftSenders,proto3" json:"gift_senders,omitempty"` +} + +func (x *HostRevenueStats) Reset() { + *x = HostRevenueStats{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[275] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HostRevenueStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HostRevenueStats) ProtoMessage() {} + +func (x *HostRevenueStats) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[275] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HostRevenueStats.ProtoReflect.Descriptor instead. +func (*HostRevenueStats) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{275} +} + +func (x *HostRevenueStats) GetDiamondEarnings() int64 { + if x != nil { + return x.DiamondEarnings + } + return 0 +} + +func (x *HostRevenueStats) GetDiamondExchanged() int64 { + if x != nil { + return x.DiamondExchanged + } + return 0 +} + +func (x *HostRevenueStats) GetGiftSenders() int64 { + if x != nil { + return x.GiftSenders + } + return 0 +} + +type GetHostRevenueStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + HostUserId int64 `protobuf:"varint,3,opt,name=host_user_id,json=hostUserId,proto3" json:"host_user_id,omitempty"` + StartAtMs int64 `protobuf:"varint,4,opt,name=start_at_ms,json=startAtMs,proto3" json:"start_at_ms,omitempty"` + EndAtMs int64 `protobuf:"varint,5,opt,name=end_at_ms,json=endAtMs,proto3" json:"end_at_ms,omitempty"` +} + +func (x *GetHostRevenueStatsRequest) Reset() { + *x = GetHostRevenueStatsRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[276] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetHostRevenueStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetHostRevenueStatsRequest) ProtoMessage() {} + +func (x *GetHostRevenueStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[276] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetHostRevenueStatsRequest.ProtoReflect.Descriptor instead. +func (*GetHostRevenueStatsRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{276} +} + +func (x *GetHostRevenueStatsRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *GetHostRevenueStatsRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *GetHostRevenueStatsRequest) GetHostUserId() int64 { + if x != nil { + return x.HostUserId + } + return 0 +} + +func (x *GetHostRevenueStatsRequest) GetStartAtMs() int64 { + if x != nil { + return x.StartAtMs + } + return 0 +} + +func (x *GetHostRevenueStatsRequest) GetEndAtMs() int64 { + if x != nil { + return x.EndAtMs + } + return 0 +} + +type GetHostRevenueStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stats *HostRevenueStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` +} + +func (x *GetHostRevenueStatsResponse) Reset() { + *x = GetHostRevenueStatsResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[277] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetHostRevenueStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetHostRevenueStatsResponse) ProtoMessage() {} + +func (x *GetHostRevenueStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[277] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetHostRevenueStatsResponse.ProtoReflect.Descriptor instead. +func (*GetHostRevenueStatsResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{277} +} + +func (x *GetHostRevenueStatsResponse) GetStats() *HostRevenueStats { + if x != nil { + return x.Stats + } + return nil +} + +// AgencyPointShareStats 只统计独立 Agency 分成流水,不把 owner 自己的主播礼物收益重复算入分成。 +type AgencyPointShareStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShareIncome int64 `protobuf:"varint,1,opt,name=share_income,json=shareIncome,proto3" json:"share_income,omitempty"` + GiftedHostCount int64 `protobuf:"varint,2,opt,name=gifted_host_count,json=giftedHostCount,proto3" json:"gifted_host_count,omitempty"` +} + +func (x *AgencyPointShareStats) Reset() { + *x = AgencyPointShareStats{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[278] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgencyPointShareStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgencyPointShareStats) ProtoMessage() {} + +func (x *AgencyPointShareStats) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[278] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgencyPointShareStats.ProtoReflect.Descriptor instead. +func (*AgencyPointShareStats) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{278} +} + +func (x *AgencyPointShareStats) GetShareIncome() int64 { + if x != nil { + return x.ShareIncome + } + return 0 +} + +func (x *AgencyPointShareStats) GetGiftedHostCount() int64 { + if x != nil { + return x.GiftedHostCount + } + return 0 +} + +type GetAgencyPointShareStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + AgencyOwnerUserId int64 `protobuf:"varint,3,opt,name=agency_owner_user_id,json=agencyOwnerUserId,proto3" json:"agency_owner_user_id,omitempty"` + StartAtMs int64 `protobuf:"varint,4,opt,name=start_at_ms,json=startAtMs,proto3" json:"start_at_ms,omitempty"` + EndAtMs int64 `protobuf:"varint,5,opt,name=end_at_ms,json=endAtMs,proto3" json:"end_at_ms,omitempty"` +} + +func (x *GetAgencyPointShareStatsRequest) Reset() { + *x = GetAgencyPointShareStatsRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[279] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgencyPointShareStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgencyPointShareStatsRequest) ProtoMessage() {} + +func (x *GetAgencyPointShareStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[279] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAgencyPointShareStatsRequest.ProtoReflect.Descriptor instead. +func (*GetAgencyPointShareStatsRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{279} +} + +func (x *GetAgencyPointShareStatsRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *GetAgencyPointShareStatsRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *GetAgencyPointShareStatsRequest) GetAgencyOwnerUserId() int64 { + if x != nil { + return x.AgencyOwnerUserId + } + return 0 +} + +func (x *GetAgencyPointShareStatsRequest) GetStartAtMs() int64 { + if x != nil { + return x.StartAtMs + } + return 0 +} + +func (x *GetAgencyPointShareStatsRequest) GetEndAtMs() int64 { + if x != nil { + return x.EndAtMs + } + return 0 +} + +type GetAgencyPointShareStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stats *AgencyPointShareStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` +} + +func (x *GetAgencyPointShareStatsResponse) Reset() { + *x = GetAgencyPointShareStatsResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[280] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgencyPointShareStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgencyPointShareStatsResponse) ProtoMessage() {} + +func (x *GetAgencyPointShareStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[280] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAgencyPointShareStatsResponse.ProtoReflect.Descriptor instead. +func (*GetAgencyPointShareStatsResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{280} +} + +func (x *GetAgencyPointShareStatsResponse) GetStats() *AgencyPointShareStats { + if x != nil { + return x.Stats + } + return nil +} + +type AgencyHostGiftStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GiftIncome int64 `protobuf:"varint,1,opt,name=gift_income,json=giftIncome,proto3" json:"gift_income,omitempty"` + GiftedHostCount int64 `protobuf:"varint,2,opt,name=gifted_host_count,json=giftedHostCount,proto3" json:"gifted_host_count,omitempty"` +} + +func (x *AgencyHostGiftStats) Reset() { + *x = AgencyHostGiftStats{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[281] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgencyHostGiftStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgencyHostGiftStats) ProtoMessage() {} + +func (x *AgencyHostGiftStats) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[281] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgencyHostGiftStats.ProtoReflect.Descriptor instead. +func (*AgencyHostGiftStats) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{281} +} + +func (x *AgencyHostGiftStats) GetGiftIncome() int64 { + if x != nil { + return x.GiftIncome + } + return 0 +} + +func (x *AgencyHostGiftStats) GetGiftedHostCount() int64 { + if x != nil { + return x.GiftedHostCount + } + return 0 +} + +type GetAgencyHostGiftStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + HostUserIds []int64 `protobuf:"varint,3,rep,packed,name=host_user_ids,json=hostUserIds,proto3" json:"host_user_ids,omitempty"` + StartAtMs int64 `protobuf:"varint,4,opt,name=start_at_ms,json=startAtMs,proto3" json:"start_at_ms,omitempty"` + EndAtMs int64 `protobuf:"varint,5,opt,name=end_at_ms,json=endAtMs,proto3" json:"end_at_ms,omitempty"` +} + +func (x *GetAgencyHostGiftStatsRequest) Reset() { + *x = GetAgencyHostGiftStatsRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[282] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgencyHostGiftStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgencyHostGiftStatsRequest) ProtoMessage() {} + +func (x *GetAgencyHostGiftStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[282] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAgencyHostGiftStatsRequest.ProtoReflect.Descriptor instead. +func (*GetAgencyHostGiftStatsRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{282} +} + +func (x *GetAgencyHostGiftStatsRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *GetAgencyHostGiftStatsRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *GetAgencyHostGiftStatsRequest) GetHostUserIds() []int64 { + if x != nil { + return x.HostUserIds + } + return nil +} + +func (x *GetAgencyHostGiftStatsRequest) GetStartAtMs() int64 { + if x != nil { + return x.StartAtMs + } + return 0 +} + +func (x *GetAgencyHostGiftStatsRequest) GetEndAtMs() int64 { + if x != nil { + return x.EndAtMs + } + return 0 +} + +type GetAgencyHostGiftStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stats *AgencyHostGiftStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` +} + +func (x *GetAgencyHostGiftStatsResponse) Reset() { + *x = GetAgencyHostGiftStatsResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[283] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgencyHostGiftStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgencyHostGiftStatsResponse) ProtoMessage() {} + +func (x *GetAgencyHostGiftStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[283] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAgencyHostGiftStatsResponse.ProtoReflect.Descriptor instead. +func (*GetAgencyHostGiftStatsResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{283} +} + +func (x *GetAgencyHostGiftStatsResponse) GetStats() *AgencyHostGiftStats { + if x != nil { + return x.Stats + } + return nil +} + +// PointWithdrawalCoinSellerConfig 是按 App 隔离的 POINT 提现币商白名单与兑换比例。 +// 比例用整数分子/分母保存,避免浮点金额在 H5、gateway 和账本间产生舍入分歧。 +type PointWithdrawalCoinSellerConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppCode string `protobuf:"bytes,1,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + SellerUserId int64 `protobuf:"varint,2,opt,name=seller_user_id,json=sellerUserId,proto3" json:"seller_user_id,omitempty"` + SortOrder int32 `protobuf:"varint,3,opt,name=sort_order,json=sortOrder,proto3" json:"sort_order,omitempty"` + PointAmount int64 `protobuf:"varint,4,opt,name=point_amount,json=pointAmount,proto3" json:"point_amount,omitempty"` + SellerCoinAmount int64 `protobuf:"varint,5,opt,name=seller_coin_amount,json=sellerCoinAmount,proto3" json:"seller_coin_amount,omitempty"` + ServiceCountryCodes []string `protobuf:"bytes,6,rep,name=service_country_codes,json=serviceCountryCodes,proto3" json:"service_country_codes,omitempty"` + Status string `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` + CreatedAtMs int64 `protobuf:"varint,8,opt,name=created_at_ms,json=createdAtMs,proto3" json:"created_at_ms,omitempty"` + UpdatedAtMs int64 `protobuf:"varint,9,opt,name=updated_at_ms,json=updatedAtMs,proto3" json:"updated_at_ms,omitempty"` +} + +func (x *PointWithdrawalCoinSellerConfig) Reset() { + *x = PointWithdrawalCoinSellerConfig{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[284] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PointWithdrawalCoinSellerConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PointWithdrawalCoinSellerConfig) ProtoMessage() {} + +func (x *PointWithdrawalCoinSellerConfig) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[284] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PointWithdrawalCoinSellerConfig.ProtoReflect.Descriptor instead. +func (*PointWithdrawalCoinSellerConfig) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{284} +} + +func (x *PointWithdrawalCoinSellerConfig) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *PointWithdrawalCoinSellerConfig) GetSellerUserId() int64 { + if x != nil { + return x.SellerUserId + } + return 0 +} + +func (x *PointWithdrawalCoinSellerConfig) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +func (x *PointWithdrawalCoinSellerConfig) GetPointAmount() int64 { + if x != nil { + return x.PointAmount + } + return 0 +} + +func (x *PointWithdrawalCoinSellerConfig) GetSellerCoinAmount() int64 { + if x != nil { + return x.SellerCoinAmount + } + return 0 +} + +func (x *PointWithdrawalCoinSellerConfig) GetServiceCountryCodes() []string { + if x != nil { + return x.ServiceCountryCodes + } + return nil +} + +func (x *PointWithdrawalCoinSellerConfig) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *PointWithdrawalCoinSellerConfig) GetCreatedAtMs() int64 { + if x != nil { + return x.CreatedAtMs + } + return 0 +} + +func (x *PointWithdrawalCoinSellerConfig) GetUpdatedAtMs() int64 { + if x != nil { + return x.UpdatedAtMs + } + return 0 +} + +type ListPointWithdrawalCoinSellersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + // country_code 由 gateway 从登录用户资料注入;为空只用于 Admin/内部查询。 + CountryCode string `protobuf:"bytes,3,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` + IncludeDisabled bool `protobuf:"varint,4,opt,name=include_disabled,json=includeDisabled,proto3" json:"include_disabled,omitempty"` +} + +func (x *ListPointWithdrawalCoinSellersRequest) Reset() { + *x = ListPointWithdrawalCoinSellersRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[285] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPointWithdrawalCoinSellersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPointWithdrawalCoinSellersRequest) ProtoMessage() {} + +func (x *ListPointWithdrawalCoinSellersRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[285] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPointWithdrawalCoinSellersRequest.ProtoReflect.Descriptor instead. +func (*ListPointWithdrawalCoinSellersRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{285} +} + +func (x *ListPointWithdrawalCoinSellersRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *ListPointWithdrawalCoinSellersRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *ListPointWithdrawalCoinSellersRequest) GetCountryCode() string { + if x != nil { + return x.CountryCode + } + return "" +} + +func (x *ListPointWithdrawalCoinSellersRequest) GetIncludeDisabled() bool { + if x != nil { + return x.IncludeDisabled + } + return false +} + +type ListPointWithdrawalCoinSellersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sellers []*PointWithdrawalCoinSellerConfig `protobuf:"bytes,1,rep,name=sellers,proto3" json:"sellers,omitempty"` +} + +func (x *ListPointWithdrawalCoinSellersResponse) Reset() { + *x = ListPointWithdrawalCoinSellersResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[286] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPointWithdrawalCoinSellersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPointWithdrawalCoinSellersResponse) ProtoMessage() {} + +func (x *ListPointWithdrawalCoinSellersResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[286] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPointWithdrawalCoinSellersResponse.ProtoReflect.Descriptor instead. +func (*ListPointWithdrawalCoinSellersResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{286} +} + +func (x *ListPointWithdrawalCoinSellersResponse) GetSellers() []*PointWithdrawalCoinSellerConfig { + if x != nil { + return x.Sellers + } + return nil +} + +type TransferPointToCoinSellerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CommandId string `protobuf:"bytes,1,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + SourceUserId int64 `protobuf:"varint,3,opt,name=source_user_id,json=sourceUserId,proto3" json:"source_user_id,omitempty"` + SellerUserId int64 `protobuf:"varint,4,opt,name=seller_user_id,json=sellerUserId,proto3" json:"seller_user_id,omitempty"` + PointAmount int64 `protobuf:"varint,5,opt,name=point_amount,json=pointAmount,proto3" json:"point_amount,omitempty"` + // source_country_code 由 gateway 从用户资料读取,wallet 会再次校验币商服务国家。 + SourceCountryCode string `protobuf:"bytes,6,opt,name=source_country_code,json=sourceCountryCode,proto3" json:"source_country_code,omitempty"` + Reason string `protobuf:"bytes,7,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *TransferPointToCoinSellerRequest) Reset() { + *x = TransferPointToCoinSellerRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[287] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TransferPointToCoinSellerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferPointToCoinSellerRequest) ProtoMessage() {} + +func (x *TransferPointToCoinSellerRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[287] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferPointToCoinSellerRequest.ProtoReflect.Descriptor instead. +func (*TransferPointToCoinSellerRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{287} +} + +func (x *TransferPointToCoinSellerRequest) GetCommandId() string { + if x != nil { + return x.CommandId + } + return "" +} + +func (x *TransferPointToCoinSellerRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *TransferPointToCoinSellerRequest) GetSourceUserId() int64 { + if x != nil { + return x.SourceUserId + } + return 0 +} + +func (x *TransferPointToCoinSellerRequest) GetSellerUserId() int64 { + if x != nil { + return x.SellerUserId + } + return 0 +} + +func (x *TransferPointToCoinSellerRequest) GetPointAmount() int64 { + if x != nil { + return x.PointAmount + } + return 0 +} + +func (x *TransferPointToCoinSellerRequest) GetSourceCountryCode() string { + if x != nil { + return x.SourceCountryCode + } + return "" +} + +func (x *TransferPointToCoinSellerRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type TransferPointToCoinSellerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` + SourcePointBalanceAfter int64 `protobuf:"varint,2,opt,name=source_point_balance_after,json=sourcePointBalanceAfter,proto3" json:"source_point_balance_after,omitempty"` + SellerBalanceAfter int64 `protobuf:"varint,3,opt,name=seller_balance_after,json=sellerBalanceAfter,proto3" json:"seller_balance_after,omitempty"` + PointAmount int64 `protobuf:"varint,4,opt,name=point_amount,json=pointAmount,proto3" json:"point_amount,omitempty"` + SellerCoinAmount int64 `protobuf:"varint,5,opt,name=seller_coin_amount,json=sellerCoinAmount,proto3" json:"seller_coin_amount,omitempty"` + RatioPointAmount int64 `protobuf:"varint,6,opt,name=ratio_point_amount,json=ratioPointAmount,proto3" json:"ratio_point_amount,omitempty"` + RatioSellerCoinAmount int64 `protobuf:"varint,7,opt,name=ratio_seller_coin_amount,json=ratioSellerCoinAmount,proto3" json:"ratio_seller_coin_amount,omitempty"` +} + +func (x *TransferPointToCoinSellerResponse) Reset() { + *x = TransferPointToCoinSellerResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[288] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TransferPointToCoinSellerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferPointToCoinSellerResponse) ProtoMessage() {} + +func (x *TransferPointToCoinSellerResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[288] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferPointToCoinSellerResponse.ProtoReflect.Descriptor instead. +func (*TransferPointToCoinSellerResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{288} +} + +func (x *TransferPointToCoinSellerResponse) GetTransactionId() string { + if x != nil { + return x.TransactionId + } + return "" +} + +func (x *TransferPointToCoinSellerResponse) GetSourcePointBalanceAfter() int64 { + if x != nil { + return x.SourcePointBalanceAfter + } + return 0 +} + +func (x *TransferPointToCoinSellerResponse) GetSellerBalanceAfter() int64 { + if x != nil { + return x.SellerBalanceAfter + } + return 0 +} + +func (x *TransferPointToCoinSellerResponse) GetPointAmount() int64 { + if x != nil { + return x.PointAmount + } + return 0 +} + +func (x *TransferPointToCoinSellerResponse) GetSellerCoinAmount() int64 { + if x != nil { + return x.SellerCoinAmount + } + return 0 +} + +func (x *TransferPointToCoinSellerResponse) GetRatioPointAmount() int64 { + if x != nil { + return x.RatioPointAmount + } + return 0 +} + +func (x *TransferPointToCoinSellerResponse) GetRatioSellerCoinAmount() int64 { + if x != nil { + return x.RatioSellerCoinAmount + } + return 0 +} + +type GetPointWithdrawalConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + RegionId int64 `protobuf:"varint,3,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` + NowMs int64 `protobuf:"varint,4,opt,name=now_ms,json=nowMs,proto3" json:"now_ms,omitempty"` +} + +func (x *GetPointWithdrawalConfigRequest) Reset() { + *x = GetPointWithdrawalConfigRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[289] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPointWithdrawalConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPointWithdrawalConfigRequest) ProtoMessage() {} + +func (x *GetPointWithdrawalConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[289] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPointWithdrawalConfigRequest.ProtoReflect.Descriptor instead. +func (*GetPointWithdrawalConfigRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{289} +} + +func (x *GetPointWithdrawalConfigRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *GetPointWithdrawalConfigRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *GetPointWithdrawalConfigRequest) GetRegionId() int64 { + if x != nil { + return x.RegionId + } + return 0 +} + +func (x *GetPointWithdrawalConfigRequest) GetNowMs() int64 { + if x != nil { + return x.NowMs + } + return 0 +} + +type GetPointWithdrawalConfigResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Found bool `protobuf:"varint,1,opt,name=found,proto3" json:"found,omitempty"` + PointsPerUsd int64 `protobuf:"varint,2,opt,name=points_per_usd,json=pointsPerUsd,proto3" json:"points_per_usd,omitempty"` + FeeBps int32 `protobuf:"varint,3,opt,name=fee_bps,json=feeBps,proto3" json:"fee_bps,omitempty"` + MinimumPoints int64 `protobuf:"varint,4,opt,name=minimum_points,json=minimumPoints,proto3" json:"minimum_points,omitempty"` + PolicyInstanceCode string `protobuf:"bytes,5,opt,name=policy_instance_code,json=policyInstanceCode,proto3" json:"policy_instance_code,omitempty"` +} + +func (x *GetPointWithdrawalConfigResponse) Reset() { + *x = GetPointWithdrawalConfigResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[290] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPointWithdrawalConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPointWithdrawalConfigResponse) ProtoMessage() {} + +func (x *GetPointWithdrawalConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[290] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPointWithdrawalConfigResponse.ProtoReflect.Descriptor instead. +func (*GetPointWithdrawalConfigResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{290} +} + +func (x *GetPointWithdrawalConfigResponse) GetFound() bool { + if x != nil { + return x.Found + } + return false +} + +func (x *GetPointWithdrawalConfigResponse) GetPointsPerUsd() int64 { + if x != nil { + return x.PointsPerUsd + } + return 0 +} + +func (x *GetPointWithdrawalConfigResponse) GetFeeBps() int32 { + if x != nil { + return x.FeeBps + } + return 0 +} + +func (x *GetPointWithdrawalConfigResponse) GetMinimumPoints() int64 { + if x != nil { + return x.MinimumPoints + } + return 0 +} + +func (x *GetPointWithdrawalConfigResponse) GetPolicyInstanceCode() string { + if x != nil { + return x.PolicyInstanceCode + } + return "" +} + var File_proto_wallet_v1_wallet_proto protoreflect.FileDescriptor var file_proto_wallet_v1_wallet_proto_rawDesc = []byte{ @@ -29117,84 +30211,286 @@ var file_proto_wallet_v1_wallet_proto_rawDesc = []byte{ 0x39, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0xf4, 0x03, 0x0a, 0x11, 0x57, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x6e, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, 0x6f, 0x73, 0x74, 0x53, - 0x61, 0x6c, 0x61, 0x72, 0x79, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x72, 0x0a, 0x29, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, 0x6f, 0x73, 0x74, 0x53, - 0x61, 0x6c, 0x61, 0x72, 0x79, 0x48, 0x61, 0x6c, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x53, 0x65, - 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, - 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x45, 0x6e, - 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, - 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, - 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, - 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, - 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xe1, 0x6a, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, - 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x44, 0x65, 0x62, 0x69, 0x74, - 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, - 0x69, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, - 0x66, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e, 0x44, 0x65, - 0x62, 0x69, 0x74, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x26, 0x2e, 0x68, + 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x01, 0x0a, 0x10, 0x48, + 0x6f, 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x29, 0x0a, 0x10, 0x64, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x5f, 0x65, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x64, 0x69, 0x61, 0x6d, 0x6f, + 0x6e, 0x64, 0x45, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, + 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x5f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x64, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x45, 0x78, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x69, 0x66, 0x74, 0x5f, + 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x67, + 0x69, 0x66, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x22, 0xb4, 0x01, 0x0a, 0x1a, 0x47, + 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x61, + 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x1a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x5f, + 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x4d, + 0x73, 0x22, 0x56, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, + 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x37, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x66, 0x0a, 0x15, 0x41, 0x67, 0x65, + 0x6e, 0x63, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6f, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x65, 0x49, + 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x69, 0x66, 0x74, 0x65, 0x64, 0x5f, + 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0f, 0x67, 0x69, 0x66, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0xc8, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x2f, 0x0a, 0x14, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x61, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x74, 0x4d, 0x73, + 0x12, 0x1a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0x60, 0x0a, 0x20, + 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3c, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x62, + 0x0a, 0x13, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x69, 0x66, 0x74, 0x5f, 0x69, 0x6e, + 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x67, 0x69, 0x66, 0x74, + 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x69, 0x66, 0x74, 0x65, 0x64, + 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x67, 0x69, 0x66, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, + 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x22, + 0x0a, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x61, 0x74, 0x5f, 0x6d, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x74, + 0x4d, 0x73, 0x12, 0x1a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0x5c, + 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, + 0x69, 0x66, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0xe6, 0x02, 0x0a, + 0x1f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, + 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x73, + 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, + 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x10, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, + 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x0a, + 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, + 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, + 0x6d, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0xaf, 0x01, 0x0a, 0x25, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x69, + 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x10, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x74, 0x0a, 0x26, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x93, 0x02, + 0x0a, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x54, + 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x6c, + 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x22, 0xf1, 0x02, 0x0a, 0x21, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x30, 0x0a, + 0x14, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65, 0x6c, + 0x6c, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, + 0x21, 0x0a, 0x0c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x69, + 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, + 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, + 0x0a, 0x18, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, + 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x15, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x69, + 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, + 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, + 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x77, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x6e, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0xd0, 0x01, 0x0a, 0x20, 0x47, 0x65, + 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x50, 0x65, 0x72, 0x55, 0x73, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x65, + 0x65, 0x5f, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x65, 0x65, + 0x42, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x69, 0x6e, + 0x69, 0x6d, 0x75, 0x6d, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x32, 0xf4, 0x03, 0x0a, + 0x11, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x6e, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, 0x6f, 0x73, + 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x72, 0x0a, 0x29, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, 0x6f, 0x73, + 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x48, 0x61, 0x6c, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x74, 0x68, + 0x45, 0x6e, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x91, 0x01, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, + 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, + 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x32, 0xe9, 0x70, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, + 0x66, 0x74, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x44, 0x65, 0x62, + 0x69, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x62, 0x69, 0x74, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x73, 0x74, - 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x48, - 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x48, 0x6f, - 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, - 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x65, 0x62, 0x69, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x62, 0x69, 0x74, + 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e, + 0x44, 0x65, 0x62, 0x69, 0x74, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x47, 0x69, 0x66, 0x74, 0x12, 0x26, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x47, 0x69, 0x66, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x47, 0x69, + 0x66, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0b, 0x47, 0x65, + 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x48, 0x6f, + 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x47, 0x65, 0x74, + 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, + 0x72, 0x79, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, + 0x79, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x70, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, + 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, + 0x73, 0x74, 0x52, 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2e, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, + 0x66, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x69, + 0x66, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, @@ -29261,752 +30557,778 @@ var file_proto_wallet_v1_wallet_proto_rawDesc = []byte{ 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x54, 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x79, 0x0a, 0x16, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, - 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, - 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, - 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, - 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, - 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x53, - 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x61, - 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x61, - 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, - 0x6c, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, - 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x61, 0x6c, 0x61, - 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2d, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, - 0x72, 0x65, 0x65, 0x7a, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, - 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, - 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, - 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2e, + 0x12, 0x91, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, + 0x65, 0x72, 0x73, 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, + 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, + 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, + 0x65, 0x72, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x54, 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x6f, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x47, 0x65, 0x74, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x46, 0x72, + 0x65, 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, + 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x53, 0x61, 0x6c, + 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, + 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, + 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, + 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2f, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, 0x64, + 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x61, 0x6c, 0x61, 0x72, 0x79, 0x57, 0x69, 0x74, 0x68, + 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, + 0x0a, 0x15, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, + 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, + 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, + 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x5e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x58, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2a, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, + 0x2e, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, + 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, + 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, + 0x73, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, + 0x73, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x28, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x6a, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x13, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x27, 0x2e, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0b, 0x47, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x70, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, - 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5b, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, + 0x11, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5b, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, + 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x67, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, - 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x13, 0x53, - 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x69, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2b, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x70, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, + 0x47, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x14, 0x55, 0x70, 0x73, 0x65, 0x72, - 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0d, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x12, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2a, 0x2e, 0x68, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, + 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, + 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, + 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x65, 0x74, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, + 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x69, 0x66, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x69, 0x66, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6d, 0x0a, 0x14, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, + 0x72, 0x74, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x66, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5e, 0x0a, 0x0d, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x6a, 0x0a, 0x13, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x45, 0x71, 0x75, 0x69, - 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x45, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, - 0x65, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, - 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x1d, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x71, - 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x12, 0x68, 0x0a, 0x12, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x45, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, + 0x0a, 0x13, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x8e, 0x01, 0x0a, 0x1d, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x45, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x45, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x76, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, - 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, - 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, - 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, - 0x0a, 0x17, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, - 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, - 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, - 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x19, - 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, - 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, 0x75, 0x72, 0x63, - 0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, 0x75, 0x72, - 0x63, 0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x50, - 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, - 0x73, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, - 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, - 0x68, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, - 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x42, 0x69, 0x6c, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x76, - 0x69, 0x65, 0x77, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, + 0x65, 0x6d, 0x73, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, - 0x72, 0x69, 0x63, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, - 0x0a, 0x11, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x76, - 0x69, 0x65, 0x77, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4f, - 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, - 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x47, 0x65, - 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x69, 0x66, - 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, - 0x69, 0x66, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x69, 0x66, 0x74, 0x57, 0x61, 0x6c, 0x6c, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, - 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, - 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x47, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, - 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, - 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x63, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, - 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x15, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, - 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x74, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x63, - 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, 0x72, - 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, 0x72, - 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x91, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x54, 0x68, 0x69, 0x72, - 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, - 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, - 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x50, + 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, + 0x6d, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x6f, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, + 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2e, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, + 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, + 0x68, 0x61, 0x72, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x12, 0x2f, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x4f, + 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x42, 0x69, 0x6c, 0x6c, + 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x85, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x47, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x57, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x12, 0x29, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, + 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2d, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x69, 0x66, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x12, + 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x69, 0x66, 0x74, 0x57, 0x61, 0x6c, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x47, 0x69, 0x66, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, + 0x19, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x70, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, + 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x2d, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x2d, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, + 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, + 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x68, 0x69, + 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, + 0x01, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, + 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, - 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x69, - 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8b, 0x01, 0x0a, - 0x1c, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x34, 0x2e, + 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x84, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, + 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, + 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, + 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, + 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8b, 0x01, 0x0a, 0x1c, 0x53, 0x79, 0x6e, 0x63, 0x54, + 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x68, + 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, - 0x61, 0x72, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x15, 0x4c, 0x69, - 0x73, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x15, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x35, 0x52, 0x65, - 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x1c, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x19, - 0x47, 0x65, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x35, 0x52, 0x65, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, + 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x35, + 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, - 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x6a, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, - 0x68, 0x61, 0x72, 0x67, 0x65, 0x54, 0x78, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, - 0x12, 0x47, 0x65, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, - 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x1f, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, - 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x37, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, - 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, - 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x70, 0x0a, 0x13, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x4d, 0x69, 0x66, 0x61, 0x70, 0x61, - 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x4d, 0x69, 0x66, 0x61, 0x70, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x4d, 0x69, 0x66, - 0x61, 0x70, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x35, 0x50, 0x61, - 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x56, 0x35, 0x50, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x35, 0x50, 0x61, 0x79, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, - 0x0a, 0x18, 0x47, 0x65, 0x74, 0x44, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x45, 0x78, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x44, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x44, 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x79, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x56, 0x69, 0x70, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x27, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x56, 0x69, 0x70, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x64, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x69, 0x70, - 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x70, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x69, 0x70, - 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, - 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x12, 0x20, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x69, 0x70, 0x42, - 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x69, - 0x70, 0x42, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x69, 0x70, 0x42, 0x65, 0x6e, 0x65, 0x66, 0x69, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0b, 0x50, 0x75, 0x72, - 0x63, 0x68, 0x61, 0x73, 0x65, 0x56, 0x69, 0x70, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, - 0x61, 0x73, 0x65, 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x88, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, + 0x6f, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x12, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x54, + 0x78, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x44, 0x65, 0x62, 0x69, 0x74, 0x43, 0x50, 0x42, 0x72, - 0x65, 0x61, 0x6b, 0x75, 0x70, 0x46, 0x65, 0x65, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, - 0x43, 0x50, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x75, 0x70, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x43, 0x50, 0x42, 0x72, 0x65, - 0x61, 0x6b, 0x75, 0x70, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x61, 0x0a, 0x0e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x72, 0x61, - 0x77, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x72, - 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, - 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x08, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x12, 0x20, + 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x48, 0x35, + 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x2a, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x48, 0x35, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x35, 0x52, 0x65, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x1f, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, + 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x48, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x4d, 0x69, 0x66, 0x61, 0x70, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x4d, 0x69, 0x66, 0x61, 0x70, 0x61, + 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x54, - 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x4d, 0x69, 0x66, 0x61, 0x70, 0x61, 0x79, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x35, 0x50, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x35, 0x50, 0x61, 0x79, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x35, 0x50, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x44, + 0x69, 0x61, 0x6d, 0x6f, 0x6e, 0x64, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x61, 0x6d, 0x6f, 0x6e, + 0x64, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x61, 0x6d, + 0x6f, 0x6e, 0x64, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x16, 0x4c, 0x69, 0x73, + 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x69, 0x70, 0x50, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x69, + 0x70, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x69, 0x70, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, + 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x08, + 0x47, 0x65, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, + 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x79, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, + 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x69, 0x70, 0x42, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, + 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x69, 0x70, 0x42, 0x65, 0x6e, 0x65, 0x66, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x56, 0x69, 0x70, 0x42, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0b, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x56, + 0x69, 0x70, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x56, 0x69, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, + 0x73, 0x65, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, + 0x11, 0x44, 0x65, 0x62, 0x69, 0x74, 0x43, 0x50, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x75, 0x70, 0x46, + 0x65, 0x65, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x43, 0x50, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x75, 0x70, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x62, 0x69, 0x74, 0x43, 0x50, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x75, 0x70, 0x46, 0x65, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x44, 0x65, 0x62, + 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x72, 0x61, 0x77, 0x12, 0x26, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x62, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x72, 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x62, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, + 0x44, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x08, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x54, 0x72, - 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6a, 0x0a, 0x11, 0x45, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, - 0x43, 0x61, 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, - 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x55, + 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x56, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, + 0x11, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, + 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, + 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x45, 0x71, 0x75, + 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x12, 0x29, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x71, 0x75, 0x69, + 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, + 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x12, 0x2b, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, - 0x72, 0x64, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, - 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, - 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, - 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, - 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x73, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, - 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x88, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, - 0x6e, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, - 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, - 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, + 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x71, + 0x75, 0x69, 0x70, 0x56, 0x69, 0x70, 0x54, 0x72, 0x69, 0x61, 0x6c, 0x43, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x12, 0x2a, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x12, 0x2c, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x1b, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x34, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x56, 0x69, + 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x79, 0x56, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2b, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x79, 0x56, 0x69, - 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, - 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x56, - 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, - 0x65, 0x12, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, - 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, - 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, - 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x79, - 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x39, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, + 0x4d, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, + 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x12, 0x36, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x4d, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, + 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, + 0x62, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, + 0x20, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, + 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, + 0x73, 0x12, 0x38, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, - 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, + 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x79, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, + 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x17, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x10, 0x43, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x28, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x65, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, 0x6c, + 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x69, 0x70, 0x44, 0x61, 0x69, + 0x6c, 0x79, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x62, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x61, + 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x4c, 0x75, 0x63, - 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x2d, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x4c, 0x75, 0x63, 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, - 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x4c, 0x75, 0x63, 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x77, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x43, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, - 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x52, 0x65, - 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x77, - 0x61, 0x72, 0x64, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x6d, - 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, - 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x52, 0x6f, - 0x6f, 0x6d, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, - 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x82, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, - 0x79, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x31, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x70, 0x65, - 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, - 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x61, - 0x6d, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x70, 0x70, 0x6c, 0x79, 0x47, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, - 0x79, 0x47, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x2e, - 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, - 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, - 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, + 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, + 0x15, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x4c, 0x75, 0x63, 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, + 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x4c, + 0x75, 0x63, 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x4c, 0x75, + 0x63, 0x6b, 0x79, 0x47, 0x69, 0x66, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x57, + 0x68, 0x65, 0x65, 0x6c, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x64, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, - 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0c, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, + 0x64, 0x69, 0x74, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x57, 0x68, + 0x65, 0x65, 0x6c, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x7f, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x54, + 0x75, 0x72, 0x6e, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x30, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x54, 0x75, 0x72, 0x6e, + 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x76, + 0x69, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x77, 0x61, 0x72, + 0x64, 0x12, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x49, 0x6e, + 0x76, 0x69, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x77, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x19, 0x43, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x70, 0x65, 0x6e, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x70, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x69, 0x6e, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x61, + 0x6d, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x61, 0x6d, 0x65, 0x43, + 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x76, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x64, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, + 0x0a, 0x0e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, + 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x61, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, + 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x69, 0x72, - 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, - 0x70, 0x69, 0x72, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, + 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x67, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x52, 0x65, - 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x73, 0x0a, 0x14, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, - 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, - 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2a, 0x5a, 0x28, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, - 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x14, 0x52, 0x65, + 0x74, 0x72, 0x79, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x66, 0x75, + 0x6e, 0x64, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x2a, 0x5a, 0x28, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, + 0x76, 0x31, 0x3b, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -30021,7 +31343,7 @@ func file_proto_wallet_v1_wallet_proto_rawDescGZIP() []byte { return file_proto_wallet_v1_wallet_proto_rawDescData } -var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 276) +var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 292) var file_proto_wallet_v1_wallet_proto_goTypes = []any{ (*DebitGiftRequest)(nil), // 0: hyapp.wallet.v1.DebitGiftRequest (*DebitDirectGiftRequest)(nil), // 1: hyapp.wallet.v1.DebitDirectGiftRequest @@ -30298,7 +31620,23 @@ var file_proto_wallet_v1_wallet_proto_goTypes = []any{ (*ListResourceShopPurchaseOrdersResponse)(nil), // 272: hyapp.wallet.v1.ListResourceShopPurchaseOrdersResponse (*GetGiftCatalogVersionRequest)(nil), // 273: hyapp.wallet.v1.GetGiftCatalogVersionRequest (*GetGiftCatalogVersionResponse)(nil), // 274: hyapp.wallet.v1.GetGiftCatalogVersionResponse - nil, // 275: hyapp.wallet.v1.HandleV5PayNotifyRequest.FieldsEntry + (*HostRevenueStats)(nil), // 275: hyapp.wallet.v1.HostRevenueStats + (*GetHostRevenueStatsRequest)(nil), // 276: hyapp.wallet.v1.GetHostRevenueStatsRequest + (*GetHostRevenueStatsResponse)(nil), // 277: hyapp.wallet.v1.GetHostRevenueStatsResponse + (*AgencyPointShareStats)(nil), // 278: hyapp.wallet.v1.AgencyPointShareStats + (*GetAgencyPointShareStatsRequest)(nil), // 279: hyapp.wallet.v1.GetAgencyPointShareStatsRequest + (*GetAgencyPointShareStatsResponse)(nil), // 280: hyapp.wallet.v1.GetAgencyPointShareStatsResponse + (*AgencyHostGiftStats)(nil), // 281: hyapp.wallet.v1.AgencyHostGiftStats + (*GetAgencyHostGiftStatsRequest)(nil), // 282: hyapp.wallet.v1.GetAgencyHostGiftStatsRequest + (*GetAgencyHostGiftStatsResponse)(nil), // 283: hyapp.wallet.v1.GetAgencyHostGiftStatsResponse + (*PointWithdrawalCoinSellerConfig)(nil), // 284: hyapp.wallet.v1.PointWithdrawalCoinSellerConfig + (*ListPointWithdrawalCoinSellersRequest)(nil), // 285: hyapp.wallet.v1.ListPointWithdrawalCoinSellersRequest + (*ListPointWithdrawalCoinSellersResponse)(nil), // 286: hyapp.wallet.v1.ListPointWithdrawalCoinSellersResponse + (*TransferPointToCoinSellerRequest)(nil), // 287: hyapp.wallet.v1.TransferPointToCoinSellerRequest + (*TransferPointToCoinSellerResponse)(nil), // 288: hyapp.wallet.v1.TransferPointToCoinSellerResponse + (*GetPointWithdrawalConfigRequest)(nil), // 289: hyapp.wallet.v1.GetPointWithdrawalConfigRequest + (*GetPointWithdrawalConfigResponse)(nil), // 290: hyapp.wallet.v1.GetPointWithdrawalConfigResponse + nil, // 291: hyapp.wallet.v1.HandleV5PayNotifyRequest.FieldsEntry } var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{ 3, // 0: hyapp.wallet.v1.BatchDebitGiftRequest.targets:type_name -> hyapp.wallet.v1.DebitGiftTarget @@ -30380,7 +31718,7 @@ var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{ 153, // 76: hyapp.wallet.v1.H5RechargeOptionsResponse.payment_methods:type_name -> hyapp.wallet.v1.ThirdPartyPaymentMethod 165, // 77: hyapp.wallet.v1.ListTemporaryRechargeOrdersResponse.orders:type_name -> hyapp.wallet.v1.ExternalRechargeOrder 165, // 78: hyapp.wallet.v1.H5RechargeOrderResponse.order:type_name -> hyapp.wallet.v1.ExternalRechargeOrder - 275, // 79: hyapp.wallet.v1.HandleV5PayNotifyRequest.fields:type_name -> hyapp.wallet.v1.HandleV5PayNotifyRequest.FieldsEntry + 291, // 79: hyapp.wallet.v1.HandleV5PayNotifyRequest.fields:type_name -> hyapp.wallet.v1.HandleV5PayNotifyRequest.FieldsEntry 180, // 80: hyapp.wallet.v1.GetDiamondExchangeConfigResponse.rules:type_name -> hyapp.wallet.v1.DiamondExchangeRule 183, // 81: hyapp.wallet.v1.ListWalletTransactionsResponse.transactions:type_name -> hyapp.wallet.v1.WalletTransaction 186, // 82: hyapp.wallet.v1.VipLevel.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem @@ -30445,255 +31783,271 @@ var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{ 251, // 141: hyapp.wallet.v1.RetryRedPacketRefundResponse.packet:type_name -> hyapp.wallet.v1.RedPacket 48, // 142: hyapp.wallet.v1.ResourceShopPurchaseOrder.resource:type_name -> hyapp.wallet.v1.Resource 270, // 143: hyapp.wallet.v1.ListResourceShopPurchaseOrdersResponse.orders:type_name -> hyapp.wallet.v1.ResourceShopPurchaseOrder - 268, // 144: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryDailySettlementBatch:input_type -> hyapp.wallet.v1.CronBatchRequest - 268, // 145: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryHalfMonthSettlementBatch:input_type -> hyapp.wallet.v1.CronBatchRequest - 268, // 146: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryMonthEndBatch:input_type -> hyapp.wallet.v1.CronBatchRequest - 214, // 147: hyapp.wallet.v1.WalletCronService.ProcessVipDailyCoinRebateBatch:input_type -> hyapp.wallet.v1.ProcessVipDailyCoinRebateBatchRequest - 0, // 148: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest - 1, // 149: hyapp.wallet.v1.WalletService.DebitDirectGift:input_type -> hyapp.wallet.v1.DebitDirectGiftRequest - 4, // 150: hyapp.wallet.v1.WalletService.BatchDebitGift:input_type -> hyapp.wallet.v1.BatchDebitGiftRequest - 7, // 151: hyapp.wallet.v1.WalletService.DebitRobotGift:input_type -> hyapp.wallet.v1.DebitRobotGiftRequest - 9, // 152: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest - 13, // 153: hyapp.wallet.v1.WalletService.GetActiveHostSalaryPolicy:input_type -> hyapp.wallet.v1.GetActiveHostSalaryPolicyRequest - 16, // 154: hyapp.wallet.v1.WalletService.GetHostSalaryProgress:input_type -> hyapp.wallet.v1.GetHostSalaryProgressRequest - 19, // 155: hyapp.wallet.v1.WalletService.GetTeamHostSalaryStats:input_type -> hyapp.wallet.v1.GetTeamHostSalaryStatsRequest - 21, // 156: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest - 23, // 157: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest - 25, // 158: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest - 27, // 159: hyapp.wallet.v1.WalletService.TransferCoinSellerStockToChild:input_type -> hyapp.wallet.v1.TransferCoinSellerStockToChildRequest - 30, // 160: hyapp.wallet.v1.WalletService.ListCoinSellerSalaryExchangeRateTiers:input_type -> hyapp.wallet.v1.ListCoinSellerSalaryExchangeRateTiersRequest - 32, // 161: hyapp.wallet.v1.WalletService.ExchangeSalaryToCoin:input_type -> hyapp.wallet.v1.ExchangeSalaryToCoinRequest - 34, // 162: hyapp.wallet.v1.WalletService.TransferSalaryToCoinSeller:input_type -> hyapp.wallet.v1.TransferSalaryToCoinSellerRequest - 36, // 163: hyapp.wallet.v1.WalletService.FreezeSalaryWithdrawal:input_type -> hyapp.wallet.v1.FreezeSalaryWithdrawalRequest - 38, // 164: hyapp.wallet.v1.WalletService.SettleSalaryWithdrawal:input_type -> hyapp.wallet.v1.SettleSalaryWithdrawalRequest - 40, // 165: hyapp.wallet.v1.WalletService.ReleaseSalaryWithdrawal:input_type -> hyapp.wallet.v1.ReleaseSalaryWithdrawalRequest - 42, // 166: hyapp.wallet.v1.WalletService.FreezePointWithdrawal:input_type -> hyapp.wallet.v1.FreezePointWithdrawalRequest - 44, // 167: hyapp.wallet.v1.WalletService.SettlePointWithdrawal:input_type -> hyapp.wallet.v1.SettlePointWithdrawalRequest - 46, // 168: hyapp.wallet.v1.WalletService.ReleasePointWithdrawal:input_type -> hyapp.wallet.v1.ReleasePointWithdrawalRequest - 58, // 169: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest - 60, // 170: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest - 62, // 171: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest - 63, // 172: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest - 64, // 173: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest - 65, // 174: hyapp.wallet.v1.WalletService.DeleteResource:input_type -> hyapp.wallet.v1.DeleteResourceRequest - 66, // 175: hyapp.wallet.v1.WalletService.BatchDeleteResources:input_type -> hyapp.wallet.v1.BatchDeleteResourcesRequest - 69, // 176: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest - 71, // 177: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest - 73, // 178: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest - 74, // 179: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest - 75, // 180: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest - 77, // 181: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest - 79, // 182: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest - 273, // 183: hyapp.wallet.v1.WalletService.GetGiftCatalogVersion:input_type -> hyapp.wallet.v1.GetGiftCatalogVersionRequest - 83, // 184: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest - 84, // 185: hyapp.wallet.v1.WalletService.BatchCreateGiftConfigs:input_type -> hyapp.wallet.v1.BatchCreateGiftConfigsRequest - 86, // 186: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest - 87, // 187: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest - 88, // 188: hyapp.wallet.v1.WalletService.DeleteGiftConfig:input_type -> hyapp.wallet.v1.DeleteGiftConfigRequest - 81, // 189: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest - 90, // 190: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest - 91, // 191: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest - 92, // 192: hyapp.wallet.v1.WalletService.RevokeResourceGrant:input_type -> hyapp.wallet.v1.RevokeResourceGrantRequest - 94, // 193: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest - 96, // 194: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest - 98, // 195: hyapp.wallet.v1.WalletService.UnequipUserResource:input_type -> hyapp.wallet.v1.UnequipUserResourceRequest - 100, // 196: hyapp.wallet.v1.WalletService.BatchGetUserEquippedResources:input_type -> hyapp.wallet.v1.BatchGetUserEquippedResourcesRequest - 103, // 197: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest - 106, // 198: hyapp.wallet.v1.WalletService.ListResourceShopItems:input_type -> hyapp.wallet.v1.ListResourceShopItemsRequest - 108, // 199: hyapp.wallet.v1.WalletService.UpsertResourceShopItems:input_type -> hyapp.wallet.v1.UpsertResourceShopItemsRequest - 110, // 200: hyapp.wallet.v1.WalletService.SetResourceShopItemStatus:input_type -> hyapp.wallet.v1.SetResourceShopItemStatusRequest - 271, // 201: hyapp.wallet.v1.WalletService.ListResourceShopPurchaseOrders:input_type -> hyapp.wallet.v1.ListResourceShopPurchaseOrdersRequest - 112, // 202: hyapp.wallet.v1.WalletService.PurchaseResourceShopItem:input_type -> hyapp.wallet.v1.PurchaseResourceShopItemRequest - 115, // 203: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest - 117, // 204: hyapp.wallet.v1.WalletService.GetRechargeBillSummary:input_type -> hyapp.wallet.v1.GetRechargeBillSummaryRequest - 121, // 205: hyapp.wallet.v1.WalletService.BatchGetUserRechargeStats:input_type -> hyapp.wallet.v1.BatchGetUserRechargeStatsRequest - 123, // 206: hyapp.wallet.v1.WalletService.GetRechargeBillOverview:input_type -> hyapp.wallet.v1.GetRechargeBillOverviewRequest - 129, // 207: hyapp.wallet.v1.WalletService.RefreshGooglePaymentPrices:input_type -> hyapp.wallet.v1.RefreshGooglePaymentPricesRequest - 133, // 208: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest - 136, // 209: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest - 139, // 210: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest - 142, // 211: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest - 144, // 212: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:input_type -> hyapp.wallet.v1.ConfirmGooglePaymentRequest - 146, // 213: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest - 148, // 214: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest - 149, // 215: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest - 150, // 216: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest - 155, // 217: hyapp.wallet.v1.WalletService.ListThirdPartyPaymentChannels:input_type -> hyapp.wallet.v1.ListThirdPartyPaymentChannelsRequest - 157, // 218: hyapp.wallet.v1.WalletService.SetThirdPartyPaymentMethodStatus:input_type -> hyapp.wallet.v1.SetThirdPartyPaymentMethodStatusRequest - 159, // 219: hyapp.wallet.v1.WalletService.UpdateThirdPartyPaymentRate:input_type -> hyapp.wallet.v1.UpdateThirdPartyPaymentRateRequest - 161, // 220: hyapp.wallet.v1.WalletService.SyncThirdPartyPaymentMethods:input_type -> hyapp.wallet.v1.SyncThirdPartyPaymentMethodsRequest - 163, // 221: hyapp.wallet.v1.WalletService.ListH5RechargeOptions:input_type -> hyapp.wallet.v1.H5RechargeOptionsRequest - 166, // 222: hyapp.wallet.v1.WalletService.CreateH5RechargeOrder:input_type -> hyapp.wallet.v1.CreateH5RechargeOrderRequest - 167, // 223: hyapp.wallet.v1.WalletService.CreateTemporaryRechargeOrder:input_type -> hyapp.wallet.v1.CreateTemporaryRechargeOrderRequest - 168, // 224: hyapp.wallet.v1.WalletService.GetTemporaryRechargeOrder:input_type -> hyapp.wallet.v1.GetTemporaryRechargeOrderRequest - 169, // 225: hyapp.wallet.v1.WalletService.ListTemporaryRechargeOrders:input_type -> hyapp.wallet.v1.ListTemporaryRechargeOrdersRequest - 171, // 226: hyapp.wallet.v1.WalletService.SubmitH5RechargeTx:input_type -> hyapp.wallet.v1.SubmitH5RechargeTxRequest - 172, // 227: hyapp.wallet.v1.WalletService.GetH5RechargeOrder:input_type -> hyapp.wallet.v1.GetH5RechargeOrderRequest - 174, // 228: hyapp.wallet.v1.WalletService.VerifyCoinSellerRechargeReceipt:input_type -> hyapp.wallet.v1.VerifyCoinSellerRechargeReceiptRequest - 176, // 229: hyapp.wallet.v1.WalletService.HandleMifapayNotify:input_type -> hyapp.wallet.v1.HandleMifapayNotifyRequest - 178, // 230: hyapp.wallet.v1.WalletService.HandleV5PayNotify:input_type -> hyapp.wallet.v1.HandleV5PayNotifyRequest - 181, // 231: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest - 184, // 232: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest - 194, // 233: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest - 206, // 234: hyapp.wallet.v1.WalletService.GetVipProgramConfig:input_type -> hyapp.wallet.v1.GetVipProgramConfigRequest - 196, // 235: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest - 228, // 236: hyapp.wallet.v1.WalletService.CheckVipBenefit:input_type -> hyapp.wallet.v1.CheckVipBenefitRequest - 198, // 237: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest - 200, // 238: hyapp.wallet.v1.WalletService.DebitCPBreakupFee:input_type -> hyapp.wallet.v1.DebitCPBreakupFeeRequest - 202, // 239: hyapp.wallet.v1.WalletService.DebitWheelDraw:input_type -> hyapp.wallet.v1.DebitWheelDrawRequest - 204, // 240: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest - 222, // 241: hyapp.wallet.v1.WalletService.GrantVipTrialCard:input_type -> hyapp.wallet.v1.GrantVipTrialCardRequest - 224, // 242: hyapp.wallet.v1.WalletService.EquipVipTrialCard:input_type -> hyapp.wallet.v1.EquipVipTrialCardRequest - 226, // 243: hyapp.wallet.v1.WalletService.UnequipVipTrialCard:input_type -> hyapp.wallet.v1.UnequipVipTrialCardRequest - 231, // 244: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest - 233, // 245: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest - 208, // 246: hyapp.wallet.v1.WalletService.UpdateAdminVipProgramConfig:input_type -> hyapp.wallet.v1.UpdateAdminVipProgramConfigRequest - 210, // 247: hyapp.wallet.v1.WalletService.UpdateMyVipSettings:input_type -> hyapp.wallet.v1.UpdateMyVipSettingsRequest - 216, // 248: hyapp.wallet.v1.WalletService.GetMyCurrentVipDailyCoinRebate:input_type -> hyapp.wallet.v1.GetMyCurrentVipDailyCoinRebateRequest - 218, // 249: hyapp.wallet.v1.WalletService.ListMyVipDailyCoinRebateStatuses:input_type -> hyapp.wallet.v1.ListMyVipDailyCoinRebateStatusesRequest - 220, // 250: hyapp.wallet.v1.WalletService.ClaimVipDailyCoinRebate:input_type -> hyapp.wallet.v1.ClaimVipDailyCoinRebateRequest - 235, // 251: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest - 237, // 252: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:input_type -> hyapp.wallet.v1.CreditLuckyGiftRewardRequest - 239, // 253: hyapp.wallet.v1.WalletService.CreditWheelReward:input_type -> hyapp.wallet.v1.CreditWheelRewardRequest - 241, // 254: hyapp.wallet.v1.WalletService.CreditRoomTurnoverReward:input_type -> hyapp.wallet.v1.CreditRoomTurnoverRewardRequest - 243, // 255: hyapp.wallet.v1.WalletService.CreditInviteActivityReward:input_type -> hyapp.wallet.v1.CreditInviteActivityRewardRequest - 245, // 256: hyapp.wallet.v1.WalletService.CreditAgencyOpeningReward:input_type -> hyapp.wallet.v1.CreditAgencyOpeningRewardRequest - 247, // 257: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest - 252, // 258: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest - 254, // 259: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest - 256, // 260: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest - 258, // 261: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest - 260, // 262: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest - 262, // 263: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest - 264, // 264: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest - 266, // 265: hyapp.wallet.v1.WalletService.RetryRedPacketRefund:input_type -> hyapp.wallet.v1.RetryRedPacketRefundRequest - 269, // 266: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryDailySettlementBatch:output_type -> hyapp.wallet.v1.CronBatchResponse - 269, // 267: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryHalfMonthSettlementBatch:output_type -> hyapp.wallet.v1.CronBatchResponse - 269, // 268: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryMonthEndBatch:output_type -> hyapp.wallet.v1.CronBatchResponse - 215, // 269: hyapp.wallet.v1.WalletCronService.ProcessVipDailyCoinRebateBatch:output_type -> hyapp.wallet.v1.ProcessVipDailyCoinRebateBatchResponse - 2, // 270: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse - 2, // 271: hyapp.wallet.v1.WalletService.DebitDirectGift:output_type -> hyapp.wallet.v1.DebitGiftResponse - 6, // 272: hyapp.wallet.v1.WalletService.BatchDebitGift:output_type -> hyapp.wallet.v1.BatchDebitGiftResponse - 2, // 273: hyapp.wallet.v1.WalletService.DebitRobotGift:output_type -> hyapp.wallet.v1.DebitGiftResponse - 10, // 274: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse - 14, // 275: hyapp.wallet.v1.WalletService.GetActiveHostSalaryPolicy:output_type -> hyapp.wallet.v1.GetActiveHostSalaryPolicyResponse - 17, // 276: hyapp.wallet.v1.WalletService.GetHostSalaryProgress:output_type -> hyapp.wallet.v1.GetHostSalaryProgressResponse - 20, // 277: hyapp.wallet.v1.WalletService.GetTeamHostSalaryStats:output_type -> hyapp.wallet.v1.GetTeamHostSalaryStatsResponse - 22, // 278: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse - 24, // 279: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse - 26, // 280: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse - 28, // 281: hyapp.wallet.v1.WalletService.TransferCoinSellerStockToChild:output_type -> hyapp.wallet.v1.TransferCoinSellerStockToChildResponse - 31, // 282: hyapp.wallet.v1.WalletService.ListCoinSellerSalaryExchangeRateTiers:output_type -> hyapp.wallet.v1.ListCoinSellerSalaryExchangeRateTiersResponse - 33, // 283: hyapp.wallet.v1.WalletService.ExchangeSalaryToCoin:output_type -> hyapp.wallet.v1.ExchangeSalaryToCoinResponse - 35, // 284: hyapp.wallet.v1.WalletService.TransferSalaryToCoinSeller:output_type -> hyapp.wallet.v1.TransferSalaryToCoinSellerResponse - 37, // 285: hyapp.wallet.v1.WalletService.FreezeSalaryWithdrawal:output_type -> hyapp.wallet.v1.FreezeSalaryWithdrawalResponse - 39, // 286: hyapp.wallet.v1.WalletService.SettleSalaryWithdrawal:output_type -> hyapp.wallet.v1.SettleSalaryWithdrawalResponse - 41, // 287: hyapp.wallet.v1.WalletService.ReleaseSalaryWithdrawal:output_type -> hyapp.wallet.v1.ReleaseSalaryWithdrawalResponse - 43, // 288: hyapp.wallet.v1.WalletService.FreezePointWithdrawal:output_type -> hyapp.wallet.v1.FreezePointWithdrawalResponse - 45, // 289: hyapp.wallet.v1.WalletService.SettlePointWithdrawal:output_type -> hyapp.wallet.v1.SettlePointWithdrawalResponse - 47, // 290: hyapp.wallet.v1.WalletService.ReleasePointWithdrawal:output_type -> hyapp.wallet.v1.ReleasePointWithdrawalResponse - 59, // 291: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse - 61, // 292: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse - 68, // 293: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse - 68, // 294: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse - 68, // 295: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse - 68, // 296: hyapp.wallet.v1.WalletService.DeleteResource:output_type -> hyapp.wallet.v1.ResourceResponse - 67, // 297: hyapp.wallet.v1.WalletService.BatchDeleteResources:output_type -> hyapp.wallet.v1.BatchDeleteResourcesResponse - 70, // 298: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse - 72, // 299: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse - 76, // 300: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 76, // 301: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 76, // 302: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 78, // 303: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse - 80, // 304: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse - 274, // 305: hyapp.wallet.v1.WalletService.GetGiftCatalogVersion:output_type -> hyapp.wallet.v1.GetGiftCatalogVersionResponse - 89, // 306: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse - 85, // 307: hyapp.wallet.v1.WalletService.BatchCreateGiftConfigs:output_type -> hyapp.wallet.v1.BatchCreateGiftConfigsResponse - 89, // 308: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse - 89, // 309: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse - 89, // 310: hyapp.wallet.v1.WalletService.DeleteGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse - 82, // 311: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse - 93, // 312: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse - 93, // 313: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse - 93, // 314: hyapp.wallet.v1.WalletService.RevokeResourceGrant:output_type -> hyapp.wallet.v1.ResourceGrantResponse - 95, // 315: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse - 97, // 316: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse - 99, // 317: hyapp.wallet.v1.WalletService.UnequipUserResource:output_type -> hyapp.wallet.v1.UnequipUserResourceResponse - 102, // 318: hyapp.wallet.v1.WalletService.BatchGetUserEquippedResources:output_type -> hyapp.wallet.v1.BatchGetUserEquippedResourcesResponse - 104, // 319: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse - 107, // 320: hyapp.wallet.v1.WalletService.ListResourceShopItems:output_type -> hyapp.wallet.v1.ListResourceShopItemsResponse - 109, // 321: hyapp.wallet.v1.WalletService.UpsertResourceShopItems:output_type -> hyapp.wallet.v1.UpsertResourceShopItemsResponse - 111, // 322: hyapp.wallet.v1.WalletService.SetResourceShopItemStatus:output_type -> hyapp.wallet.v1.ResourceShopItemResponse - 272, // 323: hyapp.wallet.v1.WalletService.ListResourceShopPurchaseOrders:output_type -> hyapp.wallet.v1.ListResourceShopPurchaseOrdersResponse - 113, // 324: hyapp.wallet.v1.WalletService.PurchaseResourceShopItem:output_type -> hyapp.wallet.v1.PurchaseResourceShopItemResponse - 116, // 325: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse - 119, // 326: hyapp.wallet.v1.WalletService.GetRechargeBillSummary:output_type -> hyapp.wallet.v1.GetRechargeBillSummaryResponse - 122, // 327: hyapp.wallet.v1.WalletService.BatchGetUserRechargeStats:output_type -> hyapp.wallet.v1.BatchGetUserRechargeStatsResponse - 128, // 328: hyapp.wallet.v1.WalletService.GetRechargeBillOverview:output_type -> hyapp.wallet.v1.GetRechargeBillOverviewResponse - 131, // 329: hyapp.wallet.v1.WalletService.RefreshGooglePaymentPrices:output_type -> hyapp.wallet.v1.RefreshGooglePaymentPricesResponse - 134, // 330: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse - 137, // 331: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse - 140, // 332: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse - 143, // 333: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse - 145, // 334: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:output_type -> hyapp.wallet.v1.ConfirmGooglePaymentResponse - 147, // 335: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse - 151, // 336: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse - 151, // 337: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse - 152, // 338: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse - 156, // 339: hyapp.wallet.v1.WalletService.ListThirdPartyPaymentChannels:output_type -> hyapp.wallet.v1.ListThirdPartyPaymentChannelsResponse - 158, // 340: hyapp.wallet.v1.WalletService.SetThirdPartyPaymentMethodStatus:output_type -> hyapp.wallet.v1.ThirdPartyPaymentMethodResponse - 158, // 341: hyapp.wallet.v1.WalletService.UpdateThirdPartyPaymentRate:output_type -> hyapp.wallet.v1.ThirdPartyPaymentMethodResponse - 162, // 342: hyapp.wallet.v1.WalletService.SyncThirdPartyPaymentMethods:output_type -> hyapp.wallet.v1.SyncThirdPartyPaymentMethodsResponse - 164, // 343: hyapp.wallet.v1.WalletService.ListH5RechargeOptions:output_type -> hyapp.wallet.v1.H5RechargeOptionsResponse - 173, // 344: hyapp.wallet.v1.WalletService.CreateH5RechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse - 173, // 345: hyapp.wallet.v1.WalletService.CreateTemporaryRechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse - 173, // 346: hyapp.wallet.v1.WalletService.GetTemporaryRechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse - 170, // 347: hyapp.wallet.v1.WalletService.ListTemporaryRechargeOrders:output_type -> hyapp.wallet.v1.ListTemporaryRechargeOrdersResponse - 173, // 348: hyapp.wallet.v1.WalletService.SubmitH5RechargeTx:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse - 173, // 349: hyapp.wallet.v1.WalletService.GetH5RechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse - 175, // 350: hyapp.wallet.v1.WalletService.VerifyCoinSellerRechargeReceipt:output_type -> hyapp.wallet.v1.VerifyCoinSellerRechargeReceiptResponse - 177, // 351: hyapp.wallet.v1.WalletService.HandleMifapayNotify:output_type -> hyapp.wallet.v1.HandleMifapayNotifyResponse - 179, // 352: hyapp.wallet.v1.WalletService.HandleV5PayNotify:output_type -> hyapp.wallet.v1.HandleV5PayNotifyResponse - 182, // 353: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse - 185, // 354: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse - 195, // 355: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse - 207, // 356: hyapp.wallet.v1.WalletService.GetVipProgramConfig:output_type -> hyapp.wallet.v1.GetVipProgramConfigResponse - 197, // 357: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse - 229, // 358: hyapp.wallet.v1.WalletService.CheckVipBenefit:output_type -> hyapp.wallet.v1.CheckVipBenefitResponse - 199, // 359: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse - 201, // 360: hyapp.wallet.v1.WalletService.DebitCPBreakupFee:output_type -> hyapp.wallet.v1.DebitCPBreakupFeeResponse - 203, // 361: hyapp.wallet.v1.WalletService.DebitWheelDraw:output_type -> hyapp.wallet.v1.DebitWheelDrawResponse - 205, // 362: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse - 223, // 363: hyapp.wallet.v1.WalletService.GrantVipTrialCard:output_type -> hyapp.wallet.v1.GrantVipTrialCardResponse - 225, // 364: hyapp.wallet.v1.WalletService.EquipVipTrialCard:output_type -> hyapp.wallet.v1.EquipVipTrialCardResponse - 227, // 365: hyapp.wallet.v1.WalletService.UnequipVipTrialCard:output_type -> hyapp.wallet.v1.UnequipVipTrialCardResponse - 232, // 366: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse - 234, // 367: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse - 209, // 368: hyapp.wallet.v1.WalletService.UpdateAdminVipProgramConfig:output_type -> hyapp.wallet.v1.UpdateAdminVipProgramConfigResponse - 211, // 369: hyapp.wallet.v1.WalletService.UpdateMyVipSettings:output_type -> hyapp.wallet.v1.UpdateMyVipSettingsResponse - 217, // 370: hyapp.wallet.v1.WalletService.GetMyCurrentVipDailyCoinRebate:output_type -> hyapp.wallet.v1.GetMyCurrentVipDailyCoinRebateResponse - 219, // 371: hyapp.wallet.v1.WalletService.ListMyVipDailyCoinRebateStatuses:output_type -> hyapp.wallet.v1.ListMyVipDailyCoinRebateStatusesResponse - 221, // 372: hyapp.wallet.v1.WalletService.ClaimVipDailyCoinRebate:output_type -> hyapp.wallet.v1.ClaimVipDailyCoinRebateResponse - 236, // 373: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse - 238, // 374: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:output_type -> hyapp.wallet.v1.CreditLuckyGiftRewardResponse - 240, // 375: hyapp.wallet.v1.WalletService.CreditWheelReward:output_type -> hyapp.wallet.v1.CreditWheelRewardResponse - 242, // 376: hyapp.wallet.v1.WalletService.CreditRoomTurnoverReward:output_type -> hyapp.wallet.v1.CreditRoomTurnoverRewardResponse - 244, // 377: hyapp.wallet.v1.WalletService.CreditInviteActivityReward:output_type -> hyapp.wallet.v1.CreditInviteActivityRewardResponse - 246, // 378: hyapp.wallet.v1.WalletService.CreditAgencyOpeningReward:output_type -> hyapp.wallet.v1.CreditAgencyOpeningRewardResponse - 248, // 379: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse - 253, // 380: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse - 255, // 381: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse - 257, // 382: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse - 259, // 383: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse - 261, // 384: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse - 263, // 385: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse - 265, // 386: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse - 267, // 387: hyapp.wallet.v1.WalletService.RetryRedPacketRefund:output_type -> hyapp.wallet.v1.RetryRedPacketRefundResponse - 266, // [266:388] is the sub-list for method output_type - 144, // [144:266] is the sub-list for method input_type - 144, // [144:144] is the sub-list for extension type_name - 144, // [144:144] is the sub-list for extension extendee - 0, // [0:144] is the sub-list for field type_name + 275, // 144: hyapp.wallet.v1.GetHostRevenueStatsResponse.stats:type_name -> hyapp.wallet.v1.HostRevenueStats + 278, // 145: hyapp.wallet.v1.GetAgencyPointShareStatsResponse.stats:type_name -> hyapp.wallet.v1.AgencyPointShareStats + 281, // 146: hyapp.wallet.v1.GetAgencyHostGiftStatsResponse.stats:type_name -> hyapp.wallet.v1.AgencyHostGiftStats + 284, // 147: hyapp.wallet.v1.ListPointWithdrawalCoinSellersResponse.sellers:type_name -> hyapp.wallet.v1.PointWithdrawalCoinSellerConfig + 268, // 148: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryDailySettlementBatch:input_type -> hyapp.wallet.v1.CronBatchRequest + 268, // 149: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryHalfMonthSettlementBatch:input_type -> hyapp.wallet.v1.CronBatchRequest + 268, // 150: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryMonthEndBatch:input_type -> hyapp.wallet.v1.CronBatchRequest + 214, // 151: hyapp.wallet.v1.WalletCronService.ProcessVipDailyCoinRebateBatch:input_type -> hyapp.wallet.v1.ProcessVipDailyCoinRebateBatchRequest + 0, // 152: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest + 1, // 153: hyapp.wallet.v1.WalletService.DebitDirectGift:input_type -> hyapp.wallet.v1.DebitDirectGiftRequest + 4, // 154: hyapp.wallet.v1.WalletService.BatchDebitGift:input_type -> hyapp.wallet.v1.BatchDebitGiftRequest + 7, // 155: hyapp.wallet.v1.WalletService.DebitRobotGift:input_type -> hyapp.wallet.v1.DebitRobotGiftRequest + 9, // 156: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest + 13, // 157: hyapp.wallet.v1.WalletService.GetActiveHostSalaryPolicy:input_type -> hyapp.wallet.v1.GetActiveHostSalaryPolicyRequest + 16, // 158: hyapp.wallet.v1.WalletService.GetHostSalaryProgress:input_type -> hyapp.wallet.v1.GetHostSalaryProgressRequest + 276, // 159: hyapp.wallet.v1.WalletService.GetHostRevenueStats:input_type -> hyapp.wallet.v1.GetHostRevenueStatsRequest + 279, // 160: hyapp.wallet.v1.WalletService.GetAgencyPointShareStats:input_type -> hyapp.wallet.v1.GetAgencyPointShareStatsRequest + 282, // 161: hyapp.wallet.v1.WalletService.GetAgencyHostGiftStats:input_type -> hyapp.wallet.v1.GetAgencyHostGiftStatsRequest + 19, // 162: hyapp.wallet.v1.WalletService.GetTeamHostSalaryStats:input_type -> hyapp.wallet.v1.GetTeamHostSalaryStatsRequest + 21, // 163: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest + 23, // 164: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest + 25, // 165: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest + 27, // 166: hyapp.wallet.v1.WalletService.TransferCoinSellerStockToChild:input_type -> hyapp.wallet.v1.TransferCoinSellerStockToChildRequest + 30, // 167: hyapp.wallet.v1.WalletService.ListCoinSellerSalaryExchangeRateTiers:input_type -> hyapp.wallet.v1.ListCoinSellerSalaryExchangeRateTiersRequest + 32, // 168: hyapp.wallet.v1.WalletService.ExchangeSalaryToCoin:input_type -> hyapp.wallet.v1.ExchangeSalaryToCoinRequest + 34, // 169: hyapp.wallet.v1.WalletService.TransferSalaryToCoinSeller:input_type -> hyapp.wallet.v1.TransferSalaryToCoinSellerRequest + 285, // 170: hyapp.wallet.v1.WalletService.ListPointWithdrawalCoinSellers:input_type -> hyapp.wallet.v1.ListPointWithdrawalCoinSellersRequest + 287, // 171: hyapp.wallet.v1.WalletService.TransferPointToCoinSeller:input_type -> hyapp.wallet.v1.TransferPointToCoinSellerRequest + 289, // 172: hyapp.wallet.v1.WalletService.GetPointWithdrawalConfig:input_type -> hyapp.wallet.v1.GetPointWithdrawalConfigRequest + 36, // 173: hyapp.wallet.v1.WalletService.FreezeSalaryWithdrawal:input_type -> hyapp.wallet.v1.FreezeSalaryWithdrawalRequest + 38, // 174: hyapp.wallet.v1.WalletService.SettleSalaryWithdrawal:input_type -> hyapp.wallet.v1.SettleSalaryWithdrawalRequest + 40, // 175: hyapp.wallet.v1.WalletService.ReleaseSalaryWithdrawal:input_type -> hyapp.wallet.v1.ReleaseSalaryWithdrawalRequest + 42, // 176: hyapp.wallet.v1.WalletService.FreezePointWithdrawal:input_type -> hyapp.wallet.v1.FreezePointWithdrawalRequest + 44, // 177: hyapp.wallet.v1.WalletService.SettlePointWithdrawal:input_type -> hyapp.wallet.v1.SettlePointWithdrawalRequest + 46, // 178: hyapp.wallet.v1.WalletService.ReleasePointWithdrawal:input_type -> hyapp.wallet.v1.ReleasePointWithdrawalRequest + 58, // 179: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest + 60, // 180: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest + 62, // 181: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest + 63, // 182: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest + 64, // 183: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest + 65, // 184: hyapp.wallet.v1.WalletService.DeleteResource:input_type -> hyapp.wallet.v1.DeleteResourceRequest + 66, // 185: hyapp.wallet.v1.WalletService.BatchDeleteResources:input_type -> hyapp.wallet.v1.BatchDeleteResourcesRequest + 69, // 186: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest + 71, // 187: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest + 73, // 188: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest + 74, // 189: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest + 75, // 190: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest + 77, // 191: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest + 79, // 192: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest + 273, // 193: hyapp.wallet.v1.WalletService.GetGiftCatalogVersion:input_type -> hyapp.wallet.v1.GetGiftCatalogVersionRequest + 83, // 194: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest + 84, // 195: hyapp.wallet.v1.WalletService.BatchCreateGiftConfigs:input_type -> hyapp.wallet.v1.BatchCreateGiftConfigsRequest + 86, // 196: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest + 87, // 197: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest + 88, // 198: hyapp.wallet.v1.WalletService.DeleteGiftConfig:input_type -> hyapp.wallet.v1.DeleteGiftConfigRequest + 81, // 199: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest + 90, // 200: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest + 91, // 201: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest + 92, // 202: hyapp.wallet.v1.WalletService.RevokeResourceGrant:input_type -> hyapp.wallet.v1.RevokeResourceGrantRequest + 94, // 203: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest + 96, // 204: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest + 98, // 205: hyapp.wallet.v1.WalletService.UnequipUserResource:input_type -> hyapp.wallet.v1.UnequipUserResourceRequest + 100, // 206: hyapp.wallet.v1.WalletService.BatchGetUserEquippedResources:input_type -> hyapp.wallet.v1.BatchGetUserEquippedResourcesRequest + 103, // 207: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest + 106, // 208: hyapp.wallet.v1.WalletService.ListResourceShopItems:input_type -> hyapp.wallet.v1.ListResourceShopItemsRequest + 108, // 209: hyapp.wallet.v1.WalletService.UpsertResourceShopItems:input_type -> hyapp.wallet.v1.UpsertResourceShopItemsRequest + 110, // 210: hyapp.wallet.v1.WalletService.SetResourceShopItemStatus:input_type -> hyapp.wallet.v1.SetResourceShopItemStatusRequest + 271, // 211: hyapp.wallet.v1.WalletService.ListResourceShopPurchaseOrders:input_type -> hyapp.wallet.v1.ListResourceShopPurchaseOrdersRequest + 112, // 212: hyapp.wallet.v1.WalletService.PurchaseResourceShopItem:input_type -> hyapp.wallet.v1.PurchaseResourceShopItemRequest + 115, // 213: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest + 117, // 214: hyapp.wallet.v1.WalletService.GetRechargeBillSummary:input_type -> hyapp.wallet.v1.GetRechargeBillSummaryRequest + 121, // 215: hyapp.wallet.v1.WalletService.BatchGetUserRechargeStats:input_type -> hyapp.wallet.v1.BatchGetUserRechargeStatsRequest + 123, // 216: hyapp.wallet.v1.WalletService.GetRechargeBillOverview:input_type -> hyapp.wallet.v1.GetRechargeBillOverviewRequest + 129, // 217: hyapp.wallet.v1.WalletService.RefreshGooglePaymentPrices:input_type -> hyapp.wallet.v1.RefreshGooglePaymentPricesRequest + 133, // 218: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest + 136, // 219: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest + 139, // 220: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest + 142, // 221: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest + 144, // 222: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:input_type -> hyapp.wallet.v1.ConfirmGooglePaymentRequest + 146, // 223: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest + 148, // 224: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest + 149, // 225: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest + 150, // 226: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest + 155, // 227: hyapp.wallet.v1.WalletService.ListThirdPartyPaymentChannels:input_type -> hyapp.wallet.v1.ListThirdPartyPaymentChannelsRequest + 157, // 228: hyapp.wallet.v1.WalletService.SetThirdPartyPaymentMethodStatus:input_type -> hyapp.wallet.v1.SetThirdPartyPaymentMethodStatusRequest + 159, // 229: hyapp.wallet.v1.WalletService.UpdateThirdPartyPaymentRate:input_type -> hyapp.wallet.v1.UpdateThirdPartyPaymentRateRequest + 161, // 230: hyapp.wallet.v1.WalletService.SyncThirdPartyPaymentMethods:input_type -> hyapp.wallet.v1.SyncThirdPartyPaymentMethodsRequest + 163, // 231: hyapp.wallet.v1.WalletService.ListH5RechargeOptions:input_type -> hyapp.wallet.v1.H5RechargeOptionsRequest + 166, // 232: hyapp.wallet.v1.WalletService.CreateH5RechargeOrder:input_type -> hyapp.wallet.v1.CreateH5RechargeOrderRequest + 167, // 233: hyapp.wallet.v1.WalletService.CreateTemporaryRechargeOrder:input_type -> hyapp.wallet.v1.CreateTemporaryRechargeOrderRequest + 168, // 234: hyapp.wallet.v1.WalletService.GetTemporaryRechargeOrder:input_type -> hyapp.wallet.v1.GetTemporaryRechargeOrderRequest + 169, // 235: hyapp.wallet.v1.WalletService.ListTemporaryRechargeOrders:input_type -> hyapp.wallet.v1.ListTemporaryRechargeOrdersRequest + 171, // 236: hyapp.wallet.v1.WalletService.SubmitH5RechargeTx:input_type -> hyapp.wallet.v1.SubmitH5RechargeTxRequest + 172, // 237: hyapp.wallet.v1.WalletService.GetH5RechargeOrder:input_type -> hyapp.wallet.v1.GetH5RechargeOrderRequest + 174, // 238: hyapp.wallet.v1.WalletService.VerifyCoinSellerRechargeReceipt:input_type -> hyapp.wallet.v1.VerifyCoinSellerRechargeReceiptRequest + 176, // 239: hyapp.wallet.v1.WalletService.HandleMifapayNotify:input_type -> hyapp.wallet.v1.HandleMifapayNotifyRequest + 178, // 240: hyapp.wallet.v1.WalletService.HandleV5PayNotify:input_type -> hyapp.wallet.v1.HandleV5PayNotifyRequest + 181, // 241: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest + 184, // 242: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest + 194, // 243: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest + 206, // 244: hyapp.wallet.v1.WalletService.GetVipProgramConfig:input_type -> hyapp.wallet.v1.GetVipProgramConfigRequest + 196, // 245: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest + 228, // 246: hyapp.wallet.v1.WalletService.CheckVipBenefit:input_type -> hyapp.wallet.v1.CheckVipBenefitRequest + 198, // 247: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest + 200, // 248: hyapp.wallet.v1.WalletService.DebitCPBreakupFee:input_type -> hyapp.wallet.v1.DebitCPBreakupFeeRequest + 202, // 249: hyapp.wallet.v1.WalletService.DebitWheelDraw:input_type -> hyapp.wallet.v1.DebitWheelDrawRequest + 204, // 250: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest + 222, // 251: hyapp.wallet.v1.WalletService.GrantVipTrialCard:input_type -> hyapp.wallet.v1.GrantVipTrialCardRequest + 224, // 252: hyapp.wallet.v1.WalletService.EquipVipTrialCard:input_type -> hyapp.wallet.v1.EquipVipTrialCardRequest + 226, // 253: hyapp.wallet.v1.WalletService.UnequipVipTrialCard:input_type -> hyapp.wallet.v1.UnequipVipTrialCardRequest + 231, // 254: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest + 233, // 255: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest + 208, // 256: hyapp.wallet.v1.WalletService.UpdateAdminVipProgramConfig:input_type -> hyapp.wallet.v1.UpdateAdminVipProgramConfigRequest + 210, // 257: hyapp.wallet.v1.WalletService.UpdateMyVipSettings:input_type -> hyapp.wallet.v1.UpdateMyVipSettingsRequest + 216, // 258: hyapp.wallet.v1.WalletService.GetMyCurrentVipDailyCoinRebate:input_type -> hyapp.wallet.v1.GetMyCurrentVipDailyCoinRebateRequest + 218, // 259: hyapp.wallet.v1.WalletService.ListMyVipDailyCoinRebateStatuses:input_type -> hyapp.wallet.v1.ListMyVipDailyCoinRebateStatusesRequest + 220, // 260: hyapp.wallet.v1.WalletService.ClaimVipDailyCoinRebate:input_type -> hyapp.wallet.v1.ClaimVipDailyCoinRebateRequest + 235, // 261: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest + 237, // 262: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:input_type -> hyapp.wallet.v1.CreditLuckyGiftRewardRequest + 239, // 263: hyapp.wallet.v1.WalletService.CreditWheelReward:input_type -> hyapp.wallet.v1.CreditWheelRewardRequest + 241, // 264: hyapp.wallet.v1.WalletService.CreditRoomTurnoverReward:input_type -> hyapp.wallet.v1.CreditRoomTurnoverRewardRequest + 243, // 265: hyapp.wallet.v1.WalletService.CreditInviteActivityReward:input_type -> hyapp.wallet.v1.CreditInviteActivityRewardRequest + 245, // 266: hyapp.wallet.v1.WalletService.CreditAgencyOpeningReward:input_type -> hyapp.wallet.v1.CreditAgencyOpeningRewardRequest + 247, // 267: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest + 252, // 268: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest + 254, // 269: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest + 256, // 270: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest + 258, // 271: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest + 260, // 272: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest + 262, // 273: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest + 264, // 274: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest + 266, // 275: hyapp.wallet.v1.WalletService.RetryRedPacketRefund:input_type -> hyapp.wallet.v1.RetryRedPacketRefundRequest + 269, // 276: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryDailySettlementBatch:output_type -> hyapp.wallet.v1.CronBatchResponse + 269, // 277: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryHalfMonthSettlementBatch:output_type -> hyapp.wallet.v1.CronBatchResponse + 269, // 278: hyapp.wallet.v1.WalletCronService.ProcessHostSalaryMonthEndBatch:output_type -> hyapp.wallet.v1.CronBatchResponse + 215, // 279: hyapp.wallet.v1.WalletCronService.ProcessVipDailyCoinRebateBatch:output_type -> hyapp.wallet.v1.ProcessVipDailyCoinRebateBatchResponse + 2, // 280: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse + 2, // 281: hyapp.wallet.v1.WalletService.DebitDirectGift:output_type -> hyapp.wallet.v1.DebitGiftResponse + 6, // 282: hyapp.wallet.v1.WalletService.BatchDebitGift:output_type -> hyapp.wallet.v1.BatchDebitGiftResponse + 2, // 283: hyapp.wallet.v1.WalletService.DebitRobotGift:output_type -> hyapp.wallet.v1.DebitGiftResponse + 10, // 284: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse + 14, // 285: hyapp.wallet.v1.WalletService.GetActiveHostSalaryPolicy:output_type -> hyapp.wallet.v1.GetActiveHostSalaryPolicyResponse + 17, // 286: hyapp.wallet.v1.WalletService.GetHostSalaryProgress:output_type -> hyapp.wallet.v1.GetHostSalaryProgressResponse + 277, // 287: hyapp.wallet.v1.WalletService.GetHostRevenueStats:output_type -> hyapp.wallet.v1.GetHostRevenueStatsResponse + 280, // 288: hyapp.wallet.v1.WalletService.GetAgencyPointShareStats:output_type -> hyapp.wallet.v1.GetAgencyPointShareStatsResponse + 283, // 289: hyapp.wallet.v1.WalletService.GetAgencyHostGiftStats:output_type -> hyapp.wallet.v1.GetAgencyHostGiftStatsResponse + 20, // 290: hyapp.wallet.v1.WalletService.GetTeamHostSalaryStats:output_type -> hyapp.wallet.v1.GetTeamHostSalaryStatsResponse + 22, // 291: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse + 24, // 292: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse + 26, // 293: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse + 28, // 294: hyapp.wallet.v1.WalletService.TransferCoinSellerStockToChild:output_type -> hyapp.wallet.v1.TransferCoinSellerStockToChildResponse + 31, // 295: hyapp.wallet.v1.WalletService.ListCoinSellerSalaryExchangeRateTiers:output_type -> hyapp.wallet.v1.ListCoinSellerSalaryExchangeRateTiersResponse + 33, // 296: hyapp.wallet.v1.WalletService.ExchangeSalaryToCoin:output_type -> hyapp.wallet.v1.ExchangeSalaryToCoinResponse + 35, // 297: hyapp.wallet.v1.WalletService.TransferSalaryToCoinSeller:output_type -> hyapp.wallet.v1.TransferSalaryToCoinSellerResponse + 286, // 298: hyapp.wallet.v1.WalletService.ListPointWithdrawalCoinSellers:output_type -> hyapp.wallet.v1.ListPointWithdrawalCoinSellersResponse + 288, // 299: hyapp.wallet.v1.WalletService.TransferPointToCoinSeller:output_type -> hyapp.wallet.v1.TransferPointToCoinSellerResponse + 290, // 300: hyapp.wallet.v1.WalletService.GetPointWithdrawalConfig:output_type -> hyapp.wallet.v1.GetPointWithdrawalConfigResponse + 37, // 301: hyapp.wallet.v1.WalletService.FreezeSalaryWithdrawal:output_type -> hyapp.wallet.v1.FreezeSalaryWithdrawalResponse + 39, // 302: hyapp.wallet.v1.WalletService.SettleSalaryWithdrawal:output_type -> hyapp.wallet.v1.SettleSalaryWithdrawalResponse + 41, // 303: hyapp.wallet.v1.WalletService.ReleaseSalaryWithdrawal:output_type -> hyapp.wallet.v1.ReleaseSalaryWithdrawalResponse + 43, // 304: hyapp.wallet.v1.WalletService.FreezePointWithdrawal:output_type -> hyapp.wallet.v1.FreezePointWithdrawalResponse + 45, // 305: hyapp.wallet.v1.WalletService.SettlePointWithdrawal:output_type -> hyapp.wallet.v1.SettlePointWithdrawalResponse + 47, // 306: hyapp.wallet.v1.WalletService.ReleasePointWithdrawal:output_type -> hyapp.wallet.v1.ReleasePointWithdrawalResponse + 59, // 307: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse + 61, // 308: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse + 68, // 309: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse + 68, // 310: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse + 68, // 311: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse + 68, // 312: hyapp.wallet.v1.WalletService.DeleteResource:output_type -> hyapp.wallet.v1.ResourceResponse + 67, // 313: hyapp.wallet.v1.WalletService.BatchDeleteResources:output_type -> hyapp.wallet.v1.BatchDeleteResourcesResponse + 70, // 314: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse + 72, // 315: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse + 76, // 316: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 76, // 317: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 76, // 318: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 78, // 319: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse + 80, // 320: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse + 274, // 321: hyapp.wallet.v1.WalletService.GetGiftCatalogVersion:output_type -> hyapp.wallet.v1.GetGiftCatalogVersionResponse + 89, // 322: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse + 85, // 323: hyapp.wallet.v1.WalletService.BatchCreateGiftConfigs:output_type -> hyapp.wallet.v1.BatchCreateGiftConfigsResponse + 89, // 324: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse + 89, // 325: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse + 89, // 326: hyapp.wallet.v1.WalletService.DeleteGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse + 82, // 327: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse + 93, // 328: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse + 93, // 329: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse + 93, // 330: hyapp.wallet.v1.WalletService.RevokeResourceGrant:output_type -> hyapp.wallet.v1.ResourceGrantResponse + 95, // 331: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse + 97, // 332: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse + 99, // 333: hyapp.wallet.v1.WalletService.UnequipUserResource:output_type -> hyapp.wallet.v1.UnequipUserResourceResponse + 102, // 334: hyapp.wallet.v1.WalletService.BatchGetUserEquippedResources:output_type -> hyapp.wallet.v1.BatchGetUserEquippedResourcesResponse + 104, // 335: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse + 107, // 336: hyapp.wallet.v1.WalletService.ListResourceShopItems:output_type -> hyapp.wallet.v1.ListResourceShopItemsResponse + 109, // 337: hyapp.wallet.v1.WalletService.UpsertResourceShopItems:output_type -> hyapp.wallet.v1.UpsertResourceShopItemsResponse + 111, // 338: hyapp.wallet.v1.WalletService.SetResourceShopItemStatus:output_type -> hyapp.wallet.v1.ResourceShopItemResponse + 272, // 339: hyapp.wallet.v1.WalletService.ListResourceShopPurchaseOrders:output_type -> hyapp.wallet.v1.ListResourceShopPurchaseOrdersResponse + 113, // 340: hyapp.wallet.v1.WalletService.PurchaseResourceShopItem:output_type -> hyapp.wallet.v1.PurchaseResourceShopItemResponse + 116, // 341: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse + 119, // 342: hyapp.wallet.v1.WalletService.GetRechargeBillSummary:output_type -> hyapp.wallet.v1.GetRechargeBillSummaryResponse + 122, // 343: hyapp.wallet.v1.WalletService.BatchGetUserRechargeStats:output_type -> hyapp.wallet.v1.BatchGetUserRechargeStatsResponse + 128, // 344: hyapp.wallet.v1.WalletService.GetRechargeBillOverview:output_type -> hyapp.wallet.v1.GetRechargeBillOverviewResponse + 131, // 345: hyapp.wallet.v1.WalletService.RefreshGooglePaymentPrices:output_type -> hyapp.wallet.v1.RefreshGooglePaymentPricesResponse + 134, // 346: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse + 137, // 347: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse + 140, // 348: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse + 143, // 349: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse + 145, // 350: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:output_type -> hyapp.wallet.v1.ConfirmGooglePaymentResponse + 147, // 351: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse + 151, // 352: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse + 151, // 353: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse + 152, // 354: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse + 156, // 355: hyapp.wallet.v1.WalletService.ListThirdPartyPaymentChannels:output_type -> hyapp.wallet.v1.ListThirdPartyPaymentChannelsResponse + 158, // 356: hyapp.wallet.v1.WalletService.SetThirdPartyPaymentMethodStatus:output_type -> hyapp.wallet.v1.ThirdPartyPaymentMethodResponse + 158, // 357: hyapp.wallet.v1.WalletService.UpdateThirdPartyPaymentRate:output_type -> hyapp.wallet.v1.ThirdPartyPaymentMethodResponse + 162, // 358: hyapp.wallet.v1.WalletService.SyncThirdPartyPaymentMethods:output_type -> hyapp.wallet.v1.SyncThirdPartyPaymentMethodsResponse + 164, // 359: hyapp.wallet.v1.WalletService.ListH5RechargeOptions:output_type -> hyapp.wallet.v1.H5RechargeOptionsResponse + 173, // 360: hyapp.wallet.v1.WalletService.CreateH5RechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse + 173, // 361: hyapp.wallet.v1.WalletService.CreateTemporaryRechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse + 173, // 362: hyapp.wallet.v1.WalletService.GetTemporaryRechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse + 170, // 363: hyapp.wallet.v1.WalletService.ListTemporaryRechargeOrders:output_type -> hyapp.wallet.v1.ListTemporaryRechargeOrdersResponse + 173, // 364: hyapp.wallet.v1.WalletService.SubmitH5RechargeTx:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse + 173, // 365: hyapp.wallet.v1.WalletService.GetH5RechargeOrder:output_type -> hyapp.wallet.v1.H5RechargeOrderResponse + 175, // 366: hyapp.wallet.v1.WalletService.VerifyCoinSellerRechargeReceipt:output_type -> hyapp.wallet.v1.VerifyCoinSellerRechargeReceiptResponse + 177, // 367: hyapp.wallet.v1.WalletService.HandleMifapayNotify:output_type -> hyapp.wallet.v1.HandleMifapayNotifyResponse + 179, // 368: hyapp.wallet.v1.WalletService.HandleV5PayNotify:output_type -> hyapp.wallet.v1.HandleV5PayNotifyResponse + 182, // 369: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse + 185, // 370: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse + 195, // 371: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse + 207, // 372: hyapp.wallet.v1.WalletService.GetVipProgramConfig:output_type -> hyapp.wallet.v1.GetVipProgramConfigResponse + 197, // 373: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse + 229, // 374: hyapp.wallet.v1.WalletService.CheckVipBenefit:output_type -> hyapp.wallet.v1.CheckVipBenefitResponse + 199, // 375: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse + 201, // 376: hyapp.wallet.v1.WalletService.DebitCPBreakupFee:output_type -> hyapp.wallet.v1.DebitCPBreakupFeeResponse + 203, // 377: hyapp.wallet.v1.WalletService.DebitWheelDraw:output_type -> hyapp.wallet.v1.DebitWheelDrawResponse + 205, // 378: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse + 223, // 379: hyapp.wallet.v1.WalletService.GrantVipTrialCard:output_type -> hyapp.wallet.v1.GrantVipTrialCardResponse + 225, // 380: hyapp.wallet.v1.WalletService.EquipVipTrialCard:output_type -> hyapp.wallet.v1.EquipVipTrialCardResponse + 227, // 381: hyapp.wallet.v1.WalletService.UnequipVipTrialCard:output_type -> hyapp.wallet.v1.UnequipVipTrialCardResponse + 232, // 382: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse + 234, // 383: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse + 209, // 384: hyapp.wallet.v1.WalletService.UpdateAdminVipProgramConfig:output_type -> hyapp.wallet.v1.UpdateAdminVipProgramConfigResponse + 211, // 385: hyapp.wallet.v1.WalletService.UpdateMyVipSettings:output_type -> hyapp.wallet.v1.UpdateMyVipSettingsResponse + 217, // 386: hyapp.wallet.v1.WalletService.GetMyCurrentVipDailyCoinRebate:output_type -> hyapp.wallet.v1.GetMyCurrentVipDailyCoinRebateResponse + 219, // 387: hyapp.wallet.v1.WalletService.ListMyVipDailyCoinRebateStatuses:output_type -> hyapp.wallet.v1.ListMyVipDailyCoinRebateStatusesResponse + 221, // 388: hyapp.wallet.v1.WalletService.ClaimVipDailyCoinRebate:output_type -> hyapp.wallet.v1.ClaimVipDailyCoinRebateResponse + 236, // 389: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse + 238, // 390: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:output_type -> hyapp.wallet.v1.CreditLuckyGiftRewardResponse + 240, // 391: hyapp.wallet.v1.WalletService.CreditWheelReward:output_type -> hyapp.wallet.v1.CreditWheelRewardResponse + 242, // 392: hyapp.wallet.v1.WalletService.CreditRoomTurnoverReward:output_type -> hyapp.wallet.v1.CreditRoomTurnoverRewardResponse + 244, // 393: hyapp.wallet.v1.WalletService.CreditInviteActivityReward:output_type -> hyapp.wallet.v1.CreditInviteActivityRewardResponse + 246, // 394: hyapp.wallet.v1.WalletService.CreditAgencyOpeningReward:output_type -> hyapp.wallet.v1.CreditAgencyOpeningRewardResponse + 248, // 395: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse + 253, // 396: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse + 255, // 397: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse + 257, // 398: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse + 259, // 399: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse + 261, // 400: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse + 263, // 401: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse + 265, // 402: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse + 267, // 403: hyapp.wallet.v1.WalletService.RetryRedPacketRefund:output_type -> hyapp.wallet.v1.RetryRedPacketRefundResponse + 276, // [276:404] is the sub-list for method output_type + 148, // [148:276] is the sub-list for method input_type + 148, // [148:148] is the sub-list for extension type_name + 148, // [148:148] is the sub-list for extension extendee + 0, // [0:148] is the sub-list for field type_name } func init() { file_proto_wallet_v1_wallet_proto_init() } @@ -30713,7 +32067,7 @@ func file_proto_wallet_v1_wallet_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_wallet_v1_wallet_proto_rawDesc, NumEnums: 0, - NumMessages: 276, + NumMessages: 292, NumExtensions: 0, NumServices: 2, }, diff --git a/api/proto/wallet/v1/wallet.proto b/api/proto/wallet/v1/wallet.proto index 36e86f0c..a7721222 100644 --- a/api/proto/wallet/v1/wallet.proto +++ b/api/proto/wallet/v1/wallet.proto @@ -2763,6 +2763,122 @@ message GetGiftCatalogVersionResponse { int64 version = 1; } +// HostRevenueStats 聚合主播在自然日区间内的收益 POINT 和送礼用户;gateway 对外仍按产品文案展示为钻石。 +message HostRevenueStats { + int64 diamond_earnings = 1; + int64 diamond_exchanged = 2; + int64 gift_senders = 3; +} + +message GetHostRevenueStatsRequest { + string request_id = 1; + string app_code = 2; + int64 host_user_id = 3; + int64 start_at_ms = 4; + int64 end_at_ms = 5; +} + +message GetHostRevenueStatsResponse { + HostRevenueStats stats = 1; +} + +// AgencyPointShareStats 只统计独立 Agency 分成流水,不把 owner 自己的主播礼物收益重复算入分成。 +message AgencyPointShareStats { + int64 share_income = 1; + int64 gifted_host_count = 2; +} + +message GetAgencyPointShareStatsRequest { + string request_id = 1; + string app_code = 2; + int64 agency_owner_user_id = 3; + int64 start_at_ms = 4; + int64 end_at_ms = 5; +} + +message GetAgencyPointShareStatsResponse { + AgencyPointShareStats stats = 1; +} + +message AgencyHostGiftStats { + int64 gift_income = 1; + int64 gifted_host_count = 2; +} + +message GetAgencyHostGiftStatsRequest { + string request_id = 1; + string app_code = 2; + repeated int64 host_user_ids = 3; + int64 start_at_ms = 4; + int64 end_at_ms = 5; +} + +message GetAgencyHostGiftStatsResponse { + AgencyHostGiftStats stats = 1; +} + +// PointWithdrawalCoinSellerConfig 是按 App 隔离的 POINT 提现币商白名单与兑换比例。 +// 比例用整数分子/分母保存,避免浮点金额在 H5、gateway 和账本间产生舍入分歧。 +message PointWithdrawalCoinSellerConfig { + string app_code = 1; + int64 seller_user_id = 2; + int32 sort_order = 3; + int64 point_amount = 4; + int64 seller_coin_amount = 5; + repeated string service_country_codes = 6; + string status = 7; + int64 created_at_ms = 8; + int64 updated_at_ms = 9; +} + +message ListPointWithdrawalCoinSellersRequest { + string request_id = 1; + string app_code = 2; + // country_code 由 gateway 从登录用户资料注入;为空只用于 Admin/内部查询。 + string country_code = 3; + bool include_disabled = 4; +} + +message ListPointWithdrawalCoinSellersResponse { + repeated PointWithdrawalCoinSellerConfig sellers = 1; +} + +message TransferPointToCoinSellerRequest { + string command_id = 1; + string app_code = 2; + int64 source_user_id = 3; + int64 seller_user_id = 4; + int64 point_amount = 5; + // source_country_code 由 gateway 从用户资料读取,wallet 会再次校验币商服务国家。 + string source_country_code = 6; + string reason = 7; +} + +message TransferPointToCoinSellerResponse { + string transaction_id = 1; + int64 source_point_balance_after = 2; + int64 seller_balance_after = 3; + int64 point_amount = 4; + int64 seller_coin_amount = 5; + int64 ratio_point_amount = 6; + int64 ratio_seller_coin_amount = 7; +} + +message GetPointWithdrawalConfigRequest { + string request_id = 1; + string app_code = 2; + int64 region_id = 3; + int64 now_ms = 4; +} + +message GetPointWithdrawalConfigResponse { + bool found = 1; + int64 points_per_usd = 2; + int32 fee_bps = 3; + int64 minimum_points = 4; + string policy_instance_code = 5; +} + // WalletCronService 只给 cron-service 调用;账务状态仍由 wallet-service owner 修改。 service WalletCronService { rpc ProcessHostSalaryDailySettlementBatch(CronBatchRequest) returns (CronBatchResponse); @@ -2780,6 +2896,9 @@ service WalletService { rpc GetBalances(GetBalancesRequest) returns (GetBalancesResponse); rpc GetActiveHostSalaryPolicy(GetActiveHostSalaryPolicyRequest) returns (GetActiveHostSalaryPolicyResponse); rpc GetHostSalaryProgress(GetHostSalaryProgressRequest) returns (GetHostSalaryProgressResponse); + rpc GetHostRevenueStats(GetHostRevenueStatsRequest) returns (GetHostRevenueStatsResponse); + rpc GetAgencyPointShareStats(GetAgencyPointShareStatsRequest) returns (GetAgencyPointShareStatsResponse); + rpc GetAgencyHostGiftStats(GetAgencyHostGiftStatsRequest) returns (GetAgencyHostGiftStatsResponse); // GetTeamHostSalaryStats 按 Agency 收款人集合聚合主播预收入工资;经理中心团队工资卡片使用。 rpc GetTeamHostSalaryStats(GetTeamHostSalaryStatsRequest) returns (GetTeamHostSalaryStatsResponse); rpc AdminCreditAsset(AdminCreditAssetRequest) returns (AdminCreditAssetResponse); @@ -2789,6 +2908,9 @@ service WalletService { rpc ListCoinSellerSalaryExchangeRateTiers(ListCoinSellerSalaryExchangeRateTiersRequest) returns (ListCoinSellerSalaryExchangeRateTiersResponse); rpc ExchangeSalaryToCoin(ExchangeSalaryToCoinRequest) returns (ExchangeSalaryToCoinResponse); rpc TransferSalaryToCoinSeller(TransferSalaryToCoinSellerRequest) returns (TransferSalaryToCoinSellerResponse); + rpc ListPointWithdrawalCoinSellers(ListPointWithdrawalCoinSellersRequest) returns (ListPointWithdrawalCoinSellersResponse); + rpc TransferPointToCoinSeller(TransferPointToCoinSellerRequest) returns (TransferPointToCoinSellerResponse); + rpc GetPointWithdrawalConfig(GetPointWithdrawalConfigRequest) returns (GetPointWithdrawalConfigResponse); rpc FreezeSalaryWithdrawal(FreezeSalaryWithdrawalRequest) returns (FreezeSalaryWithdrawalResponse); rpc SettleSalaryWithdrawal(SettleSalaryWithdrawalRequest) returns (SettleSalaryWithdrawalResponse); rpc ReleaseSalaryWithdrawal(ReleaseSalaryWithdrawalRequest) returns (ReleaseSalaryWithdrawalResponse); diff --git a/api/proto/wallet/v1/wallet_grpc.pb.go b/api/proto/wallet/v1/wallet_grpc.pb.go index 8e16fcf7..a7653246 100644 --- a/api/proto/wallet/v1/wallet_grpc.pb.go +++ b/api/proto/wallet/v1/wallet_grpc.pb.go @@ -246,6 +246,9 @@ const ( WalletService_GetBalances_FullMethodName = "/hyapp.wallet.v1.WalletService/GetBalances" WalletService_GetActiveHostSalaryPolicy_FullMethodName = "/hyapp.wallet.v1.WalletService/GetActiveHostSalaryPolicy" WalletService_GetHostSalaryProgress_FullMethodName = "/hyapp.wallet.v1.WalletService/GetHostSalaryProgress" + WalletService_GetHostRevenueStats_FullMethodName = "/hyapp.wallet.v1.WalletService/GetHostRevenueStats" + WalletService_GetAgencyPointShareStats_FullMethodName = "/hyapp.wallet.v1.WalletService/GetAgencyPointShareStats" + WalletService_GetAgencyHostGiftStats_FullMethodName = "/hyapp.wallet.v1.WalletService/GetAgencyHostGiftStats" WalletService_GetTeamHostSalaryStats_FullMethodName = "/hyapp.wallet.v1.WalletService/GetTeamHostSalaryStats" WalletService_AdminCreditAsset_FullMethodName = "/hyapp.wallet.v1.WalletService/AdminCreditAsset" WalletService_AdminCreditCoinSellerStock_FullMethodName = "/hyapp.wallet.v1.WalletService/AdminCreditCoinSellerStock" @@ -254,6 +257,9 @@ const ( WalletService_ListCoinSellerSalaryExchangeRateTiers_FullMethodName = "/hyapp.wallet.v1.WalletService/ListCoinSellerSalaryExchangeRateTiers" WalletService_ExchangeSalaryToCoin_FullMethodName = "/hyapp.wallet.v1.WalletService/ExchangeSalaryToCoin" WalletService_TransferSalaryToCoinSeller_FullMethodName = "/hyapp.wallet.v1.WalletService/TransferSalaryToCoinSeller" + WalletService_ListPointWithdrawalCoinSellers_FullMethodName = "/hyapp.wallet.v1.WalletService/ListPointWithdrawalCoinSellers" + WalletService_TransferPointToCoinSeller_FullMethodName = "/hyapp.wallet.v1.WalletService/TransferPointToCoinSeller" + WalletService_GetPointWithdrawalConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/GetPointWithdrawalConfig" WalletService_FreezeSalaryWithdrawal_FullMethodName = "/hyapp.wallet.v1.WalletService/FreezeSalaryWithdrawal" WalletService_SettleSalaryWithdrawal_FullMethodName = "/hyapp.wallet.v1.WalletService/SettleSalaryWithdrawal" WalletService_ReleaseSalaryWithdrawal_FullMethodName = "/hyapp.wallet.v1.WalletService/ReleaseSalaryWithdrawal" @@ -372,6 +378,9 @@ type WalletServiceClient interface { GetBalances(ctx context.Context, in *GetBalancesRequest, opts ...grpc.CallOption) (*GetBalancesResponse, error) GetActiveHostSalaryPolicy(ctx context.Context, in *GetActiveHostSalaryPolicyRequest, opts ...grpc.CallOption) (*GetActiveHostSalaryPolicyResponse, error) GetHostSalaryProgress(ctx context.Context, in *GetHostSalaryProgressRequest, opts ...grpc.CallOption) (*GetHostSalaryProgressResponse, error) + GetHostRevenueStats(ctx context.Context, in *GetHostRevenueStatsRequest, opts ...grpc.CallOption) (*GetHostRevenueStatsResponse, error) + GetAgencyPointShareStats(ctx context.Context, in *GetAgencyPointShareStatsRequest, opts ...grpc.CallOption) (*GetAgencyPointShareStatsResponse, error) + GetAgencyHostGiftStats(ctx context.Context, in *GetAgencyHostGiftStatsRequest, opts ...grpc.CallOption) (*GetAgencyHostGiftStatsResponse, error) // GetTeamHostSalaryStats 按 Agency 收款人集合聚合主播预收入工资;经理中心团队工资卡片使用。 GetTeamHostSalaryStats(ctx context.Context, in *GetTeamHostSalaryStatsRequest, opts ...grpc.CallOption) (*GetTeamHostSalaryStatsResponse, error) AdminCreditAsset(ctx context.Context, in *AdminCreditAssetRequest, opts ...grpc.CallOption) (*AdminCreditAssetResponse, error) @@ -381,6 +390,9 @@ type WalletServiceClient interface { ListCoinSellerSalaryExchangeRateTiers(ctx context.Context, in *ListCoinSellerSalaryExchangeRateTiersRequest, opts ...grpc.CallOption) (*ListCoinSellerSalaryExchangeRateTiersResponse, error) ExchangeSalaryToCoin(ctx context.Context, in *ExchangeSalaryToCoinRequest, opts ...grpc.CallOption) (*ExchangeSalaryToCoinResponse, error) TransferSalaryToCoinSeller(ctx context.Context, in *TransferSalaryToCoinSellerRequest, opts ...grpc.CallOption) (*TransferSalaryToCoinSellerResponse, error) + ListPointWithdrawalCoinSellers(ctx context.Context, in *ListPointWithdrawalCoinSellersRequest, opts ...grpc.CallOption) (*ListPointWithdrawalCoinSellersResponse, error) + TransferPointToCoinSeller(ctx context.Context, in *TransferPointToCoinSellerRequest, opts ...grpc.CallOption) (*TransferPointToCoinSellerResponse, error) + GetPointWithdrawalConfig(ctx context.Context, in *GetPointWithdrawalConfigRequest, opts ...grpc.CallOption) (*GetPointWithdrawalConfigResponse, error) FreezeSalaryWithdrawal(ctx context.Context, in *FreezeSalaryWithdrawalRequest, opts ...grpc.CallOption) (*FreezeSalaryWithdrawalResponse, error) SettleSalaryWithdrawal(ctx context.Context, in *SettleSalaryWithdrawalRequest, opts ...grpc.CallOption) (*SettleSalaryWithdrawalResponse, error) ReleaseSalaryWithdrawal(ctx context.Context, in *ReleaseSalaryWithdrawalRequest, opts ...grpc.CallOption) (*ReleaseSalaryWithdrawalResponse, error) @@ -564,6 +576,36 @@ func (c *walletServiceClient) GetHostSalaryProgress(ctx context.Context, in *Get return out, nil } +func (c *walletServiceClient) GetHostRevenueStats(ctx context.Context, in *GetHostRevenueStatsRequest, opts ...grpc.CallOption) (*GetHostRevenueStatsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetHostRevenueStatsResponse) + err := c.cc.Invoke(ctx, WalletService_GetHostRevenueStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *walletServiceClient) GetAgencyPointShareStats(ctx context.Context, in *GetAgencyPointShareStatsRequest, opts ...grpc.CallOption) (*GetAgencyPointShareStatsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetAgencyPointShareStatsResponse) + err := c.cc.Invoke(ctx, WalletService_GetAgencyPointShareStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *walletServiceClient) GetAgencyHostGiftStats(ctx context.Context, in *GetAgencyHostGiftStatsRequest, opts ...grpc.CallOption) (*GetAgencyHostGiftStatsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetAgencyHostGiftStatsResponse) + err := c.cc.Invoke(ctx, WalletService_GetAgencyHostGiftStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *walletServiceClient) GetTeamHostSalaryStats(ctx context.Context, in *GetTeamHostSalaryStatsRequest, opts ...grpc.CallOption) (*GetTeamHostSalaryStatsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetTeamHostSalaryStatsResponse) @@ -644,6 +686,36 @@ func (c *walletServiceClient) TransferSalaryToCoinSeller(ctx context.Context, in return out, nil } +func (c *walletServiceClient) ListPointWithdrawalCoinSellers(ctx context.Context, in *ListPointWithdrawalCoinSellersRequest, opts ...grpc.CallOption) (*ListPointWithdrawalCoinSellersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListPointWithdrawalCoinSellersResponse) + err := c.cc.Invoke(ctx, WalletService_ListPointWithdrawalCoinSellers_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *walletServiceClient) TransferPointToCoinSeller(ctx context.Context, in *TransferPointToCoinSellerRequest, opts ...grpc.CallOption) (*TransferPointToCoinSellerResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(TransferPointToCoinSellerResponse) + err := c.cc.Invoke(ctx, WalletService_TransferPointToCoinSeller_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *walletServiceClient) GetPointWithdrawalConfig(ctx context.Context, in *GetPointWithdrawalConfigRequest, opts ...grpc.CallOption) (*GetPointWithdrawalConfigResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetPointWithdrawalConfigResponse) + err := c.cc.Invoke(ctx, WalletService_GetPointWithdrawalConfig_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *walletServiceClient) FreezeSalaryWithdrawal(ctx context.Context, in *FreezeSalaryWithdrawalRequest, opts ...grpc.CallOption) (*FreezeSalaryWithdrawalResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(FreezeSalaryWithdrawalResponse) @@ -1687,6 +1759,9 @@ type WalletServiceServer interface { GetBalances(context.Context, *GetBalancesRequest) (*GetBalancesResponse, error) GetActiveHostSalaryPolicy(context.Context, *GetActiveHostSalaryPolicyRequest) (*GetActiveHostSalaryPolicyResponse, error) GetHostSalaryProgress(context.Context, *GetHostSalaryProgressRequest) (*GetHostSalaryProgressResponse, error) + GetHostRevenueStats(context.Context, *GetHostRevenueStatsRequest) (*GetHostRevenueStatsResponse, error) + GetAgencyPointShareStats(context.Context, *GetAgencyPointShareStatsRequest) (*GetAgencyPointShareStatsResponse, error) + GetAgencyHostGiftStats(context.Context, *GetAgencyHostGiftStatsRequest) (*GetAgencyHostGiftStatsResponse, error) // GetTeamHostSalaryStats 按 Agency 收款人集合聚合主播预收入工资;经理中心团队工资卡片使用。 GetTeamHostSalaryStats(context.Context, *GetTeamHostSalaryStatsRequest) (*GetTeamHostSalaryStatsResponse, error) AdminCreditAsset(context.Context, *AdminCreditAssetRequest) (*AdminCreditAssetResponse, error) @@ -1696,6 +1771,9 @@ type WalletServiceServer interface { ListCoinSellerSalaryExchangeRateTiers(context.Context, *ListCoinSellerSalaryExchangeRateTiersRequest) (*ListCoinSellerSalaryExchangeRateTiersResponse, error) ExchangeSalaryToCoin(context.Context, *ExchangeSalaryToCoinRequest) (*ExchangeSalaryToCoinResponse, error) TransferSalaryToCoinSeller(context.Context, *TransferSalaryToCoinSellerRequest) (*TransferSalaryToCoinSellerResponse, error) + ListPointWithdrawalCoinSellers(context.Context, *ListPointWithdrawalCoinSellersRequest) (*ListPointWithdrawalCoinSellersResponse, error) + TransferPointToCoinSeller(context.Context, *TransferPointToCoinSellerRequest) (*TransferPointToCoinSellerResponse, error) + GetPointWithdrawalConfig(context.Context, *GetPointWithdrawalConfigRequest) (*GetPointWithdrawalConfigResponse, error) FreezeSalaryWithdrawal(context.Context, *FreezeSalaryWithdrawalRequest) (*FreezeSalaryWithdrawalResponse, error) SettleSalaryWithdrawal(context.Context, *SettleSalaryWithdrawalRequest) (*SettleSalaryWithdrawalResponse, error) ReleaseSalaryWithdrawal(context.Context, *ReleaseSalaryWithdrawalRequest) (*ReleaseSalaryWithdrawalResponse, error) @@ -1830,6 +1908,15 @@ func (UnimplementedWalletServiceServer) GetActiveHostSalaryPolicy(context.Contex func (UnimplementedWalletServiceServer) GetHostSalaryProgress(context.Context, *GetHostSalaryProgressRequest) (*GetHostSalaryProgressResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHostSalaryProgress not implemented") } +func (UnimplementedWalletServiceServer) GetHostRevenueStats(context.Context, *GetHostRevenueStatsRequest) (*GetHostRevenueStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetHostRevenueStats not implemented") +} +func (UnimplementedWalletServiceServer) GetAgencyPointShareStats(context.Context, *GetAgencyPointShareStatsRequest) (*GetAgencyPointShareStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAgencyPointShareStats not implemented") +} +func (UnimplementedWalletServiceServer) GetAgencyHostGiftStats(context.Context, *GetAgencyHostGiftStatsRequest) (*GetAgencyHostGiftStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAgencyHostGiftStats not implemented") +} func (UnimplementedWalletServiceServer) GetTeamHostSalaryStats(context.Context, *GetTeamHostSalaryStatsRequest) (*GetTeamHostSalaryStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetTeamHostSalaryStats not implemented") } @@ -1854,6 +1941,15 @@ func (UnimplementedWalletServiceServer) ExchangeSalaryToCoin(context.Context, *E func (UnimplementedWalletServiceServer) TransferSalaryToCoinSeller(context.Context, *TransferSalaryToCoinSellerRequest) (*TransferSalaryToCoinSellerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method TransferSalaryToCoinSeller not implemented") } +func (UnimplementedWalletServiceServer) ListPointWithdrawalCoinSellers(context.Context, *ListPointWithdrawalCoinSellersRequest) (*ListPointWithdrawalCoinSellersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPointWithdrawalCoinSellers not implemented") +} +func (UnimplementedWalletServiceServer) TransferPointToCoinSeller(context.Context, *TransferPointToCoinSellerRequest) (*TransferPointToCoinSellerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TransferPointToCoinSeller not implemented") +} +func (UnimplementedWalletServiceServer) GetPointWithdrawalConfig(context.Context, *GetPointWithdrawalConfigRequest) (*GetPointWithdrawalConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPointWithdrawalConfig not implemented") +} func (UnimplementedWalletServiceServer) FreezeSalaryWithdrawal(context.Context, *FreezeSalaryWithdrawalRequest) (*FreezeSalaryWithdrawalResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FreezeSalaryWithdrawal not implemented") } @@ -2310,6 +2406,60 @@ func _WalletService_GetHostSalaryProgress_Handler(srv interface{}, ctx context.C return interceptor(ctx, in, info, handler) } +func _WalletService_GetHostRevenueStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetHostRevenueStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).GetHostRevenueStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_GetHostRevenueStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).GetHostRevenueStats(ctx, req.(*GetHostRevenueStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WalletService_GetAgencyPointShareStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAgencyPointShareStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).GetAgencyPointShareStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_GetAgencyPointShareStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).GetAgencyPointShareStats(ctx, req.(*GetAgencyPointShareStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WalletService_GetAgencyHostGiftStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAgencyHostGiftStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).GetAgencyHostGiftStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_GetAgencyHostGiftStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).GetAgencyHostGiftStats(ctx, req.(*GetAgencyHostGiftStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _WalletService_GetTeamHostSalaryStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetTeamHostSalaryStatsRequest) if err := dec(in); err != nil { @@ -2454,6 +2604,60 @@ func _WalletService_TransferSalaryToCoinSeller_Handler(srv interface{}, ctx cont return interceptor(ctx, in, info, handler) } +func _WalletService_ListPointWithdrawalCoinSellers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPointWithdrawalCoinSellersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).ListPointWithdrawalCoinSellers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_ListPointWithdrawalCoinSellers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).ListPointWithdrawalCoinSellers(ctx, req.(*ListPointWithdrawalCoinSellersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WalletService_TransferPointToCoinSeller_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TransferPointToCoinSellerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).TransferPointToCoinSeller(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_TransferPointToCoinSeller_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).TransferPointToCoinSeller(ctx, req.(*TransferPointToCoinSellerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WalletService_GetPointWithdrawalConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetPointWithdrawalConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).GetPointWithdrawalConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_GetPointWithdrawalConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).GetPointWithdrawalConfig(ctx, req.(*GetPointWithdrawalConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _WalletService_FreezeSalaryWithdrawal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(FreezeSalaryWithdrawalRequest) if err := dec(in); err != nil { @@ -4343,6 +4547,18 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetHostSalaryProgress", Handler: _WalletService_GetHostSalaryProgress_Handler, }, + { + MethodName: "GetHostRevenueStats", + Handler: _WalletService_GetHostRevenueStats_Handler, + }, + { + MethodName: "GetAgencyPointShareStats", + Handler: _WalletService_GetAgencyPointShareStats_Handler, + }, + { + MethodName: "GetAgencyHostGiftStats", + Handler: _WalletService_GetAgencyHostGiftStats_Handler, + }, { MethodName: "GetTeamHostSalaryStats", Handler: _WalletService_GetTeamHostSalaryStats_Handler, @@ -4375,6 +4591,18 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{ MethodName: "TransferSalaryToCoinSeller", Handler: _WalletService_TransferSalaryToCoinSeller_Handler, }, + { + MethodName: "ListPointWithdrawalCoinSellers", + Handler: _WalletService_ListPointWithdrawalCoinSellers_Handler, + }, + { + MethodName: "TransferPointToCoinSeller", + Handler: _WalletService_TransferPointToCoinSeller_Handler, + }, + { + MethodName: "GetPointWithdrawalConfig", + Handler: _WalletService_GetPointWithdrawalConfig_Handler, + }, { MethodName: "FreezeSalaryWithdrawal", Handler: _WalletService_FreezeSalaryWithdrawal_Handler, diff --git a/server/admin/cmd/server/main.go b/server/admin/cmd/server/main.go index fd78849c..779bf7ba 100644 --- a/server/admin/cmd/server/main.go +++ b/server/admin/cmd/server/main.go @@ -63,6 +63,7 @@ import ( menumodule "hyapp-admin-server/internal/modules/menu" opscentermodule "hyapp-admin-server/internal/modules/opscenter" paymentmodule "hyapp-admin-server/internal/modules/payment" + pointwithdrawalconfigmodule "hyapp-admin-server/internal/modules/pointwithdrawalconfig" policyconfigmodule "hyapp-admin-server/internal/modules/policyconfig" prettyidmodule "hyapp-admin-server/internal/modules/prettyid" rbacmodule "hyapp-admin-server/internal/modules/rbac" @@ -397,40 +398,41 @@ func main() { gamemanagementmodule.WithRobotProfileSource(robotProfileSource), gamemanagementmodule.WithRobotAppearanceServices(walletclient.NewGRPC(walletConn), activityclient.NewGRPC(activityConn)), ), - GiftDiamond: giftdiamondmodule.New(walletDB, auditHandler), - Health: healthmodule.New(store, redisClient, jobStatus), - HostAgencyPolicy: hostagencypolicymodule.New(store, walletDB, auditHandler), - HostOrg: hostorgmodule.New(userclient.NewGRPC(userConn), walletclient.NewGRPC(walletConn), userDB, walletDB, sqlDB, auditHandler), - HostSalarySettlement: hostsalarysettlementmodule.New(walletDB, userDB, walletv1.NewWalletCronServiceClient(walletConn), cfg.WalletService.RequestTimeout, auditHandler), - HostWithdrawal: hostwithdrawalmodule.New(sqlDB, walletDB, userDB), - InviteActivityReward: inviteactivityrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), - Job: jobmodule.New(store, cfg, auditHandler), - LevelConfig: levelconfigmodule.New(activityclient.NewGRPC(activityConn), walletclient.NewGRPC(walletConn), auditHandler), - Menu: menumodule.New(store, auditHandler), - OpsCenter: opscentermodule.New(appRegistryService, luckyGiftHandler), - Payment: paymentHandler, - PolicyConfig: policyconfigmodule.New(sqlDB, walletDB, userDB, activityclient.NewGRPC(activityConn), auditHandler), - PrettyID: prettyidmodule.New(userclient.NewGRPC(userConn), auditHandler), - RBAC: rbacmodule.New(store, auditHandler), - RedPacket: redpacketmodule.New(walletclient.NewGRPC(walletConn), auditHandler), - Report: reportmodule.New(userDB, roomClient), - RegistrationReward: registrationrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), - RegionBlock: regionblockmodule.New(userDB, userclient.NewGRPC(userConn), auditHandler), - Resource: resourcemodule.New(walletclient.NewGRPC(walletConn), store, userDB, cfg.WalletService.RequestTimeout, auditHandler), - RiskConfig: riskconfigmodule.New(userclient.NewGRPC(userConn), auditHandler), - RoomAdmin: roomadminmodule.New(userDB, store, roomClient, robotClient, auditHandler), - RoomRocket: roomrocketmodule.New(roomClient, auditHandler), - RoomTurnoverReward: roomturnoverrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), - Search: searchmodule.New(store), - SevenDayCheckIn: sevendaycheckinmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), - Team: teammodule.New(store, auditHandler), - TeamSalaryPolicy: teamsalarypolicymodule.New(store, auditHandler), - TeamSalarySettlement: teamSalarySettlementHandler, - Upload: uploadmodule.New(objectUploader, cfg.TencentCOS.ObjectPrefix, auditHandler), - UserLeaderboard: userleaderboardmodule.New(walletDB, userDB, roomClient), - VIPConfig: vipconfigmodule.New(walletclient.NewGRPC(walletConn), auditHandler), - WeeklyStar: weeklystarmodule.New(activityclient.NewGRPC(activityConn), auditHandler), - Wheel: wheelmodule.New(activityclient.NewGRPC(activityConn), cfg.ActivityService.RequestTimeout, auditHandler), + GiftDiamond: giftdiamondmodule.New(walletDB, auditHandler), + Health: healthmodule.New(store, redisClient, jobStatus), + HostAgencyPolicy: hostagencypolicymodule.New(store, walletDB, auditHandler), + HostOrg: hostorgmodule.New(userclient.NewGRPC(userConn), walletclient.NewGRPC(walletConn), userDB, walletDB, sqlDB, auditHandler), + HostSalarySettlement: hostsalarysettlementmodule.New(walletDB, userDB, walletv1.NewWalletCronServiceClient(walletConn), cfg.WalletService.RequestTimeout, auditHandler), + HostWithdrawal: hostwithdrawalmodule.New(sqlDB, walletDB, userDB), + InviteActivityReward: inviteactivityrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), + Job: jobmodule.New(store, cfg, auditHandler), + LevelConfig: levelconfigmodule.New(activityclient.NewGRPC(activityConn), walletclient.NewGRPC(walletConn), auditHandler), + Menu: menumodule.New(store, auditHandler), + OpsCenter: opscentermodule.New(appRegistryService, luckyGiftHandler), + Payment: paymentHandler, + PolicyConfig: policyconfigmodule.New(sqlDB, walletDB, userDB, activityclient.NewGRPC(activityConn), auditHandler), + PointWithdrawalConfig: pointwithdrawalconfigmodule.New(walletDB, userDB, auditHandler), + PrettyID: prettyidmodule.New(userclient.NewGRPC(userConn), auditHandler), + RBAC: rbacmodule.New(store, auditHandler), + RedPacket: redpacketmodule.New(walletclient.NewGRPC(walletConn), auditHandler), + Report: reportmodule.New(userDB, roomClient), + RegistrationReward: registrationrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), + RegionBlock: regionblockmodule.New(userDB, userclient.NewGRPC(userConn), auditHandler), + Resource: resourcemodule.New(walletclient.NewGRPC(walletConn), store, userDB, cfg.WalletService.RequestTimeout, auditHandler), + RiskConfig: riskconfigmodule.New(userclient.NewGRPC(userConn), auditHandler), + RoomAdmin: roomadminmodule.New(userDB, store, roomClient, robotClient, auditHandler), + RoomRocket: roomrocketmodule.New(roomClient, auditHandler), + RoomTurnoverReward: roomturnoverrewardmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), + Search: searchmodule.New(store), + SevenDayCheckIn: sevendaycheckinmodule.New(activityclient.NewGRPC(activityConn), userDB, auditHandler), + Team: teammodule.New(store, auditHandler), + TeamSalaryPolicy: teamsalarypolicymodule.New(store, auditHandler), + TeamSalarySettlement: teamSalarySettlementHandler, + Upload: uploadmodule.New(objectUploader, cfg.TencentCOS.ObjectPrefix, auditHandler), + UserLeaderboard: userleaderboardmodule.New(walletDB, userDB, roomClient), + VIPConfig: vipconfigmodule.New(walletclient.NewGRPC(walletConn), auditHandler), + WeeklyStar: weeklystarmodule.New(activityclient.NewGRPC(activityConn), auditHandler), + Wheel: wheelmodule.New(activityclient.NewGRPC(activityConn), cfg.ActivityService.RequestTimeout, auditHandler), } engine := router.New(cfg, auth, handlers) diff --git a/server/admin/internal/model/models.go b/server/admin/internal/model/models.go index 32a296ae..91369b06 100644 --- a/server/admin/internal/model/models.go +++ b/server/admin/internal/model/models.go @@ -653,6 +653,11 @@ type UserWithdrawalApplication struct { SalaryAssetType string `gorm:"size:64;not null;default:''" json:"salaryAssetType"` WithdrawAmount string `gorm:"type:decimal(18,2);not null;default:0.00" json:"withdrawAmount"` WithdrawAmountMinor int64 `gorm:"not null;default:0" json:"withdrawAmountMinor"` + PointFeeAmount int64 `gorm:"not null;default:0" json:"pointFeeAmount"` + PointNetAmount int64 `gorm:"not null;default:0" json:"pointNetAmount"` + PointsPerUSD int64 `gorm:"not null;default:100000" json:"pointsPerUsd"` + PointFeeBPS int32 `gorm:"not null;default:500" json:"pointFeeBps"` + PointPolicyInstance string `gorm:"column:point_policy_instance_code;size:96;not null;default:''" json:"pointPolicyInstanceCode"` WithdrawMethod string `gorm:"size:64;index:idx_admin_withdrawal_method;not null;default:''" json:"withdrawMethod"` WithdrawAddress string `gorm:"size:255;not null;default:''" json:"withdrawAddress"` FreezeCommandID string `gorm:"size:128;not null;default:''" json:"freezeCommandId"` diff --git a/server/admin/internal/modules/financewithdrawal/response.go b/server/admin/internal/modules/financewithdrawal/response.go index c03999bf..cae15c08 100644 --- a/server/admin/internal/modules/financewithdrawal/response.go +++ b/server/admin/internal/modules/financewithdrawal/response.go @@ -15,6 +15,7 @@ type withdrawalApplicationDTO struct { PointNetAmount int64 `json:"pointNetAmount,omitempty"` PointsPerUSD int64 `json:"pointsPerUsd,omitempty"` PointFeeBPS int32 `json:"pointFeeBps,omitempty"` + PointPolicyInstance string `json:"pointPolicyInstanceCode,omitempty"` WithdrawMethod string `json:"withdrawMethod"` WithdrawAddress string `json:"withdrawAddress"` FreezeTransactionID string `json:"freezeTransactionId"` @@ -52,17 +53,35 @@ func withdrawalApplicationDTOFromModel(item model.UserWithdrawalApplication) wit UpdatedAtMS: item.UpdatedAtMS, } if isPointWithdrawalAssetType(item.SalaryAssetType) { - grossPoints := item.WithdrawAmountMinor - feePoints := grossPoints * int64(pointWithdrawalDefaultFeeBPS) / 10000 - dto.PointGrossAmount = grossPoints + feePoints, netPoints, pointsPerUSD, feeBPS := pointWithdrawalSnapshot(item) + dto.PointGrossAmount = item.WithdrawAmountMinor dto.PointFeeAmount = feePoints - dto.PointNetAmount = grossPoints - feePoints - dto.PointsPerUSD = pointWithdrawalDefaultPointsPerUSD - dto.PointFeeBPS = pointWithdrawalDefaultFeeBPS + dto.PointNetAmount = netPoints + dto.PointsPerUSD = pointsPerUSD + dto.PointFeeBPS = feeBPS + dto.PointPolicyInstance = item.PointPolicyInstance } return dto } +func pointWithdrawalSnapshot(item model.UserWithdrawalApplication) (feePoints int64, netPoints int64, pointsPerUSD int64, feeBPS int32) { + pointsPerUSD = item.PointsPerUSD + if pointsPerUSD <= 0 { + pointsPerUSD = pointWithdrawalDefaultPointsPerUSD + } + feeBPS = item.PointFeeBPS + if feeBPS < 0 || feeBPS > 10000 { + feeBPS = pointWithdrawalDefaultFeeBPS + } + feePoints, netPoints = item.PointFeeAmount, item.PointNetAmount + if feePoints < 0 || netPoints < 0 || feePoints+netPoints != item.WithdrawAmountMinor { + // 090 之前的存量 POINT 申请没有快照;只对这些不一致旧行按历史 5% 默认回填。 + feePoints = item.WithdrawAmountMinor * int64(feeBPS) / 10000 + netPoints = item.WithdrawAmountMinor - feePoints + } + return +} + func withdrawalApplicationDTOsFromModel(items []model.UserWithdrawalApplication) []withdrawalApplicationDTO { out := make([]withdrawalApplicationDTO, 0, len(items)) for _, item := range items { diff --git a/server/admin/internal/modules/financewithdrawal/service.go b/server/admin/internal/modules/financewithdrawal/service.go index 3cf2c10d..b41ebf42 100644 --- a/server/admin/internal/modules/financewithdrawal/service.go +++ b/server/admin/internal/modules/financewithdrawal/service.go @@ -92,7 +92,7 @@ func (s *Service) auditApplication(ctx context.Context, actor shared.Actor, id u } commandID := withdrawalAuditCommandID(id, decision) amountMinor := item.WithdrawAmountMinor - transactionID, err := s.applyWalletDecision(ctx, decision, commandID, appCode, userID, item.SalaryAssetType, amountMinor, actor, strings.TrimSpace(remark), id) + transactionID, err := s.applyWalletDecision(ctx, decision, commandID, appCode, userID, item.SalaryAssetType, amountMinor, item.PointFeeAmount, item.PointNetAmount, item.PointsPerUSD, item.PointFeeBPS, actor, strings.TrimSpace(remark), id) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func (s *Service) auditApplication(ctx context.Context, actor shared.Actor, id u return &dto, nil } -func (s *Service) applyWalletDecision(ctx context.Context, decision string, commandID string, appCode string, userID int64, assetType string, amountMinor int64, actor shared.Actor, remark string, applicationID uint) (string, error) { +func (s *Service) applyWalletDecision(ctx context.Context, decision string, commandID string, appCode string, userID int64, assetType string, amountMinor int64, storedFeePoints int64, storedNetPoints int64, storedPointsPerUSD int64, storedFeeBPS int32, actor shared.Actor, remark string, applicationID uint) (string, error) { reason := strings.TrimSpace(remark) if reason == "" { reason = "salary withdrawal " + decision @@ -141,8 +141,10 @@ func (s *Service) applyWalletDecision(ctx context.Context, decision string, comm if !ok { return "", errors.New("point withdrawal wallet executor is not configured") } - feePoints := amountMinor * int64(pointWithdrawalDefaultFeeBPS) / 10000 - netPoints := amountMinor - feePoints + feePoints, netPoints, pointsPerUSD, feeBPS := pointWithdrawalSnapshot(model.UserWithdrawalApplication{ + WithdrawAmountMinor: amountMinor, PointFeeAmount: storedFeePoints, PointNetAmount: storedNetPoints, + PointsPerUSD: storedPointsPerUSD, PointFeeBPS: storedFeeBPS, + }) switch decision { case model.WithdrawalApplicationStatusApproved: resp, err := pointWallet.SettlePointWithdrawal(ctx, &walletv1.SettlePointWithdrawalRequest{ @@ -152,8 +154,8 @@ func (s *Service) applyWalletDecision(ctx context.Context, decision string, comm GrossPointAmount: amountMinor, FeePointAmount: feePoints, NetPointAmount: netPoints, - PointsPerUsd: pointWithdrawalDefaultPointsPerUSD, - FeeBps: pointWithdrawalDefaultFeeBPS, + PointsPerUsd: pointsPerUSD, + FeeBps: feeBPS, OperatorUserId: int64(actor.UserID), Reason: reason, AppCode: appCode, @@ -171,8 +173,8 @@ func (s *Service) applyWalletDecision(ctx context.Context, decision string, comm GrossPointAmount: amountMinor, FeePointAmount: feePoints, NetPointAmount: netPoints, - PointsPerUsd: pointWithdrawalDefaultPointsPerUSD, - FeeBps: pointWithdrawalDefaultFeeBPS, + PointsPerUsd: pointsPerUSD, + FeeBps: feeBPS, OperatorUserId: int64(actor.UserID), Reason: reason, AppCode: appCode, diff --git a/server/admin/internal/modules/financewithdrawal/service_test.go b/server/admin/internal/modules/financewithdrawal/service_test.go index af644bb8..30c95036 100644 --- a/server/admin/internal/modules/financewithdrawal/service_test.go +++ b/server/admin/internal/modules/financewithdrawal/service_test.go @@ -14,7 +14,7 @@ func TestApplyWalletDecisionRoutesPointApprovalToPointSettlement(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} - transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:77:approved", "huwaa", 42001, "POINT", 1_000_000, shared.Actor{UserID: 90001}, "paid", 77) + transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:77:approved", "fami", 42001, "POINT", 1_000_000, 25_000, 975_000, 200_000, 250, shared.Actor{UserID: 90001}, "paid", 77) if err != nil { t.Fatalf("apply point approval failed: %v", err) } @@ -23,12 +23,14 @@ func TestApplyWalletDecisionRoutesPointApprovalToPointSettlement(t *testing.T) { } if wallet.settlePoint == nil || wallet.settlePoint.GetCommandId() != "audit:77:approved" || - wallet.settlePoint.GetAppCode() != "huwaa" || + wallet.settlePoint.GetAppCode() != "fami" || wallet.settlePoint.GetUserId() != 42001 || wallet.settlePoint.GetAssetType() != "POINT" || wallet.settlePoint.GetGrossPointAmount() != 1_000_000 || - wallet.settlePoint.GetFeePointAmount() != 50_000 || - wallet.settlePoint.GetNetPointAmount() != 950_000 || + wallet.settlePoint.GetFeePointAmount() != 25_000 || + wallet.settlePoint.GetNetPointAmount() != 975_000 || + wallet.settlePoint.GetPointsPerUsd() != 200_000 || + wallet.settlePoint.GetFeeBps() != 250 || wallet.settlePoint.GetOperatorUserId() != 90001 || wallet.settlePoint.GetWithdrawalApplicationId() != "77" { t.Fatalf("SettlePointWithdrawal payload mismatch: %+v", wallet.settlePoint) @@ -42,7 +44,7 @@ func TestApplyWalletDecisionRoutesPointRejectionToPointRelease(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} - transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusRejected, "audit:78:rejected", "huwaa", 42002, "COIN_SELLER_POINT", 2_000_000, shared.Actor{UserID: 90002}, "bad address", 78) + transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusRejected, "audit:78:rejected", "huwaa", 42002, "COIN_SELLER_POINT", 2_000_000, 100_000, 1_900_000, 100_000, 500, shared.Actor{UserID: 90002}, "bad address", 78) if err != nil { t.Fatalf("apply point rejection failed: %v", err) } @@ -71,7 +73,7 @@ func TestApplyWalletDecisionKeepsLegacySalaryAssetsOnSalaryRPC(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} - transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:79:approved", "lalu", 42003, "HOST_SALARY_USD", 12_345, shared.Actor{UserID: 90003}, "", 79) + transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:79:approved", "lalu", 42003, "HOST_SALARY_USD", 12_345, 0, 0, 0, 0, shared.Actor{UserID: 90003}, "", 79) if err != nil { t.Fatalf("apply salary approval failed: %v", err) } diff --git a/server/admin/internal/modules/pointwithdrawalconfig/dto.go b/server/admin/internal/modules/pointwithdrawalconfig/dto.go new file mode 100644 index 00000000..e2aa327e --- /dev/null +++ b/server/admin/internal/modules/pointwithdrawalconfig/dto.go @@ -0,0 +1,26 @@ +package pointwithdrawalconfig + +type itemDTO struct { + AppCode string `json:"appCode"` + SellerUserID string `json:"sellerUserId"` + DisplayUserID string `json:"displayUserId"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + CountryName string `json:"countryName"` + SortOrder int `json:"sortOrder"` + PointAmount int64 `json:"pointAmount"` + SellerCoinAmount int64 `json:"sellerCoinAmount"` + ServiceCountryCodes []string `json:"serviceCountryCodes"` + Status string `json:"status"` + CreatedAtMS int64 `json:"createdAtMs"` + UpdatedAtMS int64 `json:"updatedAtMs"` +} + +type upsertRequest struct { + SellerUserID int64 `json:"sellerUserId" binding:"required"` + SortOrder int `json:"sortOrder"` + PointAmount int64 `json:"pointAmount" binding:"required"` + SellerCoinAmount int64 `json:"sellerCoinAmount" binding:"required"` + ServiceCountryCodes []string `json:"serviceCountryCodes"` + Status string `json:"status"` +} diff --git a/server/admin/internal/modules/pointwithdrawalconfig/handler.go b/server/admin/internal/modules/pointwithdrawalconfig/handler.go new file mode 100644 index 00000000..cdca4178 --- /dev/null +++ b/server/admin/internal/modules/pointwithdrawalconfig/handler.go @@ -0,0 +1,66 @@ +package pointwithdrawalconfig + +import ( + "database/sql" + "errors" + "strconv" + "strings" + + "hyapp-admin-server/internal/appctx" + "hyapp-admin-server/internal/modules/shared" + "hyapp-admin-server/internal/response" + + "github.com/gin-gonic/gin" +) + +type Handler struct { + service *Service + audit shared.OperationLogger +} + +func New(walletDB *sql.DB, userDB *sql.DB, audit shared.OperationLogger) *Handler { + return &Handler{service: NewService(walletDB, userDB), audit: audit} +} + +func (h *Handler) List(c *gin.Context) { + items, err := h.service.List(c.Request.Context(), appctx.FromContext(c.Request.Context())) + if err != nil { + response.ServerError(c, "获取币商提现白名单失败") + return + } + response.OK(c, map[string]any{"items": items}) +} + +func (h *Handler) Upsert(c *gin.Context) { + var req upsertRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "币商提现配置参数不正确") + return + } + item, err := h.service.Upsert(c.Request.Context(), appctx.FromContext(c.Request.Context()), req, int64(shared.ActorFromContext(c).UserID)) + if err != nil { + response.BadRequest(c, err.Error()) + return + } + shared.OperationLogWithResourceID(c, h.audit, "point-withdrawal-coin-seller-upsert", "point_withdrawal_coin_seller_configs", item.AppCode+":"+item.SellerUserID, "success", "ratio="+strconv.FormatInt(item.PointAmount, 10)+":"+strconv.FormatInt(item.SellerCoinAmount, 10)) + response.OK(c, item) +} + +func (h *Handler) Delete(c *gin.Context) { + sellerUserID, err := strconv.ParseInt(strings.TrimSpace(c.Param("seller_user_id")), 10, 64) + if err != nil || sellerUserID <= 0 { + response.BadRequest(c, "币商 ID 不正确") + return + } + appCode := appctx.FromContext(c.Request.Context()) + if err := h.service.Delete(c.Request.Context(), appCode, sellerUserID); err != nil { + if errors.Is(err, sql.ErrNoRows) { + response.NotFound(c, "配置不存在") + return + } + response.ServerError(c, "删除币商提现配置失败") + return + } + shared.OperationLogWithResourceID(c, h.audit, "point-withdrawal-coin-seller-delete", "point_withdrawal_coin_seller_configs", appCode+":"+strconv.FormatInt(sellerUserID, 10), "success", "") + response.OK(c, map[string]any{"deleted": true}) +} diff --git a/server/admin/internal/modules/pointwithdrawalconfig/routes.go b/server/admin/internal/modules/pointwithdrawalconfig/routes.go new file mode 100644 index 00000000..aeeb556b --- /dev/null +++ b/server/admin/internal/modules/pointwithdrawalconfig/routes.go @@ -0,0 +1,16 @@ +package pointwithdrawalconfig + +import ( + "hyapp-admin-server/internal/middleware" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(protected *gin.RouterGroup, h *Handler) { + if h == nil { + return + } + protected.GET("/admin/point-withdrawal/coin-sellers", middleware.RequirePermission("point-withdrawal-config:view"), h.List) + protected.PUT("/admin/point-withdrawal/coin-sellers", middleware.RequirePermission("point-withdrawal-config:update"), h.Upsert) + protected.DELETE("/admin/point-withdrawal/coin-sellers/:seller_user_id", middleware.RequirePermission("point-withdrawal-config:update"), h.Delete) +} diff --git a/server/admin/internal/modules/pointwithdrawalconfig/service.go b/server/admin/internal/modules/pointwithdrawalconfig/service.go new file mode 100644 index 00000000..2a0568a8 --- /dev/null +++ b/server/admin/internal/modules/pointwithdrawalconfig/service.go @@ -0,0 +1,201 @@ +package pointwithdrawalconfig + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "sort" + "strconv" + "strings" + "time" +) + +type Service struct { + walletDB *sql.DB + userDB *sql.DB +} + +func NewService(walletDB *sql.DB, userDB *sql.DB) *Service { + return &Service{walletDB: walletDB, userDB: userDB} +} + +// List 按 app_code 读取同一套公共配置表,并补齐用户资料;孤儿配置仍返回,便于运营删除而不是静默隐藏。 +func (s *Service) List(ctx context.Context, appCode string) ([]itemDTO, error) { + if err := s.ensureSchema(ctx); err != nil { + return nil, err + } + rows, err := s.walletDB.QueryContext(ctx, ` + SELECT app_code, seller_user_id, sort_order, point_amount, seller_coin_amount, + service_country_codes, status, created_at_ms, updated_at_ms + FROM point_withdrawal_coin_seller_configs + WHERE app_code = ? + ORDER BY sort_order ASC, seller_user_id ASC`, normalizeAppCode(appCode)) + if err != nil { + return nil, err + } + defer rows.Close() + items := make([]itemDTO, 0) + for rows.Next() { + var item itemDTO + var sellerUserID int64 + var countriesJSON []byte + if err := rows.Scan(&item.AppCode, &sellerUserID, &item.SortOrder, &item.PointAmount, &item.SellerCoinAmount, &countriesJSON, &item.Status, &item.CreatedAtMS, &item.UpdatedAtMS); err != nil { + return nil, err + } + item.SellerUserID = strconv.FormatInt(sellerUserID, 10) + if err := json.Unmarshal(countriesJSON, &item.ServiceCountryCodes); err != nil { + return nil, fmt.Errorf("parse service countries for seller %d: %w", sellerUserID, err) + } + item.ServiceCountryCodes = normalizeCountries(item.ServiceCountryCodes) + displayUserID, nickname, avatar, countryName, lookupErr := s.lookupSeller(ctx, item.AppCode, sellerUserID, false) + if lookupErr != nil && !errors.Is(lookupErr, sql.ErrNoRows) { + return nil, lookupErr + } + item.DisplayUserID, item.Nickname, item.Avatar, item.CountryName = displayUserID, nickname, avatar, countryName + items = append(items, item) + } + return items, rows.Err() +} + +// Upsert 在写白名单前验证同 App 的 active 币商身份,防止普通用户被配置成账务收款方。 +func (s *Service) Upsert(ctx context.Context, appCode string, req upsertRequest, adminID int64) (itemDTO, error) { + appCode = normalizeAppCode(appCode) + if req.SellerUserID <= 0 || req.PointAmount <= 0 || req.SellerCoinAmount <= 0 || req.SortOrder < 0 { + return itemDTO{}, errors.New("币商、排序和兑换比例必须是正数") + } + status := strings.ToLower(strings.TrimSpace(req.Status)) + if status == "" { + status = "active" + } + if status != "active" && status != "disabled" { + return itemDTO{}, errors.New("状态只能是 active 或 disabled") + } + if _, _, _, _, err := s.lookupSeller(ctx, appCode, req.SellerUserID, true); err != nil { + return itemDTO{}, err + } + if err := s.ensureSchema(ctx); err != nil { + return itemDTO{}, err + } + countries := normalizeCountries(req.ServiceCountryCodes) + countriesJSON, err := json.Marshal(countries) + if err != nil { + return itemDTO{}, err + } + nowMS := time.Now().UTC().UnixMilli() + _, err = s.walletDB.ExecContext(ctx, ` + INSERT INTO point_withdrawal_coin_seller_configs ( + app_code, seller_user_id, sort_order, point_amount, seller_coin_amount, service_country_codes, + status, created_by_admin_id, updated_by_admin_id, created_at_ms, updated_at_ms + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + sort_order = VALUES(sort_order), point_amount = VALUES(point_amount), + seller_coin_amount = VALUES(seller_coin_amount), service_country_codes = VALUES(service_country_codes), + status = VALUES(status), updated_by_admin_id = VALUES(updated_by_admin_id), updated_at_ms = VALUES(updated_at_ms)`, + appCode, req.SellerUserID, req.SortOrder, req.PointAmount, req.SellerCoinAmount, countriesJSON, + status, adminID, adminID, nowMS, nowMS) + if err != nil { + return itemDTO{}, err + } + return s.Get(ctx, appCode, req.SellerUserID) +} + +func (s *Service) Get(ctx context.Context, appCode string, sellerUserID int64) (itemDTO, error) { + items, err := s.List(ctx, appCode) + if err != nil { + return itemDTO{}, err + } + needle := strconv.FormatInt(sellerUserID, 10) + for _, item := range items { + if item.SellerUserID == needle { + return item, nil + } + } + return itemDTO{}, sql.ErrNoRows +} + +func (s *Service) Delete(ctx context.Context, appCode string, sellerUserID int64) error { + if sellerUserID <= 0 { + return errors.New("币商 ID 不正确") + } + if err := s.ensureSchema(ctx); err != nil { + return err + } + result, err := s.walletDB.ExecContext(ctx, `DELETE FROM point_withdrawal_coin_seller_configs WHERE app_code = ? AND seller_user_id = ?`, normalizeAppCode(appCode), sellerUserID) + if err != nil { + return err + } + affected, err := result.RowsAffected() + if err != nil { + return err + } + if affected == 0 { + return sql.ErrNoRows + } + return nil +} + +func (s *Service) lookupSeller(ctx context.Context, appCode string, sellerUserID int64, requireActive bool) (displayUserID string, nickname string, avatar string, countryName string, err error) { + if s.userDB == nil { + return "", "", "", "", errors.New("user db is not configured") + } + query := ` + SELECT COALESCE(u.current_display_user_id, ''), COALESCE(u.username, ''), COALESCE(u.avatar, ''), + COALESCE(c.country_display_name, c.country_name, u.country, '') + FROM coin_seller_profiles csp + JOIN users u ON u.user_id = csp.user_id AND u.app_code = csp.app_code + LEFT JOIN countries c ON c.app_code = u.app_code AND c.country_code = u.country + WHERE csp.app_code = ? AND csp.user_id = ?` + if requireActive { + query += " AND csp.status = 'active' AND u.status = 'active'" + } + query += " LIMIT 1" + err = s.userDB.QueryRowContext(ctx, query, appCode, sellerUserID).Scan(&displayUserID, &nickname, &avatar, &countryName) + if errors.Is(err, sql.ErrNoRows) && requireActive { + return "", "", "", "", errors.New("目标用户不是当前 App 的启用币商") + } + return +} + +func (s *Service) ensureSchema(ctx context.Context) error { + if s == nil || s.walletDB == nil { + return errors.New("wallet db is not configured") + } + _, err := s.walletDB.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS point_withdrawal_coin_seller_configs ( + app_code VARCHAR(32) NOT NULL, seller_user_id BIGINT NOT NULL, sort_order INT NOT NULL DEFAULT 0, + point_amount BIGINT NOT NULL, seller_coin_amount BIGINT NOT NULL, service_country_codes JSON NOT NULL, + status VARCHAR(24) NOT NULL DEFAULT 'active', created_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + updated_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, created_at_ms BIGINT NOT NULL, updated_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, seller_user_id), + KEY idx_point_withdraw_seller_list (app_code, status, sort_order, seller_user_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='POINT 提现币商白名单与兑换比例'`) + return err +} + +func normalizeCountries(values []string) []string { + seen := map[string]struct{}{} + out := make([]string, 0, len(values)) + for _, value := range values { + value = strings.ToUpper(strings.TrimSpace(value)) + if value == "" || len(value) > 16 { + continue + } + if _, exists := seen[value]; exists { + continue + } + seen[value] = struct{}{} + out = append(out, value) + } + sort.Strings(out) + return out +} + +func normalizeAppCode(value string) string { + value = strings.ToLower(strings.TrimSpace(value)) + if value == "" { + return "lalu" + } + return value +} diff --git a/server/admin/internal/modules/pointwithdrawalconfig/service_test.go b/server/admin/internal/modules/pointwithdrawalconfig/service_test.go new file mode 100644 index 00000000..be8b8b36 --- /dev/null +++ b/server/admin/internal/modules/pointwithdrawalconfig/service_test.go @@ -0,0 +1,23 @@ +package pointwithdrawalconfig + +import ( + "reflect" + "testing" +) + +func TestNormalizeCountriesCanonicalizesWhitelist(t *testing.T) { + got := normalizeCountries([]string{" sa ", "TR", "sa", "", "country-code-that-is-too-long"}) + want := []string{"SA", "TR"} + if !reflect.DeepEqual(got, want) { + t.Fatalf("normalizeCountries() = %v, want %v", got, want) + } +} + +func TestNormalizeAppCodeKeepsLegacyDefault(t *testing.T) { + if got := normalizeAppCode(""); got != "lalu" { + t.Fatalf("empty app code = %q, want lalu", got) + } + if got := normalizeAppCode(" FAMI "); got != "fami" { + t.Fatalf("Fami app code = %q, want fami", got) + } +} diff --git a/server/admin/internal/modules/policyconfig/service.go b/server/admin/internal/modules/policyconfig/service.go index 773fb706..2dd799ab 100644 --- a/server/admin/internal/modules/policyconfig/service.go +++ b/server/admin/internal/modules/policyconfig/service.go @@ -10,6 +10,7 @@ import ( "strings" "time" + mysqlDriver "github.com/go-sql-driver/mysql" "hyapp-admin-server/internal/appctx" "hyapp-admin-server/internal/integration/activityclient" activityv1 "hyapp.local/api/proto/activity/v1" @@ -64,6 +65,7 @@ type policyInstanceRow struct { type compiledPolicy struct { HostPointRatioPPM int64 + AgencyPointRatioPPM int64 PointsPerUSD int64 WithdrawFeeBPS int64 TaskRewardAssetType string @@ -496,12 +498,12 @@ func (s *Service) publishWalletRuntime(ctx context.Context, item policyInstanceR if _, err := tx.ExecContext(ctx, ` INSERT INTO wallet_policy_instances ( app_code, instance_code, template_code, template_version, region_id, status, - effective_from_ms, effective_to_ms, host_point_asset_type, host_point_ratio_ppm, + effective_from_ms, effective_to_ms, host_point_asset_type, host_point_ratio_ppm, agency_point_ratio_ppm, points_per_usd, withdraw_fee_bps, rule_json, published_by_admin_id, published_at_ms, created_at_ms, updated_at_ms - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'POINT', ?, ?, ?, CAST(? AS JSON), ?, ?, ?, ?)`, + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'POINT', ?, ?, ?, ?, CAST(? AS JSON), ?, ?, ?, ?)`, item.AppCode, item.InstanceCode, item.TemplateCode, item.TemplateVersion, regionID, item.Status, - item.EffectiveFromMS, item.EffectiveToMS, compiled.HostPointRatioPPM, compiled.PointsPerUSD, + item.EffectiveFromMS, item.EffectiveToMS, compiled.HostPointRatioPPM, compiled.AgencyPointRatioPPM, compiled.PointsPerUSD, compiled.WithdrawFeeBPS, string(compiled.RuleJSON), actorID, nowMS, nowMS, nowMS, ); err != nil { return err @@ -563,6 +565,7 @@ func ensureWalletPolicyRuntimeTable(ctx context.Context, db *sql.DB) error { effective_to_ms BIGINT NOT NULL DEFAULT 0 COMMENT '0 表示长期有效', host_point_asset_type VARCHAR(32) NOT NULL DEFAULT 'POINT' COMMENT '主播收益积分资产', host_point_ratio_ppm BIGINT NOT NULL DEFAULT 700000 COMMENT '有效付费礼物转 POINT 比例,ppm', + agency_point_ratio_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '有效付费礼物给 Agency owner 的 POINT 分成比例,ppm', points_per_usd BIGINT NOT NULL DEFAULT 100000 COMMENT 'POINT/USD 展示换算比例', withdraw_fee_bps INT NOT NULL DEFAULT 500 COMMENT '提现手续费 bps', rule_json JSON NOT NULL COMMENT '完整政策快照', @@ -573,7 +576,19 @@ func ensureWalletPolicyRuntimeTable(ctx context.Context, db *sql.DB) error { PRIMARY KEY (app_code, instance_code, region_id), KEY idx_wallet_policy_active (app_code, region_id, status, effective_from_ms, effective_to_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包运行侧收益政策实例表'`) - return err + if err != nil { + return err + } + // 运行库可能是旧版本建表;幂等补列保证发布新策略时不会因列缺失中断。 + if _, err := db.ExecContext(ctx, `ALTER TABLE wallet_policy_instances ADD COLUMN agency_point_ratio_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '有效付费礼物给 Agency owner 的 POINT 分成比例,ppm' AFTER host_point_ratio_ppm`); err != nil && !isDuplicateColumnError(err) { + return err + } + return nil +} + +func isDuplicateColumnError(err error) bool { + var mysqlErr *mysqlDriver.MySQLError + return errors.As(err, &mysqlErr) && mysqlErr.Number == 1060 } func (s *Service) insertPublishItems(ctx context.Context, jobID uint64, appCode string, regionIDs []int64, activitySucceeded bool, nowMS int64) error { @@ -635,11 +650,15 @@ func compilePolicy(raw json.RawMessage) (compiledPolicy, error) { pointsPerUSD := int64FromJSON(decoded["points_per_usd"], 100000) host, _ := decoded["host"].(map[string]any) hostRatioPercent := floatFromJSON(host["point_ratio_percent"], 70) + agency, _ := decoded["agency"].(map[string]any) + // Agency 比例由跨 App 共用的策略模板显式配置;旧模板缺字段时保持 0,避免发布动作隐式改变存量 App 账务。 + agencyRatioPercent := floatFromJSON(agency["point_ratio_percent"], 0) withdrawFeeBPS := int64FromJSON(host["withdraw_fee_bps"], 500) ratioPPM := int64(math.Round(hostRatioPercent * 10000)) + agencyRatioPPM := int64(math.Round(agencyRatioPercent * 10000)) tasks, _ := decoded["tasks"].(map[string]any) taskRewardAssetType := strings.ToUpper(strings.TrimSpace(stringFromJSON(tasks["reward_asset_type"], policyTaskRewardAssetCoin))) - if pointsPerUSD <= 0 || ratioPPM <= 0 || ratioPPM > 1000000 || withdrawFeeBPS < 0 || withdrawFeeBPS > 10000 { + if pointsPerUSD <= 0 || ratioPPM <= 0 || ratioPPM > 1000000 || agencyRatioPPM < 0 || agencyRatioPPM > 1000000 || ratioPPM+agencyRatioPPM > 1000000 || withdrawFeeBPS < 0 || withdrawFeeBPS > 10000 { return compiledPolicy{}, errors.New("rule_json host point policy is invalid") } if taskRewardAssetType != policyTaskRewardAssetCoin && taskRewardAssetType != "POINT" { @@ -647,6 +666,7 @@ func compilePolicy(raw json.RawMessage) (compiledPolicy, error) { } return compiledPolicy{ HostPointRatioPPM: ratioPPM, + AgencyPointRatioPPM: agencyRatioPPM, PointsPerUSD: pointsPerUSD, WithdrawFeeBPS: withdrawFeeBPS, TaskRewardAssetType: taskRewardAssetType, diff --git a/server/admin/internal/modules/policyconfig/service_test.go b/server/admin/internal/modules/policyconfig/service_test.go index 4a23b072..603c8698 100644 --- a/server/admin/internal/modules/policyconfig/service_test.go +++ b/server/admin/internal/modules/policyconfig/service_test.go @@ -3,6 +3,7 @@ package policyconfig import ( "context" "database/sql" + "encoding/json" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -60,6 +61,7 @@ func TestPublishRuntimeWritesWalletRowsAndActivityTaskRewardPolicy(t *testing.T) } compiled := compiledPolicy{ HostPointRatioPPM: 700000, + AgencyPointRatioPPM: 0, PointsPerUSD: 100000, WithdrawFeeBPS: 500, TaskRewardAssetType: "POINT", @@ -67,6 +69,7 @@ func TestPublishRuntimeWritesWalletRowsAndActivityTaskRewardPolicy(t *testing.T) } walletMock.ExpectExec(`(?s)CREATE TABLE IF NOT EXISTS wallet_policy_instances`).WillReturnResult(sqlmock.NewResult(0, 0)) + walletMock.ExpectExec(`(?s)ALTER TABLE wallet_policy_instances ADD COLUMN agency_point_ratio_ppm`).WillReturnResult(sqlmock.NewResult(0, 0)) walletMock.ExpectBegin() walletMock.ExpectExec(`DELETE FROM wallet_policy_instances WHERE app_code = \? AND instance_code = \?`). WithArgs("huwaa", "huwaa-point-live"). @@ -83,6 +86,7 @@ func TestPublishRuntimeWritesWalletRowsAndActivityTaskRewardPolicy(t *testing.T) int64(1700000000000), int64(0), int64(700000), + int64(0), int64(100000), int64(500), string(compiled.RuleJSON), @@ -147,6 +151,7 @@ func TestUpdateInstanceStatusSyncsWalletRuntimeAndActivityRuntime(t *testing.T) WithArgs(policyStatusDisabled, uint(90002), sqlmock.AnyArg(), "huwaa", uint64(9)). WillReturnResult(sqlmock.NewResult(0, 1)) walletMock.ExpectExec(`(?s)CREATE TABLE IF NOT EXISTS wallet_policy_instances`).WillReturnResult(sqlmock.NewResult(0, 0)) + walletMock.ExpectExec(`(?s)ALTER TABLE wallet_policy_instances ADD COLUMN agency_point_ratio_ppm`).WillReturnResult(sqlmock.NewResult(0, 0)) walletMock.ExpectExec(`(?s)UPDATE wallet_policy_instances\s+SET status = \?, updated_at_ms = \?\s+WHERE app_code = \? AND instance_code = \?`). WithArgs(policyStatusDisabled, sqlmock.AnyArg(), "huwaa", "huwaa-point-live"). WillReturnResult(sqlmock.NewResult(0, 1)) @@ -191,6 +196,24 @@ func TestUpdateInstanceStatusSyncsWalletRuntimeAndActivityRuntime(t *testing.T) } } +func TestCompilePolicyUsesExplicitAgencyRatioAndKeepsLegacyDefaultZero(t *testing.T) { + ruleJSON := json.RawMessage(`{"host":{"point_ratio_percent":70}}`) + fami, err := compilePolicy(ruleJSON) + if err != nil { + t.Fatalf("compile Fami policy failed: %v", err) + } + if fami.AgencyPointRatioPPM != 0 { + t.Fatalf("legacy policy without agency section must remain zero: %+v", fami) + } + configured, err := compilePolicy(json.RawMessage(`{"host":{"point_ratio_percent":70},"agency":{"point_ratio_percent":20}}`)) + if err != nil { + t.Fatalf("compile configured policy failed: %v", err) + } + if configured.AgencyPointRatioPPM != 200000 { + t.Fatalf("configured agency ratio mismatch: %+v", configured) + } +} + type fakePolicyActivityClient struct { activityclient.Client last *activityv1.PublishTaskRewardPolicyRequest diff --git a/server/admin/internal/router/router.go b/server/admin/internal/router/router.go index 0873fc71..3b2b0324 100644 --- a/server/admin/internal/router/router.go +++ b/server/admin/internal/router/router.go @@ -37,6 +37,7 @@ import ( "hyapp-admin-server/internal/modules/menu" "hyapp-admin-server/internal/modules/opscenter" "hyapp-admin-server/internal/modules/payment" + "hyapp-admin-server/internal/modules/pointwithdrawalconfig" "hyapp-admin-server/internal/modules/policyconfig" "hyapp-admin-server/internal/modules/prettyid" "hyapp-admin-server/internal/modules/rbac" @@ -66,62 +67,63 @@ import ( ) type Handlers struct { - AdminUser *adminuser.Handler - AgencyOpening *agencyopening.Handler - AchievementConfig *achievementconfig.Handler - AppConfig *appconfig.Handler - AppRegistry *appregistry.Handler - AppUser *appuser.Handler - Audit *audit.Handler - Auth *authroutes.Handler - CoinLedger *coinledger.Handler - CountryRegion *countryregion.Handler - CPRelation *cprelation.Handler - CPWeeklyRank *cpweeklyrank.Handler - CumulativeRecharge *cumulativerechargereward.Handler - DailyTask *dailytask.Handler - Dashboard *dashboard.Handler - Databi *databi.Handler - FirstRechargeReward *firstrechargereward.Handler - FinanceApplication *financeapplication.Handler - FinanceOrder *financeorder.Handler - FinanceWithdrawal *financewithdrawal.Handler - FullServerNotice *fullservernotice.Handler - Game *gamemanagement.Handler - GiftDiamond *giftdiamond.Handler - Health *health.Handler - HostAgencyPolicy *hostagencypolicy.Handler - HostOrg *hostorg.Handler - HostSalarySettlement *hostsalarysettlement.Handler - HostWithdrawal *hostwithdrawal.Handler - InviteActivityReward *inviteactivityreward.Handler - Job *job.Handler - LevelConfig *levelconfig.Handler - Menu *menu.Handler - OpsCenter *opscenter.Handler - Payment *payment.Handler - PolicyConfig *policyconfig.Handler - PrettyID *prettyid.Handler - RBAC *rbac.Handler - RedPacket *redpacket.Handler - Report *reportmodule.Handler - RegistrationReward *registrationreward.Handler - RegionBlock *regionblock.Handler - Resource *resourcemodule.Handler - RiskConfig *riskconfig.Handler - RoomAdmin *roomadmin.Handler - RoomRocket *roomrocket.Handler - RoomTurnoverReward *roomturnoverreward.Handler - Search *search.Handler - SevenDayCheckIn *sevendaycheckin.Handler - Team *team.Handler - TeamSalaryPolicy *teamsalarypolicy.Handler - TeamSalarySettlement *teamsalarysettlement.Handler - Upload *upload.Handler - UserLeaderboard *userleaderboard.Handler - VIPConfig *vipconfig.Handler - WeeklyStar *weeklystar.Handler - Wheel *wheel.Handler + AdminUser *adminuser.Handler + AgencyOpening *agencyopening.Handler + AchievementConfig *achievementconfig.Handler + AppConfig *appconfig.Handler + AppRegistry *appregistry.Handler + AppUser *appuser.Handler + Audit *audit.Handler + Auth *authroutes.Handler + CoinLedger *coinledger.Handler + CountryRegion *countryregion.Handler + CPRelation *cprelation.Handler + CPWeeklyRank *cpweeklyrank.Handler + CumulativeRecharge *cumulativerechargereward.Handler + DailyTask *dailytask.Handler + Dashboard *dashboard.Handler + Databi *databi.Handler + FirstRechargeReward *firstrechargereward.Handler + FinanceApplication *financeapplication.Handler + FinanceOrder *financeorder.Handler + FinanceWithdrawal *financewithdrawal.Handler + FullServerNotice *fullservernotice.Handler + Game *gamemanagement.Handler + GiftDiamond *giftdiamond.Handler + Health *health.Handler + HostAgencyPolicy *hostagencypolicy.Handler + HostOrg *hostorg.Handler + HostSalarySettlement *hostsalarysettlement.Handler + HostWithdrawal *hostwithdrawal.Handler + InviteActivityReward *inviteactivityreward.Handler + Job *job.Handler + LevelConfig *levelconfig.Handler + Menu *menu.Handler + OpsCenter *opscenter.Handler + Payment *payment.Handler + PolicyConfig *policyconfig.Handler + PointWithdrawalConfig *pointwithdrawalconfig.Handler + PrettyID *prettyid.Handler + RBAC *rbac.Handler + RedPacket *redpacket.Handler + Report *reportmodule.Handler + RegistrationReward *registrationreward.Handler + RegionBlock *regionblock.Handler + Resource *resourcemodule.Handler + RiskConfig *riskconfig.Handler + RoomAdmin *roomadmin.Handler + RoomRocket *roomrocket.Handler + RoomTurnoverReward *roomturnoverreward.Handler + Search *search.Handler + SevenDayCheckIn *sevendaycheckin.Handler + Team *team.Handler + TeamSalaryPolicy *teamsalarypolicy.Handler + TeamSalarySettlement *teamsalarysettlement.Handler + Upload *upload.Handler + UserLeaderboard *userleaderboard.Handler + VIPConfig *vipconfig.Handler + WeeklyStar *weeklystar.Handler + Wheel *wheel.Handler } func New(cfg config.Config, auth *service.AuthService, h Handlers) *gin.Engine { @@ -176,6 +178,7 @@ func New(cfg config.Config, auth *service.AuthService, h Handlers) *gin.Engine { audit.RegisterRoutes(protected, h.Audit) payment.RegisterRoutes(protected, h.Payment) policyconfig.RegisterRoutes(protected, h.PolicyConfig) + pointwithdrawalconfig.RegisterRoutes(protected, h.PointWithdrawalConfig) prettyid.RegisterRoutes(protected, h.PrettyID) job.RegisterRoutes(protected, h.Job) levelconfig.RegisterRoutes(protected, h.LevelConfig) diff --git a/server/admin/migrations/088_fami_guild_revenue_policy.sql b/server/admin/migrations/088_fami_guild_revenue_policy.sql new file mode 100644 index 00000000..8937fe65 --- /dev/null +++ b/server/admin/migrations/088_fami_guild_revenue_policy.sql @@ -0,0 +1,66 @@ +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; + +SET @now_ms = CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED); + +-- 收益策略模板是 Lalu/Huwaa/Fami 共用的产品配置入口。存量模板显式补 0,避免旧实例重发时产生新分成。 +UPDATE admin_policy_templates +SET rule_json = JSON_SET(rule_json, '$.agency.point_ratio_percent', 0), + updated_at_ms = @now_ms +WHERE template_code = 'first_google70000_coin_seller_92000_100000_v1' + AND template_version = 'v1' + AND JSON_EXTRACT(rule_json, '$.agency.point_ratio_percent') IS NULL; + +UPDATE admin_policy_template_versions +SET rule_json = JSON_SET(rule_json, '$.agency.point_ratio_percent', 0), + updated_at_ms = @now_ms +WHERE template_code = 'first_google70000_coin_seller_92000_100000_v1' + AND template_version = 'v1' + AND JSON_EXTRACT(rule_json, '$.agency.point_ratio_percent') IS NULL; + +-- Fami 从同一份公共政策结构派生独立模板,默认 20%;运营可在 Admin 编辑并发布,不需要改代码。 +INSERT INTO admin_policy_templates ( + template_code, template_version, name, status, rule_json, description, + created_by_admin_id, updated_by_admin_id, created_at_ms, updated_at_ms +) +SELECT + 'fami_guild_revenue_policy', 'v1', 'Fami 公会收益政策', 'active', + JSON_SET(rule_json, '$.agency.point_ratio_percent', 20), + 'Fami 主播与 Agency POINT 收益政策;Agency 默认 20%,以发布后的运行快照为准。', + 0, 0, @now_ms, @now_ms +FROM admin_policy_templates +WHERE template_code = 'first_google70000_coin_seller_92000_100000_v1' AND template_version = 'v1' +ON DUPLICATE KEY UPDATE + name = VALUES(name), + status = VALUES(status), + description = VALUES(description), + updated_at_ms = @now_ms; + +INSERT INTO admin_policy_template_versions ( + template_code, template_version, status, rule_json, + created_by_admin_id, updated_by_admin_id, created_at_ms, updated_at_ms +) +SELECT + template_code, template_version, status, rule_json, + created_by_admin_id, updated_by_admin_id, created_at_ms, updated_at_ms +FROM admin_policy_templates +WHERE template_code = 'fami_guild_revenue_policy' AND template_version = 'v1' +ON DUPLICATE KEY UPDATE + status = VALUES(status), + rule_json = VALUES(rule_json), + updated_at_ms = @now_ms; + +INSERT INTO admin_policy_instances ( + app_code, instance_code, template_code, template_version, region_scope, status, + effective_from_ms, effective_to_ms, publish_status, created_by_admin_id, updated_by_admin_id, + created_at_ms, updated_at_ms +) VALUES ( + 'fami', 'fami_guild_revenue_policy', 'fami_guild_revenue_policy', 'v1', + 'all_active_regions', 'active', @now_ms, 0, 'draft', 0, 0, @now_ms, @now_ms +) +ON DUPLICATE KEY UPDATE + template_code = VALUES(template_code), + template_version = VALUES(template_version), + region_scope = VALUES(region_scope), + status = VALUES(status), + effective_to_ms = VALUES(effective_to_ms), + updated_at_ms = @now_ms; diff --git a/server/admin/migrations/089_point_withdrawal_coin_seller_config.sql b/server/admin/migrations/089_point_withdrawal_coin_seller_config.sql new file mode 100644 index 00000000..6148a72b --- /dev/null +++ b/server/admin/migrations/089_point_withdrawal_coin_seller_config.sql @@ -0,0 +1,33 @@ +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 币商提现白名单是按当前后台 App 范围编辑的公共能力;不在表中复制 Who/Sofun 等固定开关, +-- 新增 App 时复用 X-App-Code 作用域即可,避免每增加一套公会页面就增加一列。 +SET @now_ms = CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED); + +INSERT INTO admin_permissions (name, code, kind, description, created_at_ms, updated_at_ms) VALUES + ('币商提现白名单查看', 'point-withdrawal-config:view', 'menu', '查看当前 App 的 POINT 提现币商、服务国家和兑换比例', @now_ms, @now_ms), + ('币商提现白名单编辑', 'point-withdrawal-config:update', 'button', '新增、编辑、禁用或删除当前 App 的 POINT 提现币商配置', @now_ms, @now_ms) +ON DUPLICATE KEY UPDATE + name = VALUES(name), kind = VALUES(kind), description = VALUES(description), updated_at_ms = @now_ms; + +INSERT INTO admin_menus (parent_id, title, code, path, icon, permission_code, sort, visible, created_at_ms, updated_at_ms) +SELECT parent.id, '币商提现白名单', 'host-org-point-withdrawal-config', '/host/point-withdrawal-config', 'wallet', 'point-withdrawal-config:view', 89, TRUE, @now_ms, @now_ms +FROM admin_menus parent +WHERE parent.code = 'host-org' +ON DUPLICATE KEY UPDATE + parent_id = VALUES(parent_id), title = VALUES(title), path = VALUES(path), icon = VALUES(icon), + permission_code = VALUES(permission_code), sort = VALUES(sort), visible = VALUES(visible), updated_at_ms = @now_ms; + +INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) +SELECT role.id, permission.id +FROM admin_roles role +JOIN admin_permissions permission +WHERE role.code IN ('platform-admin', 'ops-admin') + AND permission.code IN ('point-withdrawal-config:view', 'point-withdrawal-config:update'); + +INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) +SELECT role.id, permission.id +FROM admin_roles role +JOIN admin_permissions permission +WHERE role.code IN ('auditor', 'readonly') + AND permission.code = 'point-withdrawal-config:view'; diff --git a/server/admin/migrations/090_point_withdrawal_policy_snapshot.sql b/server/admin/migrations/090_point_withdrawal_policy_snapshot.sql new file mode 100644 index 00000000..8ff3ad29 --- /dev/null +++ b/server/admin/migrations/090_point_withdrawal_policy_snapshot.sql @@ -0,0 +1,9 @@ +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- POINT 提现审核必须使用用户提交时的已发布政策快照;否则 Admin 后续修改汇率/手续费会让冻结、展示和审核扣款口径不一致。 +ALTER TABLE admin_user_withdrawal_applications + ADD COLUMN point_fee_amount BIGINT NOT NULL DEFAULT 0 COMMENT 'POINT 提现手续费积分快照' AFTER withdraw_amount_minor, + ADD COLUMN point_net_amount BIGINT NOT NULL DEFAULT 0 COMMENT 'POINT 提现预计到账积分快照' AFTER point_fee_amount, + ADD COLUMN points_per_usd BIGINT NOT NULL DEFAULT 100000 COMMENT 'POINT/USD 汇率快照' AFTER point_net_amount, + ADD COLUMN point_fee_bps INT NOT NULL DEFAULT 500 COMMENT 'POINT 提现手续费 bps 快照' AFTER points_per_usd, + ADD COLUMN point_policy_instance_code VARCHAR(96) NOT NULL DEFAULT '' COMMENT '已发布钱包政策实例快照' AFTER point_fee_bps; diff --git a/services/gateway-service/internal/client/user_client.go b/services/gateway-service/internal/client/user_client.go index 441a2833..8b470c9c 100644 --- a/services/gateway-service/internal/client/user_client.go +++ b/services/gateway-service/internal/client/user_client.go @@ -635,6 +635,14 @@ func (c *grpcUserHostClient) KickAgencyHost(ctx context.Context, req *userv1.Kic return c.client.KickAgencyHost(ctx, req) } +func (c *grpcUserHostClient) GetHostEngagementStats(ctx context.Context, req *userv1.GetHostEngagementStatsRequest) (*userv1.GetHostEngagementStatsResponse, error) { + return c.client.GetHostEngagementStats(ctx, req) +} + +func (c *grpcUserHostClient) RecordPrivateMessageEvent(ctx context.Context, req *userv1.RecordPrivateMessageEventRequest) (*userv1.RecordPrivateMessageEventResponse, error) { + return c.client.RecordPrivateMessageEvent(ctx, req) +} + func (c *grpcUserHostAdminClient) CreateBDLeader(ctx context.Context, req *userv1.CreateBDLeaderRequest) (*userv1.CreateBDLeaderResponse, error) { return c.client.CreateBDLeader(ctx, req) } diff --git a/services/gateway-service/internal/client/wallet_client.go b/services/gateway-service/internal/client/wallet_client.go index acbd735e..f9dfd256 100644 --- a/services/gateway-service/internal/client/wallet_client.go +++ b/services/gateway-service/internal/client/wallet_client.go @@ -99,6 +99,18 @@ func (c *grpcWalletClient) GetHostSalaryProgress(ctx context.Context, req *walle return c.client.GetHostSalaryProgress(ctx, req) } +func (c *grpcWalletClient) GetHostRevenueStats(ctx context.Context, req *walletv1.GetHostRevenueStatsRequest) (*walletv1.GetHostRevenueStatsResponse, error) { + return c.client.GetHostRevenueStats(ctx, req) +} + +func (c *grpcWalletClient) GetAgencyPointShareStats(ctx context.Context, req *walletv1.GetAgencyPointShareStatsRequest) (*walletv1.GetAgencyPointShareStatsResponse, error) { + return c.client.GetAgencyPointShareStats(ctx, req) +} + +func (c *grpcWalletClient) GetAgencyHostGiftStats(ctx context.Context, req *walletv1.GetAgencyHostGiftStatsRequest) (*walletv1.GetAgencyHostGiftStatsResponse, error) { + return c.client.GetAgencyHostGiftStats(ctx, req) +} + func (c *grpcWalletClient) GetTeamHostSalaryStats(ctx context.Context, req *walletv1.GetTeamHostSalaryStatsRequest) (*walletv1.GetTeamHostSalaryStatsResponse, error) { return c.client.GetTeamHostSalaryStats(ctx, req) } @@ -251,6 +263,18 @@ func (c *grpcWalletClient) TransferSalaryToCoinSeller(ctx context.Context, req * return c.client.TransferSalaryToCoinSeller(ctx, req) } +func (c *grpcWalletClient) ListPointWithdrawalCoinSellers(ctx context.Context, req *walletv1.ListPointWithdrawalCoinSellersRequest) (*walletv1.ListPointWithdrawalCoinSellersResponse, error) { + return c.client.ListPointWithdrawalCoinSellers(ctx, req) +} + +func (c *grpcWalletClient) TransferPointToCoinSeller(ctx context.Context, req *walletv1.TransferPointToCoinSellerRequest) (*walletv1.TransferPointToCoinSellerResponse, error) { + return c.client.TransferPointToCoinSeller(ctx, req) +} + +func (c *grpcWalletClient) GetPointWithdrawalConfig(ctx context.Context, req *walletv1.GetPointWithdrawalConfigRequest) (*walletv1.GetPointWithdrawalConfigResponse, error) { + return c.client.GetPointWithdrawalConfig(ctx, req) +} + func (c *grpcWalletClient) FreezeSalaryWithdrawal(ctx context.Context, req *walletv1.FreezeSalaryWithdrawalRequest) (*walletv1.FreezeSalaryWithdrawalResponse, error) { return c.client.FreezeSalaryWithdrawal(ctx, req) } diff --git a/services/gateway-service/internal/financewithdrawal/writer.go b/services/gateway-service/internal/financewithdrawal/writer.go index a4ff6dd5..be439750 100644 --- a/services/gateway-service/internal/financewithdrawal/writer.go +++ b/services/gateway-service/internal/financewithdrawal/writer.go @@ -25,6 +25,11 @@ type CreateApplicationCommand struct { SalaryAssetType string WithdrawAmount string WithdrawAmountMinor int64 + PointFeeAmount int64 + PointNetAmount int64 + PointsPerUSD int64 + PointFeeBPS int32 + PointPolicyInstance string WithdrawMethod string WithdrawAddress string FreezeCommandID string @@ -40,6 +45,11 @@ type Application struct { SalaryAssetType string WithdrawAmount string WithdrawAmountMinor int64 + PointFeeAmount int64 + PointNetAmount int64 + PointsPerUSD int64 + PointFeeBPS int32 + PointPolicyInstance string WithdrawMethod string WithdrawAddress string FreezeCommandID string @@ -106,14 +116,21 @@ func (w *MySQLWriter) CreateApplication(ctx context.Context, command CreateAppli result, err := w.db.ExecContext(ctx, ` INSERT INTO admin_user_withdrawal_applications - (app_code, user_id, salary_asset_type, withdraw_amount, withdraw_amount_minor, withdraw_method, withdraw_address, freeze_command_id, freeze_transaction_id, status, created_at_ms, updated_at_ms) + (app_code, user_id, salary_asset_type, withdraw_amount, withdraw_amount_minor, + point_fee_amount, point_net_amount, points_per_usd, point_fee_bps, point_policy_instance_code, + withdraw_method, withdraw_address, freeze_command_id, freeze_transaction_id, status, created_at_ms, updated_at_ms) VALUES - (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, command.AppCode, formatUserID(command.UserID), command.SalaryAssetType, command.WithdrawAmount, command.WithdrawAmountMinor, + command.PointFeeAmount, + command.PointNetAmount, + command.PointsPerUSD, + command.PointFeeBPS, + command.PointPolicyInstance, command.WithdrawMethod, command.WithdrawAddress, command.FreezeCommandID, @@ -144,6 +161,11 @@ VALUES SalaryAssetType: command.SalaryAssetType, WithdrawAmount: command.WithdrawAmount, WithdrawAmountMinor: command.WithdrawAmountMinor, + PointFeeAmount: command.PointFeeAmount, + PointNetAmount: command.PointNetAmount, + PointsPerUSD: command.PointsPerUSD, + PointFeeBPS: command.PointFeeBPS, + PointPolicyInstance: command.PointPolicyInstance, WithdrawMethod: command.WithdrawMethod, WithdrawAddress: command.WithdrawAddress, FreezeCommandID: command.FreezeCommandID, @@ -157,6 +179,7 @@ VALUES func (w *MySQLWriter) getApplicationByFreezeCommand(ctx context.Context, appCode string, freezeCommandID string) (Application, bool, error) { row := w.db.QueryRowContext(ctx, ` SELECT id, app_code, user_id, salary_asset_type, withdraw_amount, withdraw_amount_minor, + point_fee_amount, point_net_amount, points_per_usd, point_fee_bps, point_policy_instance_code, withdraw_method, withdraw_address, freeze_command_id, freeze_transaction_id, status, created_at_ms, updated_at_ms FROM admin_user_withdrawal_applications @@ -171,6 +194,11 @@ LIMIT 1`, appCode, freezeCommandID) &item.SalaryAssetType, &item.WithdrawAmount, &item.WithdrawAmountMinor, + &item.PointFeeAmount, + &item.PointNetAmount, + &item.PointsPerUSD, + &item.PointFeeBPS, + &item.PointPolicyInstance, &item.WithdrawMethod, &item.WithdrawAddress, &item.FreezeCommandID, @@ -205,6 +233,7 @@ func normalizeCreateApplicationCommand(command CreateApplicationCommand) CreateA command.WithdrawAddress = strings.TrimSpace(command.WithdrawAddress) command.FreezeCommandID = strings.TrimSpace(command.FreezeCommandID) command.FreezeTransactionID = strings.TrimSpace(command.FreezeTransactionID) + command.PointPolicyInstance = strings.TrimSpace(command.PointPolicyInstance) if command.WithdrawMethod == "" { command.WithdrawMethod = MethodUSDTTRC20 } @@ -234,6 +263,12 @@ func validateCreateApplicationCommand(command CreateApplicationCommand) error { case command.CreatedAtMS <= 0: return errors.New("created_at_ms is required") default: + if command.SalaryAssetType == "POINT" || command.SalaryAssetType == "COIN_SELLER_POINT" { + // POINT 的政策快照会被财务审核原样复用;写入前先验证内部一致性,避免冻结成功但审核无法结算。 + if command.PointsPerUSD <= 0 || command.PointFeeBPS < 0 || command.PointFeeBPS > 10000 || command.PointFeeAmount < 0 || command.PointNetAmount < 0 || command.PointFeeAmount+command.PointNetAmount != command.WithdrawAmountMinor || command.PointFeeAmount != command.WithdrawAmountMinor*int64(command.PointFeeBPS)/10000 { + return errors.New("point withdrawal policy snapshot is invalid") + } + } return nil } } diff --git a/services/gateway-service/internal/financewithdrawal/writer_test.go b/services/gateway-service/internal/financewithdrawal/writer_test.go index 84a7c103..eaf05ce7 100644 --- a/services/gateway-service/internal/financewithdrawal/writer_test.go +++ b/services/gateway-service/internal/financewithdrawal/writer_test.go @@ -39,6 +39,11 @@ func TestCreateApplicationReturnsExistingByAppAndFreezeCommand(t *testing.T) { "POINT", "9.50", int64(1000000), + int64(50000), + int64(950000), + int64(100000), + int32(500), + "huwaa-policy-v1", MethodUSDTTRC20, "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF", "cmd-point-freeze", @@ -54,6 +59,11 @@ func TestCreateApplicationReturnsExistingByAppAndFreezeCommand(t *testing.T) { SalaryAssetType: "POINT", WithdrawAmount: "9.50", WithdrawAmountMinor: 1_000_000, + PointFeeAmount: 50_000, + PointNetAmount: 950_000, + PointsPerUSD: 100_000, + PointFeeBPS: 500, + PointPolicyInstance: "huwaa-policy-v1", WithdrawMethod: MethodUSDTTRC20, WithdrawAddress: "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF", FreezeCommandID: "cmd-point-freeze", @@ -86,6 +96,11 @@ func TestCreateApplicationInsertsAfterAppScopedMiss(t *testing.T) { "POINT", "9.50", int64(1000000), + int64(50000), + int64(950000), + int64(100000), + int32(500), + "huwaa-policy-v1", MethodUSDTTRC20, "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF", "cmd-point-freeze", @@ -102,6 +117,11 @@ func TestCreateApplicationInsertsAfterAppScopedMiss(t *testing.T) { SalaryAssetType: "point", WithdrawAmount: "9.50", WithdrawAmountMinor: 1_000_000, + PointFeeAmount: 50_000, + PointNetAmount: 950_000, + PointsPerUSD: 100_000, + PointFeeBPS: 500, + PointPolicyInstance: "huwaa-policy-v1", WithdrawAddress: "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF", FreezeCommandID: "cmd-point-freeze", FreezeTransactionID: "tx-freeze", @@ -126,6 +146,11 @@ func withdrawalApplicationRows() *sqlmock.Rows { "salary_asset_type", "withdraw_amount", "withdraw_amount_minor", + "point_fee_amount", + "point_net_amount", + "points_per_usd", + "point_fee_bps", + "point_policy_instance_code", "withdraw_method", "withdraw_address", "freeze_command_id", diff --git a/services/gateway-service/internal/transport/http/callbackapi/handler.go b/services/gateway-service/internal/transport/http/callbackapi/handler.go index 0f7ec3f6..b61cfa2e 100644 --- a/services/gateway-service/internal/transport/http/callbackapi/handler.go +++ b/services/gateway-service/internal/transport/http/callbackapi/handler.go @@ -28,6 +28,7 @@ type Handler struct { roomClient client.RoomClient roomGuardClient client.RoomGuardClient userProfileClient client.UserProfileClient + userHostClient client.UserHostClient tencentIM TencentIMConfig tencentRTC TencentRTCConfig } @@ -36,6 +37,7 @@ type Config struct { RoomClient client.RoomClient RoomGuardClient client.RoomGuardClient UserProfileClient client.UserProfileClient + UserHostClient client.UserHostClient TencentIM TencentIMConfig TencentRTC TencentRTCConfig } @@ -45,6 +47,7 @@ func New(config Config) *Handler { roomClient: config.RoomClient, roomGuardClient: config.RoomGuardClient, userProfileClient: config.UserProfileClient, + userHostClient: config.UserHostClient, tencentIM: config.TencentIM, tencentRTC: config.TencentRTC, } diff --git a/services/gateway-service/internal/transport/http/callbackapi/tencent_im_callback.go b/services/gateway-service/internal/transport/http/callbackapi/tencent_im_callback.go index c7ac09bd..0f30fd9f 100644 --- a/services/gateway-service/internal/transport/http/callbackapi/tencent_im_callback.go +++ b/services/gateway-service/internal/transport/http/callbackapi/tencent_im_callback.go @@ -1,9 +1,12 @@ package callbackapi import ( + "context" "encoding/json" + "fmt" "hyapp/services/gateway-service/internal/transport/http/httpkit" "io" + "log/slog" "net/http" "strconv" "strings" @@ -18,6 +21,7 @@ import ( const ( tencentCallbackJoinGroup = "Group.CallbackBeforeApplyJoinGroup" tencentCallbackSendMsg = "Group.CallbackBeforeSendMsg" + tencentCallbackC2CSent = "C2C.CallbackAfterSendMsg" ) // tencentIMCallbackBody 覆盖本阶段需要处理的腾讯云 IM 群回调字段。 @@ -28,6 +32,11 @@ type tencentIMCallbackBody struct { Requestor string `json:"Requestor_Account"` FromAccount string `json:"From_Account"` OperatorAccount string `json:"Operator_Account"` + ToAccount string `json:"To_Account"` + MsgKey string `json:"MsgKey"` + MsgSeq int64 `json:"MsgSeq"` + MsgRandom int64 `json:"MsgRandom"` + MsgTime int64 `json:"MsgTime"` } // tencentIMCallbackResponse 是腾讯云 IM 回调要求的原生响应结构。 @@ -86,11 +95,60 @@ func (h *Handler) handleTencentIMCallback(writer http.ResponseWriter, request *h h.handleTencentIMJoinCallback(writer, request, body) case tencentCallbackSendMsg: h.handleTencentIMSendCallback(writer, request, body) + case tencentCallbackC2CSent: + h.handleTencentIMC2CSentCallback(writer, request, body) default: writeTencentCallback(writer, http.StatusOK, 0, "") } } +func (h *Handler) handleTencentIMC2CSentCallback(writer http.ResponseWriter, request *http.Request, body tencentIMCallbackBody) { + // 服务端系统通知不属于主播“收到私信的人数”,否则批量余额/VIP 通知会污染运营指标。 + if h.tencentIMCallbackSenderIsServer(body) { + writeTencentCallback(writer, http.StatusOK, 0, "") + return + } + senderUserID, senderOK := parseTencentIMUserID(body.FromAccount) + targetUserID, targetOK := parseTencentIMUserID(body.ToAccount) + callbackAppCode := appcode.Normalize(request.URL.Query().Get("app_code")) + if callbackAppCode == "" { + callbackAppCode = appcode.FromContext(request.Context()) + } + recorder, recorderOK := h.userHostClient.(interface { + RecordPrivateMessageEvent(context.Context, *userv1.RecordPrivateMessageEventRequest) (*userv1.RecordPrivateMessageEventResponse, error) + }) + if !senderOK || !targetOK || senderUserID == targetUserID || !recorderOK { + // 统计旁路不能阻断用户已经发送成功的私信;缺配置只记告警,腾讯仍收到成功响应。 + slog.Warn("tencent_im_private_message_stats_skipped", "app_code", callbackAppCode, "from", body.FromAccount, "to", body.ToAccount) + writeTencentCallback(writer, http.StatusOK, 0, "") + return + } + occurredAtMS := body.MsgTime * 1000 + if occurredAtMS <= 0 { + occurredAtMS = time.Now().UTC().UnixMilli() + } + eventID := strings.TrimSpace(body.MsgKey) + if eventID == "" { + eventID = fmt.Sprintf("c2c:%d:%d:%d:%d:%d", senderUserID, targetUserID, body.MsgSeq, body.MsgRandom, occurredAtMS) + } + _, err := recorder.RecordPrivateMessageEvent(appcode.WithContext(request.Context(), callbackAppCode), &userv1.RecordPrivateMessageEventRequest{ + Meta: &userv1.RequestMeta{ + RequestId: httpkit.RequestIDFromContext(request.Context()), + Caller: "gateway-service", + SentAtMs: time.Now().UTC().UnixMilli(), + AppCode: callbackAppCode, + }, + EventId: eventID, + SenderUserId: senderUserID, + TargetUserId: targetUserID, + OccurredAtMs: occurredAtMS, + }) + if err != nil { + slog.Warn("tencent_im_private_message_stats_failed", "app_code", callbackAppCode, "event_id", eventID, "error", err) + } + writeTencentCallback(writer, http.StatusOK, 0, "") +} + func (h *Handler) handleTencentIMJoinCallback(writer http.ResponseWriter, request *http.Request, body tencentIMCallbackBody) { parsed := imgroup.ParseWithPrefix(body.GroupID, h.tencentIM.GroupIDPrefix) userID, ok := parseTencentIMUserID(body.Requestor) @@ -294,7 +352,7 @@ func resolveTencentIMCallbackCommand(queryCommand string, bodyCommand string) (s } func knownTencentIMCallback(command string) bool { - return command == tencentCallbackJoinGroup || command == tencentCallbackSendMsg + return command == tencentCallbackJoinGroup || command == tencentCallbackSendMsg || command == tencentCallbackC2CSent } func parseTencentIMUserID(value string) (int64, bool) { diff --git a/services/gateway-service/internal/transport/http/httproutes/router.go b/services/gateway-service/internal/transport/http/httproutes/router.go index 31f10ab2..8f3acdb8 100644 --- a/services/gateway-service/internal/transport/http/httproutes/router.go +++ b/services/gateway-service/internal/transport/http/httproutes/router.go @@ -90,8 +90,10 @@ type UserHandlers struct { ListAgencyRooms http.HandlerFunc UpdateAgencyProfile http.HandlerFunc GetHostCenterAgency http.HandlerFunc + GetHostCenterStats http.HandlerFunc GetHostCenterPlatformPolicy http.HandlerFunc GetAgencyCenterOverview http.HandlerFunc + GetAgencyCenterStats http.HandlerFunc GetAgencyCenterPlatformPolicy http.HandlerFunc ListAgencyCenterHosts http.HandlerFunc ListAgencyCenterApplications http.HandlerFunc @@ -104,6 +106,7 @@ type UserHandlers struct { InviteBDLeaderBD http.HandlerFunc InviteBDLeaderAgency http.HandlerFunc GetBDCenterOverview http.HandlerFunc + GetBDCenterStats http.HandlerFunc ListBDCenterAgencies http.HandlerFunc InviteBDAgency http.HandlerFunc ListMyRoleInvitations http.HandlerFunc @@ -287,6 +290,7 @@ type WalletHandlers struct { WithdrawSalaryWallet http.HandlerFunc GetPointWalletOverview http.HandlerFunc WithdrawPointWallet http.HandlerFunc + TransferPointWalletToCoinSeller http.HandlerFunc GetRedPacketConfig http.HandlerFunc ListRoomRedPackets http.HandlerFunc CreateRoomRedPacket http.HandlerFunc @@ -470,8 +474,10 @@ func (r routes) registerUserRoutes() { r.profile("/agencies/rooms", http.MethodGet, h.ListAgencyRooms) r.profile("/agencies/profile/update", http.MethodPost, h.UpdateAgencyProfile) r.profile("/host-center/agency", http.MethodGet, h.GetHostCenterAgency) + r.profile("/host-center/stats", http.MethodGet, h.GetHostCenterStats) r.profile("/host-center/platform-policy", http.MethodGet, h.GetHostCenterPlatformPolicy) r.profile("/agency-center/overview", http.MethodGet, h.GetAgencyCenterOverview) + r.profile("/agency-center/stats", http.MethodGet, h.GetAgencyCenterStats) r.profile("/agency-center/platform-policy", http.MethodGet, h.GetAgencyCenterPlatformPolicy) r.profile("/agency-center/hosts", http.MethodGet, h.ListAgencyCenterHosts) r.profile("/agency-center/applications", http.MethodGet, h.ListAgencyCenterApplications) @@ -484,6 +490,7 @@ func (r routes) registerUserRoutes() { r.profile("/bd-leader/invitations/bd", http.MethodPost, h.InviteBDLeaderBD) r.profile("/bd-leader/invitations/agency", http.MethodPost, h.InviteBDLeaderAgency) r.profile("/bd-center/overview", http.MethodGet, h.GetBDCenterOverview) + r.profile("/bd-center/stats", http.MethodGet, h.GetBDCenterStats) r.profile("/bd-center/agencies", http.MethodGet, h.ListBDCenterAgencies) r.profile("/bd/invitations/agency", http.MethodPost, h.InviteBDAgency) r.profile("/role-invitations", http.MethodGet, h.ListMyRoleInvitations) @@ -690,6 +697,7 @@ func (r routes) registerWalletRoutes() { r.profile("/salary-wallet/withdraw", http.MethodPost, h.WithdrawSalaryWallet) r.profile("/point-wallet/overview", http.MethodGet, h.GetPointWalletOverview) r.profile("/point-wallet/withdraw", http.MethodPost, h.WithdrawPointWallet) + r.profile("/point-wallet/transfer-to-coin-seller", http.MethodPost, h.TransferPointWalletToCoinSeller) r.profile("/red-packets/config", http.MethodGet, h.GetRedPacketConfig) r.profile("/rooms/{room_id}/red-packets", http.MethodGet, h.ListRoomRedPackets) r.profile("/rooms/{room_id}/red-packets/create", http.MethodPost, h.CreateRoomRedPacket) diff --git a/services/gateway-service/internal/transport/http/router.go b/services/gateway-service/internal/transport/http/router.go index d80eef16..5fa38d70 100644 --- a/services/gateway-service/internal/transport/http/router.go +++ b/services/gateway-service/internal/transport/http/router.go @@ -134,6 +134,7 @@ func (h *Handler) Routes(jwtVerifier *auth.Verifier) http.Handler { RoomClient: h.roomClient, RoomGuardClient: h.roomGuardClient, UserProfileClient: h.userProfileClient, + UserHostClient: h.userHostClient, TencentIM: callbackapi.TencentIMConfig{ SDKAppID: h.tencentIM.SDKAppID, AdminIdentifier: h.tencentIM.AdminIdentifier, diff --git a/services/gateway-service/internal/transport/http/userapi/agency_center_handler.go b/services/gateway-service/internal/transport/http/userapi/agency_center_handler.go index 06828e32..86cecdcb 100644 --- a/services/gateway-service/internal/transport/http/userapi/agency_center_handler.go +++ b/services/gateway-service/internal/transport/http/userapi/agency_center_handler.go @@ -33,6 +33,7 @@ type agencyCenterUserData struct { DisplayUserID string `json:"display_user_id"` Username string `json:"username"` Avatar string `json:"avatar,omitempty"` + Country string `json:"country,omitempty"` } type agencyCenterHostData struct { @@ -465,6 +466,7 @@ func agencyCenterUserFromProto(user *userv1.User) agencyCenterUserData { DisplayUserID: user.GetDisplayUserId(), Username: user.GetUsername(), Avatar: user.GetAvatar(), + Country: firstBDLeaderNonBlank(user.GetCountryDisplayName(), user.GetCountryName(), user.GetCountry()), } } diff --git a/services/gateway-service/internal/transport/http/userapi/agency_center_stats_handler.go b/services/gateway-service/internal/transport/http/userapi/agency_center_stats_handler.go new file mode 100644 index 00000000..a290c590 --- /dev/null +++ b/services/gateway-service/internal/transport/http/userapi/agency_center_stats_handler.go @@ -0,0 +1,165 @@ +package userapi + +import ( + "context" + "net/http" + "sync" + + userv1 "hyapp.local/api/proto/user/v1" + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/services/gateway-service/internal/transport/http/httpkit" +) + +type agencyRevenueStatsClient interface { + GetHostRevenueStats(context.Context, *walletv1.GetHostRevenueStatsRequest) (*walletv1.GetHostRevenueStatsResponse, error) + GetAgencyPointShareStats(context.Context, *walletv1.GetAgencyPointShareStatsRequest) (*walletv1.GetAgencyPointShareStatsResponse, error) + GetAgencyHostGiftStats(context.Context, *walletv1.GetAgencyHostGiftStatsRequest) (*walletv1.GetAgencyHostGiftStatsResponse, error) +} + +type agencyCenterStatsSummaryData struct { + TotalEarnings int64 `json:"total_earnings"` + GiftIncome int64 `json:"gift_income"` + ShareIncome int64 `json:"share_income"` + TotalHosts int `json:"total_hosts"` + GiftedHostCount int64 `json:"gifted_host_count"` +} + +type agencyCenterHostStatsData struct { + MembershipID string `json:"membership_id"` + HostUserID string `json:"host_user_id"` + DisplayUserID string `json:"display_user_id"` + Username string `json:"username"` + Avatar string `json:"avatar,omitempty"` + JoinedAtMS int64 `json:"joined_at_ms"` + DiamondEarnings int64 `json:"diamond_earnings"` + DiamondExchanged int64 `json:"diamond_exchanged"` + GiftSenders int64 `json:"gift_senders"` + OnlineDurationMS int64 `json:"online_duration_ms"` + ValidMicDurationMS int64 `json:"valid_mic_duration_ms"` + ValidMicDays int64 `json:"valid_mic_days"` + Removable bool `json:"removable"` +} + +// getAgencyCenterStats 只做跨 owner 编排:成员关系/互动来自 user-service,金额和分成来自 wallet-service。 +// 每个主播的两次 RPC 使用有界并发,避免大公会串行超时,也避免无上限 goroutine 压垮下游。 +func (h *Handler) getAgencyCenterStats(writer http.ResponseWriter, request *http.Request) { + agency, ok := h.resolveCurrentOwnerAgency(writer, request) + if !ok { + return + } + revenueClient, revenueOK := h.walletClient.(agencyRevenueStatsClient) + engagementClient, engagementOK := h.userHostClient.(hostEngagementStatsClient) + if !revenueOK || !engagementOK { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + startDate, endDate, startAtMS, endAtMS, ok := parseHostCenterStatsRange(request) + if !ok { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid date range") + return + } + + membersResp, err := h.userHostClient.GetAgencyMembers(request.Context(), &userv1.GetAgencyMembersRequest{ + Meta: httpkit.UserMeta(request, ""), AgencyId: agency.GetAgencyId(), Status: membershipStatusActive, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + memberships := make([]*userv1.AgencyMembership, 0, len(membersResp.GetMemberships())) + userIDs := make([]int64, 0, len(membersResp.GetMemberships())) + for _, membership := range membersResp.GetMemberships() { + memberships = append(memberships, membership) + userIDs = append(userIDs, membership.GetHostUserId()) + } + profiles, err := h.userProfiles(request, userIDs) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + requestID := httpkit.RequestIDFromContext(request.Context()) + appCode := appcode.FromContext(request.Context()) + shareResp, err := revenueClient.GetAgencyPointShareStats(request.Context(), &walletv1.GetAgencyPointShareStatsRequest{ + RequestId: requestID, AppCode: appCode, AgencyOwnerUserId: agency.GetOwnerUserId(), StartAtMs: startAtMS, EndAtMs: endAtMS, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + giftResp, err := revenueClient.GetAgencyHostGiftStats(request.Context(), &walletv1.GetAgencyHostGiftStatsRequest{ + RequestId: requestID, AppCode: appCode, HostUserIds: userIDs, StartAtMs: startAtMS, EndAtMs: endAtMS, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + + items := make([]agencyCenterHostStatsData, len(memberships)) + ctx, cancel := context.WithCancel(request.Context()) + defer cancel() + semaphore := make(chan struct{}, 8) + var wait sync.WaitGroup + var firstErr error + var errorMu sync.Mutex + for index, membership := range memberships { + index, membership := index, membership + wait.Add(1) + go func() { + defer wait.Done() + semaphore <- struct{}{} + defer func() { <-semaphore }() + revenue, callErr := revenueClient.GetHostRevenueStats(ctx, &walletv1.GetHostRevenueStatsRequest{ + RequestId: requestID, AppCode: appCode, HostUserId: membership.GetHostUserId(), StartAtMs: startAtMS, EndAtMs: endAtMS, + }) + if callErr == nil { + var engagement *userv1.GetHostEngagementStatsResponse + engagement, callErr = engagementClient.GetHostEngagementStats(ctx, &userv1.GetHostEngagementStatsRequest{ + Meta: httpkit.UserMeta(request, ""), HostUserId: membership.GetHostUserId(), StartAtMs: startAtMS, EndAtMs: endAtMS, + }) + if callErr == nil { + profile := profiles[membership.GetHostUserId()] + items[index] = agencyCenterHostStatsData{ + MembershipID: int64String(membership.GetMembershipId()), HostUserID: int64String(membership.GetHostUserId()), + DisplayUserID: profile.DisplayUserID, Username: profile.Username, Avatar: profile.Avatar, JoinedAtMS: membership.GetJoinedAtMs(), + DiamondEarnings: revenue.GetStats().GetDiamondEarnings(), DiamondExchanged: revenue.GetStats().GetDiamondExchanged(), GiftSenders: revenue.GetStats().GetGiftSenders(), + OnlineDurationMS: engagement.GetStats().GetOnlineDurationMs(), ValidMicDurationMS: engagement.GetStats().GetValidMicDurationMs(), ValidMicDays: engagement.GetStats().GetValidMicDays(), + Removable: membership.GetHostUserId() != agency.GetOwnerUserId() && membership.GetMembershipType() != membershipTypeOwner, + } + } + } + if callErr != nil { + errorMu.Lock() + if firstErr == nil { + firstErr = callErr + cancel() + } + errorMu.Unlock() + } + }() + } + wait.Wait() + if firstErr != nil { + httpkit.WriteRPCError(writer, request, firstErr) + return + } + shareIncome := shareResp.GetStats().GetShareIncome() + // 公会长同时是主播时,其 POINT 流水包含 Agency 分成;主播行只展示个人收益,必须扣除同区间分成。 + for index := range items { + if items[index].HostUserID == int64String(agency.GetOwnerUserId()) { + items[index].DiamondEarnings -= shareIncome + if items[index].DiamondEarnings < 0 { + items[index].DiamondEarnings = 0 + } + } + } + giftIncome := giftResp.GetStats().GetGiftIncome() + httpkit.WriteOK(writer, request, map[string]any{ + "range": hostCenterStatsRangeData{StartDate: startDate, EndDate: endDate, Timezone: "UTC"}, + "summary": agencyCenterStatsSummaryData{ + TotalEarnings: giftIncome + shareIncome, GiftIncome: giftIncome, ShareIncome: shareIncome, + TotalHosts: len(items), GiftedHostCount: giftResp.GetStats().GetGiftedHostCount(), + }, + "hosts": items, + }) +} diff --git a/services/gateway-service/internal/transport/http/userapi/bd_center_stats_handler.go b/services/gateway-service/internal/transport/http/userapi/bd_center_stats_handler.go new file mode 100644 index 00000000..2613f3df --- /dev/null +++ b/services/gateway-service/internal/transport/http/userapi/bd_center_stats_handler.go @@ -0,0 +1,117 @@ +package userapi + +import ( + "context" + "net/http" + "sync" + + userv1 "hyapp.local/api/proto/user/v1" + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/services/gateway-service/internal/auth" + "hyapp/services/gateway-service/internal/transport/http/httpkit" +) + +type agencyHostGiftStatsClient interface { + GetAgencyHostGiftStats(context.Context, *walletv1.GetAgencyHostGiftStatsRequest) (*walletv1.GetAgencyHostGiftStatsResponse, error) +} + +type bdCenterAgencyStatsData struct { + Agency hostAgencyData `json:"agency"` + Owner agencyCenterUserData `json:"owner"` + Country string `json:"country"` + TotalHosts int `json:"total_hosts"` + GiftedHostCount int64 `json:"gifted_host_count"` + DiamondEarnings int64 `json:"diamond_earnings"` + JoinedAtMS int64 `json:"joined_at_ms"` +} + +// getBDCenterStats 返回 BD 直属 Agency 的收礼统计;工资和 Agency 分成不属于设计稿口径,刻意不返回。 +func (h *Handler) getBDCenterStats(writer http.ResponseWriter, request *http.Request) { + userID := auth.UserIDFromContext(request.Context()) + if _, ok := h.resolveActiveBD(writer, request, userID); !ok { + return + } + statsClient, ok := h.walletClient.(agencyHostGiftStatsClient) + if !ok { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + startDate, endDate, startAtMS, endAtMS, ok := parseHostCenterStatsRange(request) + if !ok { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid date range") + return + } + agenciesResp, err := h.userHostClient.ListBDAgencies(request.Context(), &userv1.ListBDAgenciesRequest{ + Meta: httpkit.UserMeta(request, ""), BdUserId: userID, Status: agencyStatusActive, PageSize: 100, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + ownerIDs := make([]int64, 0, len(agenciesResp.GetAgencies())) + for _, agency := range agenciesResp.GetAgencies() { + ownerIDs = append(ownerIDs, agency.GetOwnerUserId()) + } + owners, err := h.userProfiles(request, ownerIDs) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + + items := make([]bdCenterAgencyStatsData, len(agenciesResp.GetAgencies())) + ctx, cancel := context.WithCancel(request.Context()) + defer cancel() + semaphore := make(chan struct{}, 8) + var wait sync.WaitGroup + var firstErr error + var errorMu sync.Mutex + for index, agency := range agenciesResp.GetAgencies() { + index, agency := index, agency + wait.Add(1) + go func() { + defer wait.Done() + semaphore <- struct{}{} + defer func() { <-semaphore }() + members, callErr := h.userHostClient.GetAgencyMembers(ctx, &userv1.GetAgencyMembersRequest{ + Meta: httpkit.UserMeta(request, ""), AgencyId: agency.GetAgencyId(), Status: membershipStatusActive, + }) + hostIDs := make([]int64, 0, len(members.GetMemberships())) + if callErr == nil { + for _, membership := range members.GetMemberships() { + hostIDs = append(hostIDs, membership.GetHostUserId()) + } + var stats *walletv1.GetAgencyHostGiftStatsResponse + stats, callErr = statsClient.GetAgencyHostGiftStats(ctx, &walletv1.GetAgencyHostGiftStatsRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()), + HostUserIds: hostIDs, StartAtMs: startAtMS, EndAtMs: endAtMS, + }) + if callErr == nil { + owner := owners[agency.GetOwnerUserId()] + items[index] = bdCenterAgencyStatsData{ + Agency: hostAgencyFromProto(agency), Owner: owner, Country: owner.Country, + TotalHosts: len(hostIDs), GiftedHostCount: stats.GetStats().GetGiftedHostCount(), + DiamondEarnings: stats.GetStats().GetGiftIncome(), JoinedAtMS: agency.GetCreatedAtMs(), + } + } + } + if callErr != nil { + errorMu.Lock() + if firstErr == nil { + firstErr = callErr + cancel() + } + errorMu.Unlock() + } + }() + } + wait.Wait() + if firstErr != nil { + httpkit.WriteRPCError(writer, request, firstErr) + return + } + httpkit.WriteOK(writer, request, map[string]any{ + "range": hostCenterStatsRangeData{StartDate: startDate, EndDate: endDate, Timezone: "UTC"}, + "items": items, "total": len(items), + }) +} diff --git a/services/gateway-service/internal/transport/http/userapi/handler.go b/services/gateway-service/internal/transport/http/userapi/handler.go index 4007f6b4..a12f296e 100644 --- a/services/gateway-service/internal/transport/http/userapi/handler.go +++ b/services/gateway-service/internal/transport/http/userapi/handler.go @@ -73,8 +73,10 @@ func (h *Handler) UserHandlers() httproutes.UserHandlers { ListAgencyRooms: h.listAgencyRooms, UpdateAgencyProfile: h.updateAgencyProfile, GetHostCenterAgency: h.getHostCenterAgency, + GetHostCenterStats: h.getHostCenterStats, GetHostCenterPlatformPolicy: h.getHostCenterPlatformPolicy, GetAgencyCenterOverview: h.getAgencyCenterOverview, + GetAgencyCenterStats: h.getAgencyCenterStats, GetAgencyCenterPlatformPolicy: h.getAgencyCenterPlatformPolicy, ListAgencyCenterHosts: h.listAgencyCenterHosts, ListAgencyCenterApplications: h.listAgencyCenterApplications, @@ -87,6 +89,7 @@ func (h *Handler) UserHandlers() httproutes.UserHandlers { InviteBDLeaderBD: h.inviteBDLeaderBD, InviteBDLeaderAgency: h.inviteBDLeaderAgency, GetBDCenterOverview: h.getBDCenterOverview, + GetBDCenterStats: h.getBDCenterStats, ListBDCenterAgencies: h.listBDCenterAgencies, InviteBDAgency: h.inviteBDAgency, ListMyRoleInvitations: h.listMyRoleInvitations, diff --git a/services/gateway-service/internal/transport/http/userapi/host_center_agency_handler.go b/services/gateway-service/internal/transport/http/userapi/host_center_agency_handler.go index 004f53f4..7aeb1fc8 100644 --- a/services/gateway-service/internal/transport/http/userapi/host_center_agency_handler.go +++ b/services/gateway-service/internal/transport/http/userapi/host_center_agency_handler.go @@ -8,10 +8,11 @@ import ( ) type hostCenterAgencyData struct { - AgencyID string `json:"agency_id"` - ShortID string `json:"short_id"` - Name string `json:"name"` - Avatar string `json:"avatar,omitempty"` + AgencyID string `json:"agency_id"` + ShortID string `json:"short_id"` + Name string `json:"name"` + Avatar string `json:"avatar,omitempty"` + JoinedAtMS int64 `json:"joined_at_ms,omitempty"` } func (h *Handler) getHostCenterAgency(writer http.ResponseWriter, request *http.Request) { @@ -49,6 +50,21 @@ func (h *Handler) getHostCenterAgency(writer http.ResponseWriter, request *http. Name: agency.GetName(), Avatar: agency.GetAvatar(), } + // 加入时间来自当前 membership 事实,不使用 host 首次成为主播时间;主播换公会后两者语义不同。 + membersResp, err := h.userHostClient.GetAgencyMembers(request.Context(), &userv1.GetAgencyMembersRequest{ + Meta: httpkit.UserMeta(request, ""), + AgencyId: agency.GetAgencyId(), + Status: "active", + }) + if err == nil { + // 加入时间是新增展示字段;该补充查询失败时保留旧响应,不能让 Lalu 历史页面因非关键字段不可用而整体失败。 + for _, membership := range membersResp.GetMemberships() { + if membership.GetMembershipId() == profile.GetCurrentMembershipId() && membership.GetHostUserId() == profile.GetUserId() { + data.JoinedAtMS = membership.GetJoinedAtMs() + break + } + } + } if agency.GetOwnerUserId() > 0 { profiles, err := h.userProfiles(request, []int64{agency.GetOwnerUserId()}) if err != nil { diff --git a/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler.go b/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler.go new file mode 100644 index 00000000..228ecde2 --- /dev/null +++ b/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler.go @@ -0,0 +1,114 @@ +package userapi + +import ( + "context" + "net/http" + "strings" + "time" + + userv1 "hyapp.local/api/proto/user/v1" + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/services/gateway-service/internal/transport/http/httpkit" +) + +type hostEngagementStatsClient interface { + GetHostEngagementStats(context.Context, *userv1.GetHostEngagementStatsRequest) (*userv1.GetHostEngagementStatsResponse, error) +} + +type hostRevenueStatsClient interface { + GetHostRevenueStats(context.Context, *walletv1.GetHostRevenueStatsRequest) (*walletv1.GetHostRevenueStatsResponse, error) +} + +const hostCenterMaxStatsDays = 366 + +type hostCenterStatsRangeData struct { + StartDate string `json:"start_date"` + EndDate string `json:"end_date"` + Timezone string `json:"timezone"` +} + +type hostCenterStatsMetricsData struct { + DiamondEarnings int64 `json:"diamond_earnings"` + DiamondExchanged int64 `json:"diamond_exchanged"` + GiftSenders int64 `json:"gift_senders"` + OnlineDurationMS int64 `json:"online_duration_ms"` + ValidMicDurationMS int64 `json:"valid_mic_duration_ms"` + ValidMicDays int64 `json:"valid_mic_days"` + PrivateMessageSenders int64 `json:"private_message_senders"` + NewFollowers int64 `json:"new_followers"` +} + +// getHostCenterStats 只编排 user/wallet 两个 owner 的只读聚合,不在 gateway 重算账务或在线时长。 +func (h *Handler) getHostCenterStats(writer http.ResponseWriter, request *http.Request) { + profile, ok := h.resolveCurrentActiveHostProfile(writer, request) + if !ok { + return + } + engagementClient, engagementOK := h.userHostClient.(hostEngagementStatsClient) + revenueClient, revenueOK := h.walletClient.(hostRevenueStatsClient) + if !engagementOK || !revenueOK { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + startDate, endDate, startAtMS, endAtMS, ok := parseHostCenterStatsRange(request) + if !ok { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid date range") + return + } + + engagementResp, err := engagementClient.GetHostEngagementStats(request.Context(), &userv1.GetHostEngagementStatsRequest{ + Meta: httpkit.UserMeta(request, ""), + HostUserId: profile.GetUserId(), + StartAtMs: startAtMS, + EndAtMs: endAtMS, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + revenueResp, err := revenueClient.GetHostRevenueStats(request.Context(), &walletv1.GetHostRevenueStatsRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), + AppCode: appcode.FromContext(request.Context()), + HostUserId: profile.GetUserId(), + StartAtMs: startAtMS, + EndAtMs: endAtMS, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + engagement := engagementResp.GetStats() + revenue := revenueResp.GetStats() + httpkit.WriteOK(writer, request, map[string]any{ + "range": hostCenterStatsRangeData{StartDate: startDate, EndDate: endDate, Timezone: "UTC"}, + "metrics": hostCenterStatsMetricsData{ + DiamondEarnings: revenue.GetDiamondEarnings(), + DiamondExchanged: revenue.GetDiamondExchanged(), + GiftSenders: revenue.GetGiftSenders(), + OnlineDurationMS: engagement.GetOnlineDurationMs(), + ValidMicDurationMS: engagement.GetValidMicDurationMs(), + ValidMicDays: engagement.GetValidMicDays(), + PrivateMessageSenders: engagement.GetPrivateMessageSenders(), + NewFollowers: engagement.GetNewFollowers(), + }, + }) +} + +func parseHostCenterStatsRange(request *http.Request) (string, string, int64, int64, bool) { + startText := strings.TrimSpace(request.URL.Query().Get("start_date")) + endText := strings.TrimSpace(request.URL.Query().Get("end_date")) + if startText == "" || endText == "" { + return "", "", 0, 0, false + } + start, startErr := time.Parse("2006-01-02", startText) + end, endErr := time.Parse("2006-01-02", endText) + if startErr != nil || endErr != nil || end.Before(start) { + return "", "", 0, 0, false + } + endExclusive := end.Add(24 * time.Hour) + if int(endExclusive.Sub(start)/(24*time.Hour)) > hostCenterMaxStatsDays { + return "", "", 0, 0, false + } + return startText, endText, start.UnixMilli(), endExclusive.UnixMilli(), true +} diff --git a/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler_test.go b/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler_test.go new file mode 100644 index 00000000..321643fb --- /dev/null +++ b/services/gateway-service/internal/transport/http/userapi/host_center_stats_handler_test.go @@ -0,0 +1,30 @@ +package userapi + +import ( + "net/http/httptest" + "testing" +) + +func TestParseHostCenterStatsRangeUsesInclusiveNaturalDays(t *testing.T) { + request := httptest.NewRequest("GET", "/api/v1/host-center/stats?start_date=2026-07-06&end_date=2026-07-12", nil) + startDate, endDate, startAtMS, endAtMS, ok := parseHostCenterStatsRange(request) + if !ok || startDate != "2026-07-06" || endDate != "2026-07-12" { + t.Fatalf("range parse mismatch: ok=%t start=%s end=%s", ok, startDate, endDate) + } + if got := endAtMS - startAtMS; got != 7*24*60*60*1000 { + t.Fatalf("end must be exclusive after seven inclusive days, got %d", got) + } +} + +func TestParseHostCenterStatsRangeRejectsInvalidOrOversizedRanges(t *testing.T) { + for _, rawURL := range []string{ + "/api/v1/host-center/stats?start_date=2026-07-12&end_date=2026-07-01", + "/api/v1/host-center/stats?start_date=2026-07-12", + "/api/v1/host-center/stats?start_date=2025-01-01&end_date=2026-07-12", + } { + request := httptest.NewRequest("GET", rawURL, nil) + if _, _, _, _, ok := parseHostCenterStatsRange(request); ok { + t.Fatalf("expected invalid range for %s", rawURL) + } + } +} diff --git a/services/gateway-service/internal/transport/http/walletapi/handler.go b/services/gateway-service/internal/transport/http/walletapi/handler.go index c6da6eb5..bc8194e1 100644 --- a/services/gateway-service/internal/transport/http/walletapi/handler.go +++ b/services/gateway-service/internal/transport/http/walletapi/handler.go @@ -118,6 +118,7 @@ func (h *Handler) WalletHandlers() httproutes.WalletHandlers { WithdrawSalaryWallet: h.withdrawSalaryWallet, GetPointWalletOverview: h.getPointWalletOverview, WithdrawPointWallet: h.withdrawPointWallet, + TransferPointWalletToCoinSeller: h.transferPointWalletToCoinSeller, GetRedPacketConfig: h.getRedPacketConfig, ListRoomRedPackets: h.listRoomRedPackets, CreateRoomRedPacket: h.createRoomRedPacket, diff --git a/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler.go b/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler.go index cfd002bf..73e6f51b 100644 --- a/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler.go +++ b/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler.go @@ -18,16 +18,15 @@ import ( ) const ( - pointWalletAssetType = "POINT" - pointWalletMinimumGross = int64(1000000) - pointWalletPointsPerUSD = int64(100000) - pointWalletWithdrawFeeBPS = int32(500) - pointWalletWithdrawalScope = "huwaa" + pointWalletAssetType = "POINT" ) type pointWithdrawalGatewayClient interface { FreezePointWithdrawal(ctx context.Context, req *walletv1.FreezePointWithdrawalRequest) (*walletv1.FreezePointWithdrawalResponse, error) ReleasePointWithdrawal(ctx context.Context, req *walletv1.ReleasePointWithdrawalRequest) (*walletv1.ReleasePointWithdrawalResponse, error) + ListPointWithdrawalCoinSellers(ctx context.Context, req *walletv1.ListPointWithdrawalCoinSellersRequest) (*walletv1.ListPointWithdrawalCoinSellersResponse, error) + TransferPointToCoinSeller(ctx context.Context, req *walletv1.TransferPointToCoinSellerRequest) (*walletv1.TransferPointToCoinSellerResponse, error) + GetPointWithdrawalConfig(ctx context.Context, req *walletv1.GetPointWithdrawalConfigRequest) (*walletv1.GetPointWithdrawalConfigResponse, error) } type pointWalletOverviewData struct { @@ -37,6 +36,19 @@ type pointWalletOverviewData struct { PointsPerUSD int64 `json:"points_per_usd"` FeeBPS int32 `json:"fee_bps"` MinimumPoints int64 `json:"minimum_points"` + CoinSellers []pointWalletCoinSellerData `json:"coin_sellers"` + PolicyInstance string `json:"policy_instance_code"` +} + +type pointWalletCoinSellerData struct { + UserID string `json:"user_id"` + DisplayUserID string `json:"display_user_id"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + SortOrder int32 `json:"sort_order"` + PointAmount int64 `json:"point_amount"` + SellerCoinAmount int64 `json:"seller_coin_amount"` + ServiceCountryCodes []string `json:"service_country_codes"` } type pointWalletBalanceData struct { @@ -66,6 +78,36 @@ type pointWalletWithdrawBody struct { Address string `json:"address"` } +type pointWalletCoinSellerTransferBody struct { + CommandID string `json:"command_id"` + CommandIDCamel string `json:"commandId"` + SellerUserID flexibleJSONInt64 `json:"seller_user_id"` + SellerUserIDCamel flexibleJSONInt64 `json:"sellerUserId"` + PointAmount int64 `json:"point_amount"` + PointAmountCamel int64 `json:"pointAmount"` +} + +func (b pointWalletCoinSellerTransferBody) commandID() string { + if value := strings.TrimSpace(b.CommandID); value != "" { + return value + } + return strings.TrimSpace(b.CommandIDCamel) +} + +func (b pointWalletCoinSellerTransferBody) sellerUserID() int64 { + if b.SellerUserID.Int64() > 0 { + return b.SellerUserID.Int64() + } + return b.SellerUserIDCamel.Int64() +} + +func (b pointWalletCoinSellerTransferBody) amount() int64 { + if b.PointAmount > 0 { + return b.PointAmount + } + return b.PointAmountCamel +} + func (b pointWalletWithdrawBody) commandID() string { if value := strings.TrimSpace(b.CommandID); value != "" { return value @@ -102,7 +144,7 @@ func (b pointWalletWithdrawBody) usdtTRC20Address() string { } func (h *Handler) getPointWalletOverview(writer http.ResponseWriter, request *http.Request) { - if !isHuwaaPointWalletRequest(request) { + if !isPointWalletRequest(request) { httpkit.WriteError(writer, request, http.StatusForbidden, httpkit.CodePermissionDenied, "permission denied") return } @@ -110,7 +152,37 @@ func (h *Handler) getPointWalletOverview(writer http.ResponseWriter, request *ht httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") return } + pointWallet, ok := h.walletClient.(pointWithdrawalGatewayClient) + if !ok { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } userID := auth.UserIDFromContext(request.Context()) + profileResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{ + Meta: httpkit.UserMeta(request, ""), UserId: userID, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + profile := profileResp.GetUser() + if profile == nil { + httpkit.WriteError(writer, request, http.StatusNotFound, httpkit.CodeNotFound, "user not found") + return + } + config, err := pointWallet.GetPointWithdrawalConfig(request.Context(), &walletv1.GetPointWithdrawalConfigRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()), + RegionId: profile.GetRegionId(), NowMs: time.Now().UTC().UnixMilli(), + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + if !config.GetFound() { + // 没有已发布政策就关闭资金入口;不能回退到编译期常量造成 Admin 看似配置但账务仍走旧值。 + httpkit.WriteError(writer, request, http.StatusForbidden, httpkit.CodePermissionDenied, "point wallet policy is not configured") + return + } balanceResp, err := h.walletClient.GetBalances(request.Context(), &walletv1.GetBalancesRequest{ RequestId: httpkit.RequestIDFromContext(request.Context()), UserId: userID, @@ -121,26 +193,33 @@ func (h *Handler) getPointWalletOverview(writer http.ResponseWriter, request *ht httpkit.WriteRPCError(writer, request, err) return } - profileResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{ - Meta: httpkit.UserMeta(request, ""), - UserId: userID, + sellerResp, err := pointWallet.ListPointWithdrawalCoinSellers(request.Context(), &walletv1.ListPointWithdrawalCoinSellersRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()), + CountryCode: pointWalletCountryCode(profile), }) if err != nil { httpkit.WriteRPCError(writer, request, err) return } + sellers, err := h.pointWalletCoinSellerData(request, sellerResp.GetSellers()) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } httpkit.WriteOK(writer, request, pointWalletOverviewData{ AssetType: pointWalletAssetType, - Balance: pointBalanceFromProto(firstBalance(balanceResp.GetBalances())), + Balance: pointBalanceFromProto(firstBalance(balanceResp.GetBalances()), config.GetPointsPerUsd()), WithdrawAddress: salaryWithdrawAddressFromProto(profileResp.GetUser()), - PointsPerUSD: pointWalletPointsPerUSD, - FeeBPS: pointWalletWithdrawFeeBPS, - MinimumPoints: pointWalletMinimumGross, + PointsPerUSD: config.GetPointsPerUsd(), + FeeBPS: config.GetFeeBps(), + MinimumPoints: config.GetMinimumPoints(), + CoinSellers: sellers, + PolicyInstance: config.GetPolicyInstanceCode(), }) } func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http.Request) { - if !isHuwaaPointWalletRequest(request) { + if !isPointWalletRequest(request) { httpkit.WriteError(writer, request, http.StatusForbidden, httpkit.CodePermissionDenied, "permission denied") return } @@ -164,13 +243,31 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. return } grossPoints := body.grossPointAmount() - if grossPoints < pointWalletMinimumGross { + userID := auth.UserIDFromContext(request.Context()) + profileResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{Meta: httpkit.UserMeta(request, ""), UserId: userID}) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + profile := profileResp.GetUser() + if profile == nil { + httpkit.WriteError(writer, request, http.StatusNotFound, httpkit.CodeNotFound, "user not found") + return + } + config, err := pointWallet.GetPointWithdrawalConfig(request.Context(), &walletv1.GetPointWithdrawalConfigRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()), + RegionId: profile.GetRegionId(), NowMs: time.Now().UTC().UnixMilli(), + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + if !config.GetFound() || grossPoints < config.GetMinimumPoints() { httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument") return } - feePoints := grossPoints * int64(pointWalletWithdrawFeeBPS) / 10000 + feePoints := grossPoints * int64(config.GetFeeBps()) / 10000 netPoints := grossPoints - feePoints - userID := auth.UserIDFromContext(request.Context()) balanceResp, err := h.walletClient.GetBalances(request.Context(), &walletv1.GetBalancesRequest{ RequestId: httpkit.RequestIDFromContext(request.Context()), UserId: userID, @@ -199,8 +296,8 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. GrossPointAmount: grossPoints, FeePointAmount: feePoints, NetPointAmount: netPoints, - PointsPerUsd: pointWalletPointsPerUSD, - FeeBps: pointWalletWithdrawFeeBPS, + PointsPerUsd: config.GetPointsPerUsd(), + FeeBps: config.GetFeeBps(), Reason: "point withdrawal submitted", AppCode: appcode.FromContext(request.Context()), WithdrawalRef: httpkit.RequestIDFromContext(request.Context()), @@ -213,8 +310,13 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. AppCode: appcode.FromContext(request.Context()), UserID: userID, SalaryAssetType: pointWalletAssetType, - WithdrawAmount: formatPointUSD(netPoints, pointWalletPointsPerUSD), + WithdrawAmount: formatPointUSD(netPoints, config.GetPointsPerUsd()), WithdrawAmountMinor: grossPoints, + PointFeeAmount: feePoints, + PointNetAmount: netPoints, + PointsPerUSD: config.GetPointsPerUsd(), + PointFeeBPS: config.GetFeeBps(), + PointPolicyInstance: config.GetPolicyInstanceCode(), WithdrawMethod: financewithdrawal.MethodUSDTTRC20, WithdrawAddress: address, FreezeCommandID: freezeCommandID, @@ -222,7 +324,7 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. CreatedAtMS: nowMS, }) if err != nil { - rollbackPointWithdrawalFreeze(request, pointWallet, freezeCommandID, userID, grossPoints, feePoints, netPoints) + rollbackPointWithdrawalFreeze(request, pointWallet, freezeCommandID, userID, grossPoints, feePoints, netPoints, config.GetPointsPerUsd(), config.GetFeeBps()) httpkit.WriteError(writer, request, http.StatusInternalServerError, httpkit.CodeInternalError, "internal error") return } @@ -239,12 +341,13 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. "gross_point_amount": grossPoints, "fee_point_amount": feePoints, "net_point_amount": netPoints, - "points_per_usd": pointWalletPointsPerUSD, - "fee_bps": pointWalletWithdrawFeeBPS, - "gross_usd": formatPointUSD(grossPoints, pointWalletPointsPerUSD), - "fee_usd": formatPointUSD(feePoints, pointWalletPointsPerUSD), - "net_usd": formatPointUSD(netPoints, pointWalletPointsPerUSD), - "balance_after": pointBalanceFromProto(freezeResp.GetBalance()), + "points_per_usd": config.GetPointsPerUsd(), + "fee_bps": config.GetFeeBps(), + "policy_instance_code": config.GetPolicyInstanceCode(), + "gross_usd": formatPointUSD(grossPoints, config.GetPointsPerUsd()), + "fee_usd": formatPointUSD(feePoints, config.GetPointsPerUsd()), + "net_usd": formatPointUSD(netPoints, config.GetPointsPerUsd()), + "balance_after": pointBalanceFromProto(freezeResp.GetBalance(), config.GetPointsPerUsd()), "withdraw_method": application.WithdrawMethod, "withdraw_address": application.WithdrawAddress, "freeze_transaction_id": freezeResp.GetTransactionId(), @@ -252,11 +355,17 @@ func (h *Handler) withdrawPointWallet(writer http.ResponseWriter, request *http. }) } -func isHuwaaPointWalletRequest(request *http.Request) bool { - return strings.EqualFold(appcode.FromContext(request.Context()), pointWalletWithdrawalScope) +func isPointWalletRequest(request *http.Request) bool { + // 新钱包首先服务 Huwaa 与 Fami;Lalu 旧 gonghui 页面和既有工资钱包路由不做行为变更。 + switch strings.ToLower(strings.TrimSpace(appcode.FromContext(request.Context()))) { + case "huwaa", "fami": + return true + default: + return false + } } -func pointBalanceFromProto(balance *walletv1.AssetBalance) pointWalletBalanceData { +func pointBalanceFromProto(balance *walletv1.AssetBalance, pointsPerUSD int64) pointWalletBalanceData { if balance == nil { return pointWalletBalanceData{AssetType: pointWalletAssetType, DisplayUSD: "0.00"} } @@ -265,7 +374,7 @@ func pointBalanceFromProto(balance *walletv1.AssetBalance) pointWalletBalanceDat AvailableAmount: balance.GetAvailableAmount(), FrozenAmount: balance.GetFrozenAmount(), Version: balance.GetVersion(), - DisplayUSD: formatPointUSD(balance.GetAvailableAmount(), pointWalletPointsPerUSD), + DisplayUSD: formatPointUSD(balance.GetAvailableAmount(), pointsPerUSD), } } @@ -288,7 +397,7 @@ func pointWithdrawalFreezeCommandID(submittedCommandID string, requestID string, return fmt.Sprintf("point-withdrawal:%d", nowMS) } -func rollbackPointWithdrawalFreeze(request *http.Request, walletClient pointWithdrawalGatewayClient, freezeCommandID string, userID int64, grossPoints int64, feePoints int64, netPoints int64) { +func rollbackPointWithdrawalFreeze(request *http.Request, walletClient pointWithdrawalGatewayClient, freezeCommandID string, userID int64, grossPoints int64, feePoints int64, netPoints int64, pointsPerUSD int64, feeBPS int32) { rollbackCommandID := strings.TrimSpace(freezeCommandID) + ":rollback" if len(rollbackCommandID) > 128 { rollbackCommandID = fmt.Sprintf("point-withdrawal-rollback:%s", httpkit.RequestIDFromContext(request.Context())) @@ -302,8 +411,8 @@ func rollbackPointWithdrawalFreeze(request *http.Request, walletClient pointWith GrossPointAmount: grossPoints, FeePointAmount: feePoints, NetPointAmount: netPoints, - PointsPerUsd: pointWalletPointsPerUSD, - FeeBps: pointWalletWithdrawFeeBPS, + PointsPerUsd: pointsPerUSD, + FeeBps: feeBPS, Reason: "point withdrawal application create failed", AppCode: appcode.FromContext(request.Context()), }) @@ -311,3 +420,119 @@ func rollbackPointWithdrawalFreeze(request *http.Request, walletClient pointWith slog.Error("point_withdrawal_freeze_rollback_failed", "user_id", userID, "gross_point_amount", grossPoints, "freeze_command_id", freezeCommandID, "error", err) } } + +// transferPointWalletToCoinSeller 只接收目标和 POINT 金额;wallet 事务会重新读取 active 白名单与比例。 +func (h *Handler) transferPointWalletToCoinSeller(writer http.ResponseWriter, request *http.Request) { + if !isPointWalletRequest(request) { + httpkit.WriteError(writer, request, http.StatusForbidden, httpkit.CodePermissionDenied, "permission denied") + return + } + pointWallet, ok := h.walletClient.(pointWithdrawalGatewayClient) + if !ok || h.userProfileClient == nil || h.userHostClient == nil { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + var body pointWalletCoinSellerTransferBody + if !httpkit.Decode(writer, request, &body) { + return + } + commandID := body.commandID() + sellerUserID := body.sellerUserID() + pointAmount := body.amount() + if commandID == "" || sellerUserID <= 0 || pointAmount <= 0 { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument") + return + } + userID := auth.UserIDFromContext(request.Context()) + profileResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{Meta: httpkit.UserMeta(request, ""), UserId: userID}) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + if profileResp.GetUser() == nil { + httpkit.WriteError(writer, request, http.StatusNotFound, httpkit.CodeNotFound, "user not found") + return + } + runtimeConfig, err := pointWallet.GetPointWithdrawalConfig(request.Context(), &walletv1.GetPointWithdrawalConfigRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()), + RegionId: profileResp.GetUser().GetRegionId(), NowMs: time.Now().UTC().UnixMilli(), + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + if !runtimeConfig.GetFound() || pointAmount < runtimeConfig.GetMinimumPoints() { + // 币商和 USDT 两种提现共用已发布政策中的最低门槛,客户端不能通过切换页签绕过。 + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "point withdrawal amount is below minimum") + return + } + sellerProfileResp, err := h.userHostClient.GetCoinSellerProfile(request.Context(), &userv1.GetCoinSellerProfileRequest{ + Meta: httpkit.UserMeta(request, ""), UserId: sellerUserID, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + sellerProfile := sellerProfileResp.GetCoinSellerProfile() + if sellerProfile == nil || sellerProfile.GetStatus() != "active" || sellerProfile.GetMerchantAssetType() != "COIN_SELLER_COIN" { + // Admin 白名单只证明配置存在;转账时仍要检查实时币商身份,防止币商被停用后继续收款。 + httpkit.WriteError(writer, request, http.StatusForbidden, httpkit.CodePermissionDenied, "coin seller is not active") + return + } + receipt, err := pointWallet.TransferPointToCoinSeller(request.Context(), &walletv1.TransferPointToCoinSellerRequest{ + CommandId: commandID, AppCode: appcode.FromContext(request.Context()), SourceUserId: userID, + SellerUserId: sellerUserID, PointAmount: pointAmount, + SourceCountryCode: pointWalletCountryCode(profileResp.GetUser()), Reason: "point wallet withdrawal to coin seller", + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + httpkit.WriteOK(writer, request, map[string]any{ + "transaction_id": receipt.GetTransactionId(), "seller_user_id": strconv.FormatInt(sellerUserID, 10), + "point_amount": receipt.GetPointAmount(), "seller_coin_amount": receipt.GetSellerCoinAmount(), + "source_point_balance_after": receipt.GetSourcePointBalanceAfter(), "seller_balance_after": receipt.GetSellerBalanceAfter(), + "ratio_point_amount": receipt.GetRatioPointAmount(), "ratio_seller_coin_amount": receipt.GetRatioSellerCoinAmount(), + }) +} + +func (h *Handler) pointWalletCoinSellerData(request *http.Request, configs []*walletv1.PointWithdrawalCoinSellerConfig) ([]pointWalletCoinSellerData, error) { + if len(configs) == 0 { + return []pointWalletCoinSellerData{}, nil + } + userIDs := make([]int64, 0, len(configs)) + for _, config := range configs { + if config != nil && config.GetSellerUserId() > 0 { + userIDs = append(userIDs, config.GetSellerUserId()) + } + } + profiles, err := h.userProfileClient.BatchGetUsers(request.Context(), &userv1.BatchGetUsersRequest{Meta: httpkit.UserMeta(request, ""), UserIds: userIDs}) + if err != nil { + return nil, err + } + items := make([]pointWalletCoinSellerData, 0, len(configs)) + for _, config := range configs { + if config == nil { + continue + } + profile := profiles.GetUsers()[config.GetSellerUserId()] + // 白名单可在用户删除/禁用后短暂残留;读模型跳过缺失用户,转账入口还会实时校验 coin-seller 身份。 + if profile == nil || profile.GetStatus() != userv1.UserStatus_USER_STATUS_ACTIVE { + continue + } + items = append(items, pointWalletCoinSellerData{ + UserID: strconv.FormatInt(profile.GetUserId(), 10), DisplayUserID: profile.GetDisplayUserId(), + Nickname: profile.GetUsername(), Avatar: profile.GetAvatar(), SortOrder: config.GetSortOrder(), + PointAmount: config.GetPointAmount(), SellerCoinAmount: config.GetSellerCoinAmount(), + ServiceCountryCodes: append([]string(nil), config.GetServiceCountryCodes()...), + }) + } + return items, nil +} + +func pointWalletCountryCode(profile *userv1.User) string { + if profile == nil { + return "" + } + return strings.ToUpper(strings.TrimSpace(profile.GetCountry())) +} diff --git a/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler_test.go b/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler_test.go index 5e96c997..0f20e58d 100644 --- a/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler_test.go +++ b/services/gateway-service/internal/transport/http/walletapi/point_wallet_handler_test.go @@ -91,6 +91,11 @@ func TestWithdrawPointWalletFreezesWithClientCommandIDAndCreatesApplication(t *t writer.last.SalaryAssetType != "POINT" || writer.last.WithdrawAmount != "9.50" || writer.last.WithdrawAmountMinor != 1_000_000 || + writer.last.PointFeeAmount != 50_000 || + writer.last.PointNetAmount != 950_000 || + writer.last.PointsPerUSD != 100_000 || + writer.last.PointFeeBPS != 500 || + writer.last.PointPolicyInstance != "test-policy" || writer.last.FreezeCommandID != "client-point-withdraw-1" || writer.last.FreezeTransactionID != "point-freeze-tx" || writer.last.WithdrawAddress != "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF" { @@ -112,13 +117,34 @@ func TestWithdrawPointWalletFreezesWithClientCommandIDAndCreatesApplication(t *t } } +func TestTransferPointWalletToCoinSellerUsesStringIDAndTrustedCountry(t *testing.T) { + wallet := &fakePointWalletClient{} + handler := New(Config{ + WalletClient: wallet, + UserProfileClient: &fakePointUserProfileClient{country: "SA"}, + UserHostClient: &fakePointUserHostClient{}, + }) + recorder := httptest.NewRecorder() + request := pointWalletRequest(`{"command_id":"point-seller-1","seller_user_id":"9007199254740001","point_amount":1000000}`, "fami") + + httpkit.WithRequestID(http.HandlerFunc(handler.transferPointWalletToCoinSeller)).ServeHTTP(recorder, request) + + if recorder.Code != http.StatusOK { + t.Fatalf("point seller transfer status mismatch: got %d body=%s", recorder.Code, recorder.Body.String()) + } + if wallet.lastPointTransfer == nil || wallet.lastPointTransfer.GetSellerUserId() != 9007199254740001 || wallet.lastPointTransfer.GetSourceUserId() != 42001 || wallet.lastPointTransfer.GetSourceCountryCode() != "SA" || wallet.lastPointTransfer.GetAppCode() != "fami" { + t.Fatalf("point seller transfer request mismatch: %+v", wallet.lastPointTransfer) + } +} + type fakePointWalletClient struct { client.WalletClient - balances []*walletv1.AssetBalance - lastBalance *walletv1.GetBalancesRequest - lastFreeze *walletv1.FreezePointWithdrawalRequest - lastRelease *walletv1.ReleasePointWithdrawalRequest - freezeErr error + balances []*walletv1.AssetBalance + lastBalance *walletv1.GetBalancesRequest + lastFreeze *walletv1.FreezePointWithdrawalRequest + lastRelease *walletv1.ReleasePointWithdrawalRequest + lastPointTransfer *walletv1.TransferPointToCoinSellerRequest + freezeErr error } func (f *fakePointWalletClient) GetBalances(_ context.Context, req *walletv1.GetBalancesRequest) (*walletv1.GetBalancesResponse, error) { @@ -151,9 +177,23 @@ func (f *fakePointWalletClient) ReleasePointWithdrawal(_ context.Context, req *w return &walletv1.ReleasePointWithdrawalResponse{TransactionId: "point-release-tx"}, nil } +func (f *fakePointWalletClient) GetPointWithdrawalConfig(_ context.Context, _ *walletv1.GetPointWithdrawalConfigRequest) (*walletv1.GetPointWithdrawalConfigResponse, error) { + return &walletv1.GetPointWithdrawalConfigResponse{Found: true, PointsPerUsd: 100_000, FeeBps: 500, MinimumPoints: 1_000_000, PolicyInstanceCode: "test-policy"}, nil +} + +func (f *fakePointWalletClient) ListPointWithdrawalCoinSellers(_ context.Context, _ *walletv1.ListPointWithdrawalCoinSellersRequest) (*walletv1.ListPointWithdrawalCoinSellersResponse, error) { + return &walletv1.ListPointWithdrawalCoinSellersResponse{}, nil +} + +func (f *fakePointWalletClient) TransferPointToCoinSeller(_ context.Context, req *walletv1.TransferPointToCoinSellerRequest) (*walletv1.TransferPointToCoinSellerResponse, error) { + f.lastPointTransfer = req + return &walletv1.TransferPointToCoinSellerResponse{TransactionId: "point-seller-tx", PointAmount: req.GetPointAmount(), SellerCoinAmount: 920000}, nil +} + type fakePointUserProfileClient struct { client.UserProfileClient address string + country string err error } @@ -161,7 +201,15 @@ func (f *fakePointUserProfileClient) GetUser(_ context.Context, req *userv1.GetU if f.err != nil { return nil, f.err } - return &userv1.GetUserResponse{User: &userv1.User{UserId: req.GetUserId(), WithdrawUsdtTrc20Address: f.address}}, nil + return &userv1.GetUserResponse{User: &userv1.User{UserId: req.GetUserId(), Country: f.country, WithdrawUsdtTrc20Address: f.address}}, nil +} + +type fakePointUserHostClient struct { + client.UserHostClient +} + +func (f *fakePointUserHostClient) GetCoinSellerProfile(_ context.Context, req *userv1.GetCoinSellerProfileRequest) (*userv1.GetCoinSellerProfileResponse, error) { + return &userv1.GetCoinSellerProfileResponse{CoinSellerProfile: &userv1.CoinSellerProfile{UserId: req.GetUserId(), Status: "active", MerchantAssetType: "COIN_SELLER_COIN"}}, nil } func (f *fakePointUserProfileClient) UpdateUserWithdrawAddress(_ context.Context, req *userv1.UpdateUserWithdrawAddressRequest) (*userv1.UpdateUserWithdrawAddressResponse, error) { @@ -190,6 +238,11 @@ func (f *fakePointWithdrawalWriter) CreateApplication(_ context.Context, command SalaryAssetType: command.SalaryAssetType, WithdrawAmount: command.WithdrawAmount, WithdrawAmountMinor: command.WithdrawAmountMinor, + PointFeeAmount: command.PointFeeAmount, + PointNetAmount: command.PointNetAmount, + PointsPerUSD: command.PointsPerUSD, + PointFeeBPS: command.PointFeeBPS, + PointPolicyInstance: command.PointPolicyInstance, WithdrawMethod: command.WithdrawMethod, WithdrawAddress: command.WithdrawAddress, FreezeCommandID: command.FreezeCommandID, diff --git a/services/user-service/deploy/mysql/initdb/001_user_service.sql b/services/user-service/deploy/mysql/initdb/001_user_service.sql index 4b40a4bf..efa72a92 100644 --- a/services/user-service/deploy/mysql/initdb/001_user_service.sql +++ b/services/user-service/deploy/mysql/initdb/001_user_service.sql @@ -127,6 +127,28 @@ CREATE TABLE IF NOT EXISTS user_follows ( KEY idx_user_follows_follower_status (app_code, follower_user_id, status, followed_at_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关注表'; +CREATE TABLE IF NOT EXISTS user_follow_events ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + event_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '关注状态变化事件 ID', + follower_user_id BIGINT NOT NULL COMMENT '关注人用户 ID', + followee_user_id BIGINT NOT NULL COMMENT '被关注人用户 ID', + delta TINYINT NOT NULL COMMENT '关注 +1,取消关注 -1', + occurred_at_ms BIGINT NOT NULL COMMENT '事件时间,UTC epoch ms', + PRIMARY KEY (event_id), + KEY idx_user_follow_events_followee_time (app_code, followee_user_id, occurred_at_ms, event_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关注净增统计事件表'; + +CREATE TABLE IF NOT EXISTS user_private_message_events ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + event_id VARCHAR(128) NOT NULL COMMENT '腾讯 IM 私信事件幂等 ID', + sender_user_id BIGINT NOT NULL COMMENT '消息发送用户 ID', + target_user_id BIGINT NOT NULL COMMENT '消息接收用户 ID', + occurred_at_ms BIGINT NOT NULL COMMENT '发送时间,UTC epoch ms', + created_at_ms BIGINT NOT NULL COMMENT '落库时间,UTC epoch ms', + PRIMARY KEY (app_code, event_id), + KEY idx_private_message_target_time (app_code, target_user_id, occurred_at_ms, sender_user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户私信发送事实,仅保存统计字段'; + CREATE TABLE IF NOT EXISTS user_friend_applications ( app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', requester_user_id BIGINT NOT NULL COMMENT '申请人用户 ID', diff --git a/services/user-service/deploy/mysql/migrations/014_host_center_engagement_stats.sql b/services/user-service/deploy/mysql/migrations/014_host_center_engagement_stats.sql new file mode 100644 index 00000000..8a37f90f --- /dev/null +++ b/services/user-service/deploy/mysql/migrations/014_host_center_engagement_stats.sql @@ -0,0 +1,23 @@ +USE hyapp_user; + +CREATE TABLE IF NOT EXISTS user_follow_events ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + event_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '关注状态变化事件 ID', + follower_user_id BIGINT NOT NULL COMMENT '关注人用户 ID', + followee_user_id BIGINT NOT NULL COMMENT '被关注人用户 ID', + delta TINYINT NOT NULL COMMENT '关注 +1,取消关注 -1', + occurred_at_ms BIGINT NOT NULL COMMENT '事件时间,UTC epoch ms', + PRIMARY KEY (event_id), + KEY idx_user_follow_events_followee_time (app_code, followee_user_id, occurred_at_ms, event_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户关注净增统计事件表'; + +CREATE TABLE IF NOT EXISTS user_private_message_events ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + event_id VARCHAR(128) NOT NULL COMMENT '腾讯 IM 私信事件幂等 ID', + sender_user_id BIGINT NOT NULL COMMENT '消息发送用户 ID', + target_user_id BIGINT NOT NULL COMMENT '消息接收用户 ID', + occurred_at_ms BIGINT NOT NULL COMMENT '发送时间,UTC epoch ms', + created_at_ms BIGINT NOT NULL COMMENT '落库时间,UTC epoch ms', + PRIMARY KEY (app_code, event_id), + KEY idx_private_message_target_time (app_code, target_user_id, occurred_at_ms, sender_user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户私信发送事实,仅保存统计字段'; diff --git a/services/user-service/internal/domain/host/stats.go b/services/user-service/internal/domain/host/stats.go new file mode 100644 index 00000000..a4ab84ae --- /dev/null +++ b/services/user-service/internal/domain/host/stats.go @@ -0,0 +1,25 @@ +package host + +// EngagementStats 聚合 user-service 拥有的 App 在线、有效麦时、私信发送者和粉丝净增事实。 +type EngagementStats struct { + OnlineDurationMS int64 + ValidMicDurationMS int64 + ValidMicDays int64 + PrivateMessageSenders int64 + NewFollowers int64 +} + +// EngagementStatsQuery 使用左闭右开 UTC 毫秒区间,避免跨页/跨日查询重复统计边界事件。 +type EngagementStatsQuery struct { + HostUserID int64 + StartAtMS int64 + EndAtMS int64 +} + +// PrivateMessageEvent 是腾讯 IM 已发送私信的最小可审计事实,不保存消息正文。 +type PrivateMessageEvent struct { + EventID string + SenderUserID int64 + TargetUserID int64 + OccurredAtMS int64 +} diff --git a/services/user-service/internal/service/host/service.go b/services/user-service/internal/service/host/service.go index 2575f50a..cc46da30 100644 --- a/services/user-service/internal/service/host/service.go +++ b/services/user-service/internal/service/host/service.go @@ -57,6 +57,8 @@ type Repository interface { HasActiveManagerCapability(ctx context.Context, userID int64, capability string) (bool, error) ListAgencyMembers(ctx context.Context, agencyID int64, status string) ([]hostdomain.AgencyMembership, error) ListAgencyApplications(ctx context.Context, agencyID int64, status string) ([]hostdomain.AgencyApplication, error) + GetHostEngagementStats(ctx context.Context, query hostdomain.EngagementStatsQuery) (hostdomain.EngagementStats, error) + RecordPrivateMessageEvent(ctx context.Context, event hostdomain.PrivateMessageEvent) (bool, error) } // IDGenerator 生成 Host 领域内部事实 ID。 diff --git a/services/user-service/internal/service/host/stats.go b/services/user-service/internal/service/host/stats.go new file mode 100644 index 00000000..fd2eb54a --- /dev/null +++ b/services/user-service/internal/service/host/stats.go @@ -0,0 +1,38 @@ +package host + +import ( + "context" + "strings" + "time" + + "hyapp/pkg/xerr" + hostdomain "hyapp/services/user-service/internal/domain/host" +) + +const maxHostStatsRange = 366 * 24 * time.Hour + +// GetHostEngagementStats 读取 user-service 拥有的统计事实;收益和送礼人数由 wallet-service 聚合。 +func (s *Service) GetHostEngagementStats(ctx context.Context, query hostdomain.EngagementStatsQuery) (hostdomain.EngagementStats, error) { + if s.repository == nil { + return hostdomain.EngagementStats{}, xerr.New(xerr.Unavailable, "host repository is not configured") + } + if query.HostUserID <= 0 || query.StartAtMS <= 0 || query.EndAtMS <= query.StartAtMS { + return hostdomain.EngagementStats{}, xerr.New(xerr.InvalidArgument, "host stats range is invalid") + } + if query.EndAtMS-query.StartAtMS > int64(maxHostStatsRange/time.Millisecond) { + return hostdomain.EngagementStats{}, xerr.New(xerr.InvalidArgument, "host stats range is too large") + } + return s.repository.GetHostEngagementStats(ctx, query) +} + +// RecordPrivateMessageEvent 只保存发送者、接收者和事件时间;消息正文不进入统计库。 +func (s *Service) RecordPrivateMessageEvent(ctx context.Context, event hostdomain.PrivateMessageEvent) (bool, error) { + if s.repository == nil { + return false, xerr.New(xerr.Unavailable, "host repository is not configured") + } + event.EventID = strings.TrimSpace(event.EventID) + if event.EventID == "" || len(event.EventID) > 128 || event.SenderUserID <= 0 || event.TargetUserID <= 0 || event.OccurredAtMS <= 0 { + return false, xerr.New(xerr.InvalidArgument, "private message event is invalid") + } + return s.repository.RecordPrivateMessageEvent(ctx, event) +} diff --git a/services/user-service/internal/storage/mysql/host/stats.go b/services/user-service/internal/storage/mysql/host/stats.go new file mode 100644 index 00000000..92759286 --- /dev/null +++ b/services/user-service/internal/storage/mysql/host/stats.go @@ -0,0 +1,144 @@ +package host + +import ( + "context" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + hostdomain "hyapp/services/user-service/internal/domain/host" +) + +const validMicDayThresholdMS = int64(time.Hour / time.Millisecond) + +// GetHostEngagementStats 聚合 user-service 自己拥有的事实表,不从当前 Agency 关系反推历史归属。 +func (r *Repository) GetHostEngagementStats(ctx context.Context, query hostdomain.EngagementStatsQuery) (hostdomain.EngagementStats, error) { + if r == nil || r.db == nil { + return hostdomain.EngagementStats{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + stats := hostdomain.EngagementStats{} + appCode := appcode.FromContext(ctx) + startDate := time.UnixMilli(query.StartAtMS).UTC().Format("2006-01-02") + endDate := time.UnixMilli(query.EndAtMS - 1).UTC().Format("2006-01-02") + + if err := r.db.QueryRowContext(ctx, ` + SELECT COALESCE(SUM(mic_online_ms), 0), + COALESCE(SUM(CASE WHEN mic_online_ms >= ? THEN 1 ELSE 0 END), 0) + FROM user_mic_daily_stats + WHERE app_code = ? AND user_id = ? AND stat_date BETWEEN ? AND ?`, + validMicDayThresholdMS, appCode, query.HostUserID, startDate, endDate, + ).Scan(&stats.ValidMicDurationMS, &stats.ValidMicDays); err != nil { + return hostdomain.EngagementStats{}, err + } + + if err := r.db.QueryRowContext(ctx, ` + SELECT COUNT(DISTINCT sender_user_id) + FROM user_private_message_events + WHERE app_code = ? AND target_user_id = ? AND occurred_at_ms >= ? AND occurred_at_ms < ?`, + appCode, query.HostUserID, query.StartAtMS, query.EndAtMS, + ).Scan(&stats.PrivateMessageSenders); err != nil { + return hostdomain.EngagementStats{}, err + } + + if err := r.db.QueryRowContext(ctx, ` + SELECT COALESCE(SUM(delta), 0) + FROM user_follow_events + WHERE app_code = ? AND followee_user_id = ? AND occurred_at_ms >= ? AND occurred_at_ms < ?`, + appCode, query.HostUserID, query.StartAtMS, query.EndAtMS, + ).Scan(&stats.NewFollowers); err != nil { + return hostdomain.EngagementStats{}, err + } + + onlineMS, err := r.hostOnlineDuration(ctx, query) + if err != nil { + return hostdomain.EngagementStats{}, err + } + stats.OnlineDurationMS = onlineMS + return stats, nil +} + +// hostOnlineDuration 按每天“最早会话开始到最后一次心跳”累计;多设备/多 session 不重复相加。 +func (r *Repository) hostOnlineDuration(ctx context.Context, query hostdomain.EngagementStatsQuery) (int64, error) { + rows, err := r.db.QueryContext(ctx, ` + SELECT created_at_ms, last_heartbeat_at_ms + FROM auth_sessions + WHERE app_code = ? AND user_id = ? + AND last_heartbeat_at_ms >= ? AND created_at_ms < ?`, + appcode.FromContext(ctx), query.HostUserID, query.StartAtMS, query.EndAtMS, + ) + if err != nil { + return 0, err + } + defer rows.Close() + + type daySpan struct{ first, last int64 } + spans := map[string]daySpan{} + for rows.Next() { + var startedAtMS, heartbeatAtMS int64 + if err := rows.Scan(&startedAtMS, &heartbeatAtMS); err != nil { + return 0, err + } + start := maxInt64(startedAtMS, query.StartAtMS) + end := minInt64(heartbeatAtMS, query.EndAtMS-1) + if end < start { + continue + } + for day := utcDayStart(start); day <= utcDayStart(end); day += int64(24 * time.Hour / time.Millisecond) { + segmentStart := maxInt64(start, day) + segmentEnd := minInt64(end, day+int64(24*time.Hour/time.Millisecond)-1) + key := time.UnixMilli(day).UTC().Format("2006-01-02") + span, exists := spans[key] + if !exists || segmentStart < span.first { + span.first = segmentStart + } + if !exists || segmentEnd > span.last { + span.last = segmentEnd + } + spans[key] = span + } + } + if err := rows.Err(); err != nil { + return 0, err + } + var total int64 + for _, span := range spans { + if span.last >= span.first { + total += span.last - span.first + } + } + return total, nil +} + +// RecordPrivateMessageEvent 用 app_code + event_id 幂等,不保存消息正文或扩展负载。 +func (r *Repository) RecordPrivateMessageEvent(ctx context.Context, event hostdomain.PrivateMessageEvent) (bool, error) { + result, err := r.db.ExecContext(ctx, ` + INSERT IGNORE INTO user_private_message_events ( + app_code, event_id, sender_user_id, target_user_id, occurred_at_ms, created_at_ms + ) VALUES (?, ?, ?, ?, ?, ?)`, + appcode.FromContext(ctx), event.EventID, event.SenderUserID, event.TargetUserID, event.OccurredAtMS, time.Now().UTC().UnixMilli(), + ) + if err != nil { + return false, err + } + rows, err := result.RowsAffected() + return rows > 0, err +} + +func utcDayStart(value int64) int64 { + t := time.UnixMilli(value).UTC() + return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC).UnixMilli() +} + +func minInt64(left, right int64) int64 { + if left < right { + return left + } + return right +} + +func maxInt64(left, right int64) int64 { + if left > right { + return left + } + return right +} diff --git a/services/user-service/internal/storage/mysql/host/stats_test.go b/services/user-service/internal/storage/mysql/host/stats_test.go new file mode 100644 index 00000000..bffa69e1 --- /dev/null +++ b/services/user-service/internal/storage/mysql/host/stats_test.go @@ -0,0 +1,55 @@ +package host + +import ( + "context" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "hyapp/pkg/appcode" + hostdomain "hyapp/services/user-service/internal/domain/host" +) + +func TestGetHostEngagementStatsAggregatesOwnedFacts(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("create sqlmock: %v", err) + } + defer db.Close() + + mock.ExpectQuery("FROM user_mic_daily_stats"). + WithArgs(validMicDayThresholdMS, "fami", int64(42), "2026-07-06", "2026-07-12"). + WillReturnRows(sqlmock.NewRows([]string{"mic_ms", "valid_days"}).AddRow(int64(5400000), int64(1))) + mock.ExpectQuery("FROM user_private_message_events"). + WithArgs("fami", int64(42), int64(1783296000000), int64(1783900800000)). + WillReturnRows(sqlmock.NewRows([]string{"senders"}).AddRow(int64(6))) + mock.ExpectQuery("FROM user_follow_events"). + WithArgs("fami", int64(42), int64(1783296000000), int64(1783900800000)). + WillReturnRows(sqlmock.NewRows([]string{"followers"}).AddRow(int64(4))) + mock.ExpectQuery(regexp.QuoteMeta(` + SELECT created_at_ms, last_heartbeat_at_ms + FROM auth_sessions + WHERE app_code = ? AND user_id = ? + AND last_heartbeat_at_ms >= ? AND created_at_ms < ?`)). + WithArgs("fami", int64(42), int64(1783296000000), int64(1783900800000)). + WillReturnRows(sqlmock.NewRows([]string{"created_at_ms", "last_heartbeat_at_ms"}). + AddRow(int64(1783299600000), int64(1783303200000)). + AddRow(int64(1783301400000), int64(1783306800000))) + + repo := New(db) + stats, err := repo.GetHostEngagementStats(appcode.WithContext(context.Background(), "fami"), hostdomain.EngagementStatsQuery{ + HostUserID: 42, + StartAtMS: 1783296000000, + EndAtMS: 1783900800000, + }) + if err != nil { + t.Fatalf("GetHostEngagementStats failed: %v", err) + } + // 两个重叠 session 按当天最早开始到最晚心跳合并,不能相加成重复在线时长。 + if stats.OnlineDurationMS != 7200000 || stats.ValidMicDurationMS != 5400000 || stats.ValidMicDays != 1 || stats.PrivateMessageSenders != 6 || stats.NewFollowers != 4 { + t.Fatalf("unexpected engagement stats: %+v", stats) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Fatalf("unmet SQL expectations: %v", err) + } +} diff --git a/services/user-service/internal/storage/mysql/user/social_repository.go b/services/user-service/internal/storage/mysql/user/social_repository.go index 34591bee..e03f53c6 100644 --- a/services/user-service/internal/storage/mysql/user/social_repository.go +++ b/services/user-service/internal/storage/mysql/user/social_repository.go @@ -136,6 +136,15 @@ func (r *Repository) FollowUser(ctx context.Context, followerUserID int64, follo } } if shouldIncrement { + // 新增粉丝按事件净增统计;状态未变化的重复关注不写事件,避免客户端重试重复 +1。 + if _, err := tx.ExecContext(ctx, ` + INSERT INTO user_follow_events ( + app_code, follower_user_id, followee_user_id, delta, occurred_at_ms + ) VALUES (?, ?, ?, 1, ?)`, + appCode, followerUserID, followeeUserID, nowMs, + ); err != nil { + return userdomain.ProfileStats{}, err + } if _, err := tx.ExecContext(ctx, ` UPDATE user_profile_stats SET following_count = following_count + 1, updated_at_ms = ? @@ -176,6 +185,15 @@ func (r *Repository) UnfollowUser(ctx context.Context, followerUserID int64, fol ); err != nil { return userdomain.ProfileStats{}, err } + // 取消关注写 -1,确保筛选区间内的新增粉丝展示为净增而不是只累计关注动作。 + if _, err := tx.ExecContext(ctx, ` + INSERT INTO user_follow_events ( + app_code, follower_user_id, followee_user_id, delta, occurred_at_ms + ) VALUES (?, ?, ?, -1, ?)`, + appCode, followerUserID, followeeUserID, nowMs, + ); err != nil { + return userdomain.ProfileStats{}, err + } if _, err := tx.ExecContext(ctx, ` UPDATE user_profile_stats SET following_count = GREATEST(following_count - 1, 0), updated_at_ms = ? diff --git a/services/user-service/internal/transport/grpc/host_stats.go b/services/user-service/internal/transport/grpc/host_stats.go new file mode 100644 index 00000000..525c70d7 --- /dev/null +++ b/services/user-service/internal/transport/grpc/host_stats.go @@ -0,0 +1,50 @@ +package grpc + +import ( + "context" + + userv1 "hyapp.local/api/proto/user/v1" + "hyapp/pkg/xerr" + hostdomain "hyapp/services/user-service/internal/domain/host" +) + +// GetHostEngagementStats 返回 user-service 拥有的主播互动统计;调用方不能提交聚合值。 +func (s *Server) GetHostEngagementStats(ctx context.Context, req *userv1.GetHostEngagementStatsRequest) (*userv1.GetHostEngagementStatsResponse, error) { + if s.hostSvc == nil { + return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) + } + ctx = contextWithApp(ctx, req.GetMeta()) + stats, err := s.hostSvc.GetHostEngagementStats(ctx, hostdomain.EngagementStatsQuery{ + HostUserID: req.GetHostUserId(), + StartAtMS: req.GetStartAtMs(), + EndAtMS: req.GetEndAtMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &userv1.GetHostEngagementStatsResponse{Stats: &userv1.HostEngagementStats{ + OnlineDurationMs: stats.OnlineDurationMS, + ValidMicDurationMs: stats.ValidMicDurationMS, + ValidMicDays: stats.ValidMicDays, + PrivateMessageSenders: stats.PrivateMessageSenders, + NewFollowers: stats.NewFollowers, + }}, nil +} + +// RecordPrivateMessageEvent 只接受 gateway 已鉴权回调产生的最小事件事实。 +func (s *Server) RecordPrivateMessageEvent(ctx context.Context, req *userv1.RecordPrivateMessageEventRequest) (*userv1.RecordPrivateMessageEventResponse, error) { + if s.hostSvc == nil { + return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) + } + ctx = contextWithApp(ctx, req.GetMeta()) + created, err := s.hostSvc.RecordPrivateMessageEvent(ctx, hostdomain.PrivateMessageEvent{ + EventID: req.GetEventId(), + SenderUserID: req.GetSenderUserId(), + TargetUserID: req.GetTargetUserId(), + OccurredAtMS: req.GetOccurredAtMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &userv1.RecordPrivateMessageEventResponse{Created: created}, nil +} diff --git a/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql b/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql index cecd19ea..69bc93b7 100644 --- a/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql +++ b/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql @@ -131,6 +131,7 @@ CREATE TABLE IF NOT EXISTS wallet_policy_instances ( effective_to_ms BIGINT NOT NULL DEFAULT 0 COMMENT '0 表示长期有效', host_point_asset_type VARCHAR(32) NOT NULL DEFAULT 'POINT' COMMENT '主播收益积分资产', host_point_ratio_ppm BIGINT NOT NULL DEFAULT 700000 COMMENT '有效付费礼物转 POINT 比例,ppm', + agency_point_ratio_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '有效付费礼物给 Agency owner 的 POINT 分成比例,ppm', points_per_usd BIGINT NOT NULL DEFAULT 100000 COMMENT 'POINT/USD 展示换算比例', withdraw_fee_bps INT NOT NULL DEFAULT 500 COMMENT '提现手续费 bps', rule_json JSON NOT NULL COMMENT '完整政策快照', @@ -142,6 +143,41 @@ CREATE TABLE IF NOT EXISTS wallet_policy_instances ( KEY idx_wallet_policy_active (app_code, region_id, status, effective_from_ms, effective_to_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包运行侧收益政策实例表'; +-- 三套 App 共享同一张配置表,但 app_code 是主键的一部分;新 App 只需配置数据,不再复制表和业务代码。 +-- 未配置任何 active 行时 H5 币商提现入口显示为空,不能用伪造默认币商兜底。 +CREATE TABLE IF NOT EXISTS point_withdrawal_coin_seller_configs ( + app_code VARCHAR(32) NOT NULL COMMENT '应用编码', + seller_user_id BIGINT NOT NULL COMMENT '币商用户 ID', + sort_order INT NOT NULL DEFAULT 0 COMMENT '展示顺序,越小越靠前', + point_amount BIGINT NOT NULL COMMENT '兑换比例中的 POINT 分母', + seller_coin_amount BIGINT NOT NULL COMMENT '兑换比例中的币商金币分子', + service_country_codes JSON NOT NULL COMMENT '服务国家码数组;空数组表示不限国家', + status VARCHAR(24) NOT NULL DEFAULT 'active' COMMENT 'active/disabled', + created_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + updated_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, seller_user_id), + KEY idx_point_withdraw_seller_list (app_code, status, sort_order, seller_user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='POINT 提现币商白名单与兑换比例'; + +-- Agency 分成独立流水同时承担归属快照和审计依据;不能按当前成员关系反推历史收益。 +CREATE TABLE IF NOT EXISTS agency_point_share_entries ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + transaction_id VARCHAR(96) NOT NULL COMMENT '礼物钱包交易 ID', + host_user_id BIGINT NOT NULL COMMENT '收礼主播用户 ID 快照', + agency_owner_user_id BIGINT NOT NULL COMMENT '送礼时 Agency owner 用户 ID 快照', + sender_user_id BIGINT NOT NULL COMMENT '送礼用户 ID', + room_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '房间 ID,私聊送礼为空', + point_delta BIGINT NOT NULL COMMENT 'Agency owner 本次 POINT 分成', + ratio_ppm BIGINT NOT NULL COMMENT 'Agency 分成比例快照', + policy_instance_code VARCHAR(96) NOT NULL DEFAULT '' COMMENT '收益策略实例快照', + created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms', + PRIMARY KEY (app_code, transaction_id, agency_owner_user_id), + KEY idx_agency_point_share_owner_time (app_code, agency_owner_user_id, created_at_ms), + KEY idx_agency_point_share_host_time (app_code, host_user_id, created_at_ms) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Agency POINT 礼物分成流水'; + -- 主播工资周期钻石账户:只记录政策结算用累计值,不作为用户可消费或可提现的钱包资产。 -- cycle_key 当前固定为 UTC yyyy-MM;后续日结/半月结不清空该账户,月末清算任务按策略处理。 CREATE TABLE IF NOT EXISTS host_period_diamond_accounts ( diff --git a/services/wallet-service/internal/domain/ledger/agency_host_gift_stats.go b/services/wallet-service/internal/domain/ledger/agency_host_gift_stats.go new file mode 100644 index 00000000..b8cc4e28 --- /dev/null +++ b/services/wallet-service/internal/domain/ledger/agency_host_gift_stats.go @@ -0,0 +1,12 @@ +package ledger + +type AgencyHostGiftStats struct { + GiftIncome int64 + GiftedHostCount int64 +} + +type AgencyHostGiftStatsQuery struct { + HostUserIDs []int64 + StartAtMS int64 + EndAtMS int64 +} diff --git a/services/wallet-service/internal/domain/ledger/agency_point_share_stats.go b/services/wallet-service/internal/domain/ledger/agency_point_share_stats.go new file mode 100644 index 00000000..b4e484ca --- /dev/null +++ b/services/wallet-service/internal/domain/ledger/agency_point_share_stats.go @@ -0,0 +1,13 @@ +package ledger + +// AgencyPointShareStats 聚合送礼时已固化归属的 Agency POINT 分成。 +type AgencyPointShareStats struct { + ShareIncome int64 + GiftedHostCount int64 +} + +type AgencyPointShareStatsQuery struct { + AgencyOwnerUserID int64 + StartAtMS int64 + EndAtMS int64 +} diff --git a/services/wallet-service/internal/domain/ledger/host_revenue_stats.go b/services/wallet-service/internal/domain/ledger/host_revenue_stats.go new file mode 100644 index 00000000..17885d06 --- /dev/null +++ b/services/wallet-service/internal/domain/ledger/host_revenue_stats.go @@ -0,0 +1,15 @@ +package ledger + +// HostRevenueStats 是主播中心按日期展示的 POINT 收益、已兑换数量和去重送礼人数。 +type HostRevenueStats struct { + DiamondEarnings int64 + DiamondExchanged int64 + GiftSenders int64 +} + +// HostRevenueStatsQuery 使用左闭右开 UTC 毫秒区间;调用方必须限制区间长度。 +type HostRevenueStatsQuery struct { + HostUserID int64 + StartAtMS int64 + EndAtMS int64 +} diff --git a/services/wallet-service/internal/domain/ledger/point_coin_seller.go b/services/wallet-service/internal/domain/ledger/point_coin_seller.go new file mode 100644 index 00000000..9f213497 --- /dev/null +++ b/services/wallet-service/internal/domain/ledger/point_coin_seller.go @@ -0,0 +1,48 @@ +package ledger + +// PointWithdrawalCoinSellerConfig 是 POINT 提现可选币商及其服务范围、兑换比例的运行快照。 +type PointWithdrawalCoinSellerConfig struct { + AppCode string + SellerUserID int64 + SortOrder int + PointAmount int64 + SellerCoinAmount int64 + ServiceCountryCodes []string + Status string + CreatedAtMS int64 + UpdatedAtMS int64 +} + +// PointToCoinSellerCommand 只接受用户、目标和金额;比例必须由 wallet 数据库的 active 白名单解析。 +type PointToCoinSellerCommand struct { + AppCode string + CommandID string + SourceUserID int64 + SellerUserID int64 + PointAmount int64 + SourceCountryCode string + Reason string +} + +// PointToCoinSellerReceipt 是 POINT 扣款和币商库存入账的双边稳定回执。 +type PointToCoinSellerReceipt struct { + TransactionID string + SourceUserID int64 + SellerUserID int64 + SourcePointBalanceAfter int64 + SellerBalanceAfter int64 + PointAmount int64 + SellerCoinAmount int64 + RatioPointAmount int64 + RatioSellerCoinAmount int64 + CreatedAtMS int64 +} + +// PointWithdrawalRuntimeConfig 是已发布政策中钱包页需要展示并用于冻结的参数。 +type PointWithdrawalRuntimeConfig struct { + Found bool + PointsPerUSD int64 + FeeBPS int64 + MinimumPoints int64 + PolicyInstanceCode string +} diff --git a/services/wallet-service/internal/service/wallet/agency_host_gift_stats.go b/services/wallet-service/internal/service/wallet/agency_host_gift_stats.go new file mode 100644 index 00000000..651afedd --- /dev/null +++ b/services/wallet-service/internal/service/wallet/agency_host_gift_stats.go @@ -0,0 +1,31 @@ +package wallet + +import ( + "context" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +const maxAgencyHostGiftStatsRange = 366 * 24 * time.Hour + +func (s *Service) GetAgencyHostGiftStats(ctx context.Context, appCode string, query ledger.AgencyHostGiftStatsQuery) (ledger.AgencyHostGiftStats, error) { + if s.repository == nil { + return ledger.AgencyHostGiftStats{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + if len(query.HostUserIDs) > 1000 || query.StartAtMS <= 0 || query.EndAtMS <= query.StartAtMS { + return ledger.AgencyHostGiftStats{}, xerr.New(xerr.InvalidArgument, "agency host gift stats range is invalid") + } + for _, userID := range query.HostUserIDs { + if userID <= 0 { + return ledger.AgencyHostGiftStats{}, xerr.New(xerr.InvalidArgument, "host_user_ids is invalid") + } + } + if query.EndAtMS-query.StartAtMS > int64(maxAgencyHostGiftStatsRange/time.Millisecond) { + return ledger.AgencyHostGiftStats{}, xerr.New(xerr.InvalidArgument, "agency host gift stats range is too large") + } + ctx = appcode.WithContext(ctx, appcode.Normalize(appCode)) + return s.repository.GetAgencyHostGiftStats(ctx, query) +} diff --git a/services/wallet-service/internal/service/wallet/agency_point_share_stats.go b/services/wallet-service/internal/service/wallet/agency_point_share_stats.go new file mode 100644 index 00000000..c1c673a9 --- /dev/null +++ b/services/wallet-service/internal/service/wallet/agency_point_share_stats.go @@ -0,0 +1,26 @@ +package wallet + +import ( + "context" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +const maxAgencyPointShareStatsRange = 366 * 24 * time.Hour + +func (s *Service) GetAgencyPointShareStats(ctx context.Context, appCode string, query ledger.AgencyPointShareStatsQuery) (ledger.AgencyPointShareStats, error) { + if s.repository == nil { + return ledger.AgencyPointShareStats{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + if query.AgencyOwnerUserID <= 0 || query.StartAtMS <= 0 || query.EndAtMS <= query.StartAtMS { + return ledger.AgencyPointShareStats{}, xerr.New(xerr.InvalidArgument, "agency point share stats range is invalid") + } + if query.EndAtMS-query.StartAtMS > int64(maxAgencyPointShareStatsRange/time.Millisecond) { + return ledger.AgencyPointShareStats{}, xerr.New(xerr.InvalidArgument, "agency point share stats range is too large") + } + ctx = appcode.WithContext(ctx, appcode.Normalize(appCode)) + return s.repository.GetAgencyPointShareStats(ctx, query) +} diff --git a/services/wallet-service/internal/service/wallet/host_revenue_stats.go b/services/wallet-service/internal/service/wallet/host_revenue_stats.go new file mode 100644 index 00000000..d29a647a --- /dev/null +++ b/services/wallet-service/internal/service/wallet/host_revenue_stats.go @@ -0,0 +1,27 @@ +package wallet + +import ( + "context" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +const maxHostRevenueStatsRange = 366 * 24 * time.Hour + +// GetHostRevenueStats 聚合钱包 owner 内的 POINT 收益/兑换和去重送礼人,不让 gateway 扫账本。 +func (s *Service) GetHostRevenueStats(ctx context.Context, appCode string, query ledger.HostRevenueStatsQuery) (ledger.HostRevenueStats, error) { + if s.repository == nil { + return ledger.HostRevenueStats{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + if query.HostUserID <= 0 || query.StartAtMS <= 0 || query.EndAtMS <= query.StartAtMS { + return ledger.HostRevenueStats{}, xerr.New(xerr.InvalidArgument, "host revenue stats range is invalid") + } + if query.EndAtMS-query.StartAtMS > int64(maxHostRevenueStatsRange/time.Millisecond) { + return ledger.HostRevenueStats{}, xerr.New(xerr.InvalidArgument, "host revenue stats range is too large") + } + ctx = appcode.WithContext(ctx, appcode.Normalize(appCode)) + return s.repository.GetHostRevenueStats(ctx, query) +} diff --git a/services/wallet-service/internal/service/wallet/point_coin_seller.go b/services/wallet-service/internal/service/wallet/point_coin_seller.go new file mode 100644 index 00000000..8c735b43 --- /dev/null +++ b/services/wallet-service/internal/service/wallet/point_coin_seller.go @@ -0,0 +1,56 @@ +package wallet + +import ( + "context" + "strings" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// ListPointWithdrawalCoinSellers 返回服务端过滤后的币商白名单;国家由可信用户资料提供而不是客户端表单。 +func (s *Service) ListPointWithdrawalCoinSellers(ctx context.Context, appCode string, countryCode string, includeDisabled bool) ([]ledger.PointWithdrawalCoinSellerConfig, error) { + if strings.TrimSpace(appCode) == "" { + return nil, xerr.New(xerr.InvalidArgument, "app_code is required") + } + if s.repository == nil { + return nil, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + appCode = appcode.Normalize(appCode) + return s.repository.ListPointWithdrawalCoinSellers(appcode.WithContext(ctx, appCode), appCode, strings.ToUpper(strings.TrimSpace(countryCode)), includeDisabled) +} + +// TransferPointToCoinSeller 验证客户端允许提交的最小字段;兑换比例由 repository 事务内锁定配置解析。 +func (s *Service) TransferPointToCoinSeller(ctx context.Context, command ledger.PointToCoinSellerCommand) (ledger.PointToCoinSellerReceipt, error) { + if strings.TrimSpace(command.AppCode) == "" || strings.TrimSpace(command.CommandID) == "" || command.SourceUserID <= 0 || command.SellerUserID <= 0 || command.PointAmount <= 0 { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.InvalidArgument, "point coin seller transfer command is incomplete") + } + command.AppCode = appcode.Normalize(command.AppCode) + command.CommandID = strings.TrimSpace(command.CommandID) + command.SourceCountryCode = strings.ToUpper(strings.TrimSpace(command.SourceCountryCode)) + command.Reason = strings.TrimSpace(command.Reason) + if len(command.CommandID) > 128 || len(command.SourceCountryCode) > 16 || len(command.Reason) > 512 { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.InvalidArgument, "point coin seller transfer text fields are too long") + } + if s.repository == nil { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + return s.repository.TransferPointToCoinSeller(appcode.WithContext(ctx, command.AppCode), command) +} + +// GetPointWithdrawalConfig 读取已发布政策快照;nowMS 由服务端补齐,避免客户端选择历史政策。 +func (s *Service) GetPointWithdrawalConfig(ctx context.Context, appCode string, regionID int64, nowMS int64) (ledger.PointWithdrawalRuntimeConfig, error) { + if strings.TrimSpace(appCode) == "" || regionID < 0 { + return ledger.PointWithdrawalRuntimeConfig{}, xerr.New(xerr.InvalidArgument, "point withdrawal config query is invalid") + } + if s.repository == nil { + return ledger.PointWithdrawalRuntimeConfig{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + if nowMS <= 0 { + nowMS = time.Now().UnixMilli() + } + appCode = appcode.Normalize(appCode) + return s.repository.GetPointWithdrawalConfig(appcode.WithContext(ctx, appCode), appCode, regionID, nowMS) +} diff --git a/services/wallet-service/internal/service/wallet/point_withdrawal.go b/services/wallet-service/internal/service/wallet/point_withdrawal.go index b1732f50..eadf97e3 100644 --- a/services/wallet-service/internal/service/wallet/point_withdrawal.go +++ b/services/wallet-service/internal/service/wallet/point_withdrawal.go @@ -10,12 +10,11 @@ import ( ) const ( - defaultPointWithdrawalFeeBPS int64 = 500 defaultPointWithdrawalPointsPerUSD int64 = 100000 minPointWithdrawalGrossPoints int64 = 1000000 ) -// FreezePointWithdrawal 把 Huwaa 收益积分从 available 冻结到 frozen;它复用钱包单边冻结账本,但不开放旧工资资产。 +// FreezePointWithdrawal 把已启用 App 的收益积分从 available 冻结到 frozen;gateway 必须先读取已发布政策快照。 func (s *Service) FreezePointWithdrawal(ctx context.Context, command ledger.PointWithdrawalCommand) (ledger.PointWithdrawalReceipt, error) { if err := normalizePointWithdrawalCommand(&command, false); err != nil { return ledger.PointWithdrawalReceipt{}, err @@ -83,9 +82,13 @@ func normalizePointWithdrawalCommand(command *ledger.PointWithdrawalCommand, req return xerr.New(xerr.InvalidArgument, "operator_user_id is required") } command.CommandID = strings.TrimSpace(command.CommandID) + if strings.TrimSpace(command.AppCode) == "" { + return xerr.New(xerr.InvalidArgument, "app_code is required") + } command.AppCode = appcode.Normalize(command.AppCode) - if command.AppCode != "huwaa" { - return xerr.New(xerr.InvalidArgument, "point withdrawal is only enabled for huwaa") + if command.AppCode != "huwaa" && command.AppCode != "fami" { + // Lalu 继续使用旧公会工资提现链路;只有显式迁移到 POINT 钱包的 App 才能调用本接口。 + return xerr.New(xerr.InvalidArgument, "point withdrawal is not enabled for app") } command.AssetType = strings.ToUpper(strings.TrimSpace(command.AssetType)) if !ledger.ValidPointWithdrawalAssetType(command.AssetType) { @@ -97,9 +100,6 @@ func normalizePointWithdrawalCommand(command *ledger.PointWithdrawalCommand, req if command.PointsPerUSD <= 0 { command.PointsPerUSD = defaultPointWithdrawalPointsPerUSD } - if command.FeeBPS <= 0 { - command.FeeBPS = defaultPointWithdrawalFeeBPS - } if command.FeeBPS < 0 || command.FeeBPS > 10000 { return xerr.New(xerr.InvalidArgument, "point withdrawal fee_bps is invalid") } diff --git a/services/wallet-service/internal/service/wallet/ports/repository.go b/services/wallet-service/internal/service/wallet/ports/repository.go index 711dfe91..36dda1af 100644 --- a/services/wallet-service/internal/service/wallet/ports/repository.go +++ b/services/wallet-service/internal/service/wallet/ports/repository.go @@ -55,6 +55,9 @@ type HostSalaryStore interface { GetActiveHostSalaryPolicy(ctx context.Context, regionID int64, settlementMode string, triggerMode string, nowMs int64) (ledger.HostSalaryPolicy, bool, error) GetHostSalaryProgress(ctx context.Context, userID int64, cycleKey string) (ledger.HostSalaryProgress, error) GetTeamHostSalaryStats(ctx context.Context, query ledger.TeamHostSalaryStatsQuery) ([]ledger.TeamHostSalaryCycleStat, error) + GetHostRevenueStats(ctx context.Context, query ledger.HostRevenueStatsQuery) (ledger.HostRevenueStats, error) + GetAgencyPointShareStats(ctx context.Context, query ledger.AgencyPointShareStatsQuery) (ledger.AgencyPointShareStats, error) + GetAgencyHostGiftStats(ctx context.Context, query ledger.AgencyHostGiftStatsQuery) (ledger.AgencyHostGiftStats, error) ProcessHostSalarySettlementBatch(ctx context.Context, command ledger.HostSalarySettlementBatchCommand) (ledger.HostSalarySettlementBatchResult, error) } @@ -66,6 +69,9 @@ type CoinSellerStore interface { ListCoinSellerSalaryExchangeRateTiers(ctx context.Context, appCode string, regionID int64, includeDisabled bool) ([]ledger.CoinSellerSalaryExchangeRateTier, error) ExchangeSalaryToCoin(ctx context.Context, command ledger.SalaryExchangeCommand) (ledger.SalaryExchangeReceipt, error) TransferSalaryToCoinSeller(ctx context.Context, command ledger.SalaryTransferToCoinSellerCommand) (ledger.SalaryTransferToCoinSellerReceipt, error) + ListPointWithdrawalCoinSellers(ctx context.Context, appCode string, countryCode string, includeDisabled bool) ([]ledger.PointWithdrawalCoinSellerConfig, error) + TransferPointToCoinSeller(ctx context.Context, command ledger.PointToCoinSellerCommand) (ledger.PointToCoinSellerReceipt, error) + GetPointWithdrawalConfig(ctx context.Context, appCode string, regionID int64, nowMS int64) (ledger.PointWithdrawalRuntimeConfig, error) FreezeSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error) SettleSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error) ReleaseSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error) diff --git a/services/wallet-service/internal/service/wallet/service_test.go b/services/wallet-service/internal/service/wallet/service_test.go index 550dad28..ff1bf806 100644 --- a/services/wallet-service/internal/service/wallet/service_test.go +++ b/services/wallet-service/internal/service/wallet/service_test.go @@ -168,6 +168,44 @@ func TestHuwaaHostGiftPolicyCreditsPointWithoutCoinIncomeAndAllowsSelfGift(t *te } } +func TestFamiHostGiftPolicyCreditsAgencyShareWithHistoricalOwnershipSnapshot(t *testing.T) { + repository := mysqltest.NewRepository(t) + repository.SetBalanceForApp("fami", 32001, 1000) + repository.SetGiftPriceForApp("fami", "fami-rose", "v1", 100, 0, 100) + repository.SeedWalletPolicyInstanceWithAgency("fami", "fami-guild-live", 0, "active", 700000, 200000) + svc := walletservice.New(repository) + + receipt, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{ + AppCode: "fami", CommandID: "cmd-fami-agency-share", RoomID: "room-fami", + SenderUserID: 32001, TargetUserID: 32002, TargetIsHost: true, TargetHostRegionID: 12, + TargetAgencyOwnerUserID: 32003, GiftID: "fami-rose", GiftCount: 1, PriceVersion: "v1", RegionID: 12, SenderRegionID: 12, + }) + if err != nil { + t.Fatalf("DebitGift with Fami agency policy failed: %v", err) + } + if receipt.HostPointAdded != 70 || receipt.HostPointBalanceAfter != 70 { + t.Fatalf("Fami host point receipt mismatch: %+v", receipt) + } + assertBalanceForApp(t, svc, "fami", 32002, ledger.AssetPoint, 70) + assertBalanceForApp(t, svc, "fami", 32003, ledger.AssetPoint, 20) + if got := repository.CountRows("agency_point_share_entries", "transaction_id = ? AND host_user_id = ? AND agency_owner_user_id = ? AND point_delta = ? AND ratio_ppm = ?", receipt.TransactionID, int64(32002), int64(32003), int64(20), int64(200000)); got != 1 { + t.Fatalf("Fami agency share snapshot mismatch, got %d", got) + } + if got := repository.CountRows("wallet_outbox", "transaction_id = ? AND event_type = ?", receipt.TransactionID, "AgencyPointCredited"); got != 1 { + t.Fatalf("Fami agency share must publish one event, got %d", got) + } + + replayed, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{ + AppCode: "fami", CommandID: "cmd-fami-agency-share", RoomID: "room-fami", + SenderUserID: 32001, TargetUserID: 32002, TargetIsHost: true, TargetHostRegionID: 12, + TargetAgencyOwnerUserID: 32003, GiftID: "fami-rose", GiftCount: 1, PriceVersion: "v1", RegionID: 12, SenderRegionID: 12, + }) + if err != nil || replayed.TransactionID != receipt.TransactionID { + t.Fatalf("Fami agency share replay mismatch: receipt=%+v err=%v", replayed, err) + } + assertBalanceForApp(t, svc, "fami", 32003, ledger.AssetPoint, 20) +} + func TestHostGiftWithoutActiveHuwaaPolicyKeepsLegacyCoinIncome(t *testing.T) { repository := mysqltest.NewRepository(t) repository.SetBalance(31011, 1000) @@ -2147,6 +2185,7 @@ func TestPointWithdrawalAppGateWithoutMySQL(t *testing.T) { UserID: 23012, AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, + FeeBPS: 500, }) if err != nil { t.Fatalf("Huwaa POINT withdrawal should reach repository: %v", err) @@ -2163,6 +2202,21 @@ func TestPointWithdrawalAppGateWithoutMySQL(t *testing.T) { } } +func TestFamiPointWithdrawalAllowsAdminConfiguredZeroFee(t *testing.T) { + repository := &fakePointGateRepository{} + svc := walletservice.New(repository) + receipt, err := svc.FreezePointWithdrawal(context.Background(), ledger.PointWithdrawalCommand{ + AppCode: "fami", CommandID: "cmd-fami-zero-fee", UserID: 23013, + AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, PointsPerUSD: 200_000, FeeBPS: 0, + }) + if err != nil { + t.Fatalf("zero-fee Fami point withdrawal failed: %v", err) + } + if receipt.FeePointAmount != 0 || receipt.NetPointAmount != 1_000_000 || receipt.PointsPerUSD != 200_000 || receipt.FeeBPS != 0 { + t.Fatalf("zero-fee policy snapshot mismatch: %+v", receipt) + } +} + func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { repository := mysqltest.NewRepository(t) repository.SetAssetBalanceForApp("huwaa", 22001, ledger.AssetPoint, 2_000_000) @@ -2187,6 +2241,7 @@ func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { UserID: 22001, AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, + FeeBPS: 500, }) if err != nil { t.Fatalf("FreezePointWithdrawal failed: %v", err) @@ -2202,6 +2257,7 @@ func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { UserID: 22001, AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, + FeeBPS: 500, OperatorUserID: 90001, WithdrawalApplicationID: "77", }) @@ -2219,6 +2275,7 @@ func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { UserID: 22002, AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, + FeeBPS: 500, }); err != nil { t.Fatalf("FreezePointWithdrawal for release failed: %v", err) } @@ -2228,6 +2285,7 @@ func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { UserID: 22002, AssetType: ledger.AssetPoint, GrossPointAmount: 1_000_000, + FeeBPS: 500, WithdrawalApplicationID: "78", }) if err != nil { @@ -2239,6 +2297,52 @@ func TestPointWithdrawalFreezeSettleReleaseIsHuwaaOnly(t *testing.T) { requireWalletBalanceForApp(t, svc, "huwaa", 22002, ledger.AssetPoint, 2_000_000, 0) } +// TestTransferPointToCoinSellerUsesServerWhitelist 验证 H5 不能自报比例,wallet 会按 App、国家和 active 配置原子扣 POINT/加币商库存。 +func TestTransferPointToCoinSellerUsesServerWhitelist(t *testing.T) { + repository := mysqltest.NewRepository(t) + repository.SetAssetBalanceForApp("fami", 22501, ledger.AssetPoint, 2_000_000) + repository.SetPointWithdrawalCoinSellerConfig("fami", 22502, 100_000, 92_000, []string{"SA"}, "active", 1) + svc := walletservice.New(repository) + + sellers, err := svc.ListPointWithdrawalCoinSellers(context.Background(), "fami", "SA", false) + if err != nil || len(sellers) != 1 || sellers[0].SellerUserID != 22502 { + t.Fatalf("eligible point withdrawal sellers mismatch: sellers=%+v err=%v", sellers, err) + } + if blocked, err := svc.ListPointWithdrawalCoinSellers(context.Background(), "fami", "TR", false); err != nil || len(blocked) != 0 { + t.Fatalf("country-filtered seller must be hidden: sellers=%+v err=%v", blocked, err) + } + + command := ledger.PointToCoinSellerCommand{ + AppCode: "fami", CommandID: "cmd-fami-point-seller-1", SourceUserID: 22501, + SellerUserID: 22502, PointAmount: 1_000_000, SourceCountryCode: "SA", Reason: "withdraw to seller", + } + receipt, err := svc.TransferPointToCoinSeller(context.Background(), command) + if err != nil { + t.Fatalf("TransferPointToCoinSeller failed: %v", err) + } + if receipt.SellerCoinAmount != 920_000 || receipt.RatioPointAmount != 100_000 || receipt.RatioSellerCoinAmount != 92_000 || receipt.SourcePointBalanceAfter != 1_000_000 || receipt.SellerBalanceAfter != 920_000 { + t.Fatalf("point seller transfer receipt mismatch: %+v", receipt) + } + replayed, err := svc.TransferPointToCoinSeller(context.Background(), command) + if err != nil || replayed.TransactionID != receipt.TransactionID || replayed.SellerCoinAmount != receipt.SellerCoinAmount { + t.Fatalf("point seller transfer replay mismatch: replay=%+v err=%v", replayed, err) + } + requireWalletBalanceForApp(t, svc, "fami", 22501, ledger.AssetPoint, 1_000_000, 0) + requireWalletBalanceForApp(t, svc, "fami", 22502, ledger.AssetCoinSellerCoin, 920_000, 0) + if got := repository.CountRows("wallet_transactions", "app_code = ? AND biz_type = ?", "fami", "point_transfer_to_coin_seller"); got != 1 { + t.Fatalf("idempotent point seller transfer must write one transaction, got %d", got) + } + + _, err = svc.TransferPointToCoinSeller(context.Background(), ledger.PointToCoinSellerCommand{ + AppCode: "fami", CommandID: "cmd-fami-point-seller-country-denied", SourceUserID: 22501, + SellerUserID: 22502, PointAmount: 100_000, SourceCountryCode: "TR", + }) + if err == nil { + t.Fatal("seller country restriction must reject transfer") + } + requireWalletBalanceForApp(t, svc, "fami", 22501, ledger.AssetPoint, 1_000_000, 0) +} + // TestCreditLuckyGiftRewardIsIdempotent 验证幸运礼物返奖只按 draw_id 派一次,并产出余额通知事实。 func TestCreditLuckyGiftRewardIsIdempotent(t *testing.T) { repository := mysqltest.NewRepository(t) diff --git a/services/wallet-service/internal/storage/mysql/agency_host_gift_stats.go b/services/wallet-service/internal/storage/mysql/agency_host_gift_stats.go new file mode 100644 index 00000000..82c6f49d --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/agency_host_gift_stats.go @@ -0,0 +1,43 @@ +package mysql + +import ( + "context" + "fmt" + "strings" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// GetAgencyHostGiftStats 直接读取送礼交易里的 host_point_added 快照,只统计礼物收益; +// 任务奖励、提现释放和 Agency 分成虽然也进入 POINT 账户,但都不能混入 BD 的公会收礼口径。 +func (r *Repository) GetAgencyHostGiftStats(ctx context.Context, query ledger.AgencyHostGiftStatsQuery) (ledger.AgencyHostGiftStats, error) { + if r == nil || r.db == nil { + return ledger.AgencyHostGiftStats{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + if len(query.HostUserIDs) == 0 { + return ledger.AgencyHostGiftStats{}, nil + } + placeholders := make([]string, len(query.HostUserIDs)) + args := make([]any, 0, len(query.HostUserIDs)+5) + args = append(args, appcode.FromContext(ctx), bizTypeGiftDebit, bizTypeDirectGiftDebit, query.StartAtMS, query.EndAtMS) + for index, userID := range query.HostUserIDs { + placeholders[index] = "?" + args = append(args, userID) + } + querySQL := fmt.Sprintf(` + SELECT + COALESCE(SUM(CAST(COALESCE(JSON_UNQUOTE(JSON_EXTRACT(metadata_json, '$.host_point_added')), '0') AS SIGNED)), 0), + COUNT(DISTINCT CASE + WHEN CAST(COALESCE(JSON_UNQUOTE(JSON_EXTRACT(metadata_json, '$.host_point_added')), '0') AS SIGNED) > 0 + THEN CAST(JSON_UNQUOTE(JSON_EXTRACT(metadata_json, '$.target_user_id')) AS SIGNED) + END) + FROM wallet_transactions + WHERE app_code = ? AND biz_type IN (?, ?) AND status = 'succeeded' + AND created_at_ms >= ? AND created_at_ms < ? + AND CAST(JSON_UNQUOTE(JSON_EXTRACT(metadata_json, '$.target_user_id')) AS SIGNED) IN (%s)`, strings.Join(placeholders, ",")) + var stats ledger.AgencyHostGiftStats + err := r.db.QueryRowContext(ctx, querySQL, args...).Scan(&stats.GiftIncome, &stats.GiftedHostCount) + return stats, err +} diff --git a/services/wallet-service/internal/storage/mysql/agency_point_share.go b/services/wallet-service/internal/storage/mysql/agency_point_share.go new file mode 100644 index 00000000..4af3beea --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/agency_point_share.go @@ -0,0 +1,26 @@ +package mysql + +import ( + "context" + "database/sql" + + "hyapp/pkg/appcode" +) + +// insertAgencyPointShare 把“当时属于哪个 Agency”与实际入账金额固化在同一送礼事务内; +// 后续主播转会时统计仍按这条快照归属,不能用当前成员关系重算历史收入。 +func (r *Repository) insertAgencyPointShare(ctx context.Context, tx *sql.Tx, transactionID string, metadata giftMetadata, nowMS int64) error { + if metadata.AgencyPointAdded <= 0 || metadata.TargetAgencyOwnerUserID <= 0 { + return nil + } + _, err := tx.ExecContext(ctx, ` + INSERT INTO agency_point_share_entries ( + app_code, transaction_id, host_user_id, agency_owner_user_id, sender_user_id, + room_id, point_delta, ratio_ppm, policy_instance_code, created_at_ms + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + appcode.FromContext(ctx), transactionID, metadata.TargetUserID, metadata.TargetAgencyOwnerUserID, + metadata.SenderUserID, metadata.RoomID, metadata.AgencyPointAdded, metadata.AgencyPointRatioPPM, + metadata.HostPointPolicyInstanceCode, nowMS, + ) + return err +} diff --git a/services/wallet-service/internal/storage/mysql/agency_point_share_stats.go b/services/wallet-service/internal/storage/mysql/agency_point_share_stats.go new file mode 100644 index 00000000..39ae7404 --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/agency_point_share_stats.go @@ -0,0 +1,25 @@ +package mysql + +import ( + "context" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// GetAgencyPointShareStats 按入账时归属快照统计,不受主播之后转会或被移除影响。 +func (r *Repository) GetAgencyPointShareStats(ctx context.Context, query ledger.AgencyPointShareStatsQuery) (ledger.AgencyPointShareStats, error) { + if r == nil || r.db == nil { + return ledger.AgencyPointShareStats{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + var stats ledger.AgencyPointShareStats + err := r.db.QueryRowContext(ctx, ` + SELECT COALESCE(SUM(point_delta), 0), COUNT(DISTINCT host_user_id) + FROM agency_point_share_entries + WHERE app_code = ? AND agency_owner_user_id = ? + AND created_at_ms >= ? AND created_at_ms < ?`, + appcode.FromContext(ctx), query.AgencyOwnerUserID, query.StartAtMS, query.EndAtMS, + ).Scan(&stats.ShareIncome, &stats.GiftedHostCount) + return stats, err +} diff --git a/services/wallet-service/internal/storage/mysql/agency_point_share_stats_test.go b/services/wallet-service/internal/storage/mysql/agency_point_share_stats_test.go new file mode 100644 index 00000000..4d0e0b2f --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/agency_point_share_stats_test.go @@ -0,0 +1,40 @@ +package mysql + +import ( + "context" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "hyapp/pkg/appcode" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +func TestGetAgencyPointShareStatsUsesOwnershipSnapshot(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("create sqlmock: %v", err) + } + defer db.Close() + mock.ExpectQuery(regexp.QuoteMeta(` + SELECT COALESCE(SUM(point_delta), 0), COUNT(DISTINCT host_user_id) + FROM agency_point_share_entries + WHERE app_code = ? AND agency_owner_user_id = ? + AND created_at_ms >= ? AND created_at_ms < ?`)). + WithArgs("fami", int64(73), int64(1000), int64(2000)). + WillReturnRows(sqlmock.NewRows([]string{"share_income", "gifted_hosts"}).AddRow(int64(2400), int64(3))) + + repo := &Repository{db: db} + stats, err := repo.GetAgencyPointShareStats(appcode.WithContext(context.Background(), "fami"), ledger.AgencyPointShareStatsQuery{ + AgencyOwnerUserID: 73, StartAtMS: 1000, EndAtMS: 2000, + }) + if err != nil { + t.Fatalf("GetAgencyPointShareStats failed: %v", err) + } + if stats.ShareIncome != 2400 || stats.GiftedHostCount != 3 { + t.Fatalf("unexpected agency stats: %+v", stats) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Fatalf("unmet SQL expectations: %v", err) + } +} diff --git a/services/wallet-service/internal/storage/mysql/constants.go b/services/wallet-service/internal/storage/mysql/constants.go index d2be5e2f..32b9924c 100644 --- a/services/wallet-service/internal/storage/mysql/constants.go +++ b/services/wallet-service/internal/storage/mysql/constants.go @@ -19,6 +19,7 @@ const ( bizTypeCoinSellerCoinCompensation = "coin_seller_coin_compensation" bizTypeSalaryExchangeToCoin = "salary_exchange_to_coin" bizTypeSalaryTransferToCoinSeller = "salary_transfer_to_coin_seller" + bizTypePointTransferToCoinSeller = "point_transfer_to_coin_seller" bizTypeSalaryWithdrawalFreeze = "salary_withdrawal_freeze" bizTypeSalaryWithdrawalSettle = "salary_withdrawal_settle" bizTypeSalaryWithdrawalRelease = "salary_withdrawal_release" diff --git a/services/wallet-service/internal/storage/mysql/gift_batch_debit_repository.go b/services/wallet-service/internal/storage/mysql/gift_batch_debit_repository.go index 6d91b583..2c6af529 100644 --- a/services/wallet-service/internal/storage/mysql/gift_batch_debit_repository.go +++ b/services/wallet-service/internal/storage/mysql/gift_batch_debit_repository.go @@ -112,10 +112,12 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb } type targetHostPointPolicy struct { - policy walletPolicyInstance - amount int64 - userID int64 - active bool + policy walletPolicyInstance + amount int64 + userID int64 + agencyAmount int64 + agencyOwnerUserID int64 + active bool } hostPointPolicies := make(map[string]targetHostPointPolicy, len(command.Targets)) if chargeSource != giftChargeSourceBag { @@ -139,7 +141,21 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb if err != nil { return ledger.BatchGiftReceipt{}, err } - hostPointPolicies[target.CommandID] = targetHostPointPolicy{policy: policy, amount: amount, userID: target.TargetUserID, active: true} + agencyAmount := int64(0) + if target.TargetAgencyOwnerUserID > 0 && policy.AgencyPointRatioPPM > 0 { + agencyAmount, err = giftDiamondAmount(chargeAmount, policy.AgencyPointRatioPPM) + if err != nil { + return ledger.BatchGiftReceipt{}, err + } + } + hostPointPolicies[target.CommandID] = targetHostPointPolicy{ + policy: policy, + amount: amount, + userID: target.TargetUserID, + agencyAmount: agencyAmount, + agencyOwnerUserID: target.TargetAgencyOwnerUserID, + active: true, + } } } @@ -170,6 +186,13 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb AssetType: ledger.AssetPoint, CreateIfMissing: true, }) + if hostPointPolicy.agencyAmount > 0 { + lockRequests = append(lockRequests, walletAccountLockRequest{ + UserID: hostPointPolicy.agencyOwnerUserID, + AssetType: ledger.AssetPoint, + CreateIfMissing: true, + }) + } } accountStates, err := r.lockAccountsOrdered(ctx, tx, lockRequests, nowMs) if err != nil { @@ -267,6 +290,18 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb } hostPointBalanceAfter = targetPointState.account.AvailableAmount + hostPointPolicy.amount } + agencyPointBalanceAfter := int64(0) + var agencyPointState *walletAccountState + if hostPointPolicy.agencyAmount > 0 { + agencyPointState = accountStates[walletAccountLockKey(hostPointPolicy.agencyOwnerUserID, ledger.AssetPoint)] + if agencyPointState == nil { + return ledger.BatchGiftReceipt{}, xerr.New(xerr.Internal, "agency point account is missing") + } + agencyPointBalanceAfter = agencyPointState.account.AvailableAmount + hostPointPolicy.agencyAmount + if agencyPointState == targetPointState { + agencyPointBalanceAfter += hostPointPolicy.amount + } + } // 批量事务逐目标生成独立账务交易;这里从当前 sender 版本预测本目标完成后的版本, // 下一轮会读取已推进的 senderState,因此最后一条回执自然代表整批最终版本。 senderBalanceVersionAfter := giftSenderBalanceVersionAfter( @@ -322,6 +357,9 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb HostPointTemplateCode: hostPointPolicy.policy.TemplateCode, HostPointTemplateVersion: hostPointPolicy.policy.TemplateVersion, HostPointRatioPPM: hostPointPolicy.policy.HostPointRatioPPM, + AgencyPointAdded: hostPointPolicy.agencyAmount, + AgencyPointBalanceAfter: agencyPointBalanceAfter, + AgencyPointRatioPPM: hostPointPolicy.policy.AgencyPointRatioPPM, PointsPerUSD: hostPointPolicy.policy.PointsPerUSD, RoomID: command.RoomID, RoomRegionID: command.RegionID, @@ -404,6 +442,29 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb return ledger.BatchGiftReceipt{}, err } } + if hostPointPolicy.agencyAmount > 0 { + agencyPointAccount, err := r.applyTrackedAccountDelta(ctx, tx, agencyPointState, hostPointPolicy.agencyAmount, 0, nowMs) + if err != nil { + return ledger.BatchGiftReceipt{}, err + } + metadata.AgencyPointBalanceAfter = agencyPointAccount.AvailableAmount + if err := r.insertEntry(ctx, tx, walletEntry{ + TransactionID: transactionID, + UserID: hostPointPolicy.agencyOwnerUserID, + AssetType: ledger.AssetPoint, + AvailableDelta: hostPointPolicy.agencyAmount, + AvailableAfter: agencyPointAccount.AvailableAmount, + FrozenAfter: agencyPointAccount.FrozenAmount, + CounterpartyUserID: command.SenderUserID, + RoomID: command.RoomID, + CreatedAtMS: nowMs, + }); err != nil { + return ledger.BatchGiftReceipt{}, err + } + if err := r.insertAgencyPointShare(ctx, tx, transactionID, metadata, nowMs); err != nil { + return ledger.BatchGiftReceipt{}, err + } + } if hostPeriodDiamondAdded > 0 { hostPeriodDiamondAfter, hostPeriodDiamondVersion, err := r.creditHostPeriodDiamonds(ctx, tx, transactionID, target.CommandID, metadata, nowMs) if err != nil { @@ -439,6 +500,10 @@ func (r *Repository) BatchDebitGift(ctx context.Context, command ledger.BatchDeb events = append(events, balanceChangedEvent(transactionID, target.CommandID, target.TargetUserID, ledger.AssetPoint, hostPointPolicy.amount, 0, metadata.HostPointBalanceAfter, targetPointState.account.FrozenAmount, targetPointState.account.Version, metadata, nowMs, bizTypeGiftDebit)) events = append(events, hostPointCreditedEvent(transactionID, target.CommandID, metadata, nowMs)) } + if hostPointPolicy.agencyAmount > 0 { + events = append(events, balanceChangedEvent(transactionID, target.CommandID, hostPointPolicy.agencyOwnerUserID, ledger.AssetPoint, hostPointPolicy.agencyAmount, 0, metadata.AgencyPointBalanceAfter, agencyPointState.account.FrozenAmount, agencyPointState.account.Version, metadata, nowMs, bizTypeGiftDebit)) + events = append(events, agencyPointCreditedEvent(transactionID, target.CommandID, metadata, nowMs)) + } if hostPeriodDiamondAdded > 0 { events = append(events, hostPeriodDiamondCreditedEvent(transactionID, target.CommandID, metadata, nowMs)) } diff --git a/services/wallet-service/internal/storage/mysql/gift_debit_repository.go b/services/wallet-service/internal/storage/mysql/gift_debit_repository.go index 114baed6..ec7ee941 100644 --- a/services/wallet-service/internal/storage/mysql/gift_debit_repository.go +++ b/services/wallet-service/internal/storage/mysql/gift_debit_repository.go @@ -90,6 +90,7 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm } } hostPointAdded := int64(0) + agencyPointAdded := int64(0) hostPointPolicy := walletPolicyInstance{} hostPointPolicyActive := false hostPointRegionID := command.TargetHostRegionID @@ -109,6 +110,13 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm } // 命中新政策后不再给主播走旧 COIN 返还,避免同一笔礼物同时产生 COIN 收礼返还和 POINT 收益。 giftIncomeCoinAmount = 0 + if command.TargetAgencyOwnerUserID > 0 && hostPointPolicy.AgencyPointRatioPPM > 0 { + // Agency 分成只跟随服务端注入的送礼时归属快照,客户端不能指定;自送礼同样属于有效付费礼物。 + agencyPointAdded, err = giftDiamondAmount(chargeAmount, hostPointPolicy.AgencyPointRatioPPM) + if err != nil { + return ledger.Receipt{}, err + } + } } } hostPeriodDiamondAdded := int64(0) @@ -137,6 +145,7 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm var senderState *walletAccountState var targetCoinState *walletAccountState var targetPointState *walletAccountState + var agencyPointState *walletAccountState if command.RobotGift { sender, err := r.lockAccount(ctx, tx, command.SenderUserID, accountAssetType, true, nowMs) @@ -164,6 +173,13 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm CreateIfMissing: true, }) } + if agencyPointAdded > 0 { + lockRequests = append(lockRequests, walletAccountLockRequest{ + UserID: command.TargetAgencyOwnerUserID, + AssetType: ledger.AssetPoint, + CreateIfMissing: true, + }) + } states, err := r.lockAccountsOrdered(ctx, tx, lockRequests, nowMs) if err != nil { return ledger.Receipt{}, err @@ -175,6 +191,9 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm if hostPointAdded > 0 { targetPointState = states[walletAccountLockKey(command.TargetUserID, ledger.AssetPoint)] } + if agencyPointAdded > 0 { + agencyPointState = states[walletAccountLockKey(command.TargetAgencyOwnerUserID, ledger.AssetPoint)] + } } sender := senderState.account robotCoinTopUp := int64(0) @@ -209,6 +228,16 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm } hostPointBalanceAfter = targetPointState.account.AvailableAmount + hostPointAdded } + agencyPointBalanceAfter := int64(0) + if agencyPointAdded > 0 { + if agencyPointState == nil { + return ledger.Receipt{}, xerr.New(xerr.Internal, "agency point account is missing") + } + agencyPointBalanceAfter = agencyPointState.account.AvailableAmount + agencyPointAdded + if agencyPointState == targetPointState { + agencyPointBalanceAfter += hostPointAdded + } + } transactionID := transactionID(command.AppCode, command.CommandID) // metadata 在账户更新前写入交易表,因此版本必须按本事务即将执行的 sender 分录精确预测; // 事务内实际更新仍由 wallet_accounts.version 乐观锁裁决,失败会整体回滚该预测值。 @@ -265,6 +294,9 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm HostPointTemplateCode: hostPointPolicy.TemplateCode, HostPointTemplateVersion: hostPointPolicy.TemplateVersion, HostPointRatioPPM: hostPointPolicy.HostPointRatioPPM, + AgencyPointAdded: agencyPointAdded, + AgencyPointBalanceAfter: agencyPointBalanceAfter, + AgencyPointRatioPPM: hostPointPolicy.AgencyPointRatioPPM, PointsPerUSD: hostPointPolicy.PointsPerUSD, RoomID: command.RoomID, RoomRegionID: command.RegionID, @@ -378,6 +410,29 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm return ledger.Receipt{}, err } } + if agencyPointAdded > 0 { + agencyPointAccount, err := r.applyTrackedAccountDelta(ctx, tx, agencyPointState, agencyPointAdded, 0, nowMs) + if err != nil { + return ledger.Receipt{}, err + } + metadata.AgencyPointBalanceAfter = agencyPointAccount.AvailableAmount + if err := r.insertEntry(ctx, tx, walletEntry{ + TransactionID: transactionID, + UserID: command.TargetAgencyOwnerUserID, + AssetType: ledger.AssetPoint, + AvailableDelta: agencyPointAdded, + AvailableAfter: agencyPointAccount.AvailableAmount, + FrozenAfter: agencyPointAccount.FrozenAmount, + CounterpartyUserID: command.SenderUserID, + RoomID: command.RoomID, + CreatedAtMS: nowMs, + }); err != nil { + return ledger.Receipt{}, err + } + if err := r.insertAgencyPointShare(ctx, tx, transactionID, metadata, nowMs); err != nil { + return ledger.Receipt{}, err + } + } if hostPeriodDiamondAdded > 0 { hostPeriodDiamondAfter, hostPeriodDiamondVersion, err := r.creditHostPeriodDiamonds(ctx, tx, transactionID, command.CommandID, metadata, nowMs) @@ -417,6 +472,10 @@ func (r *Repository) DebitGift(ctx context.Context, command ledger.DebitGiftComm events = append(events, balanceChangedEvent(transactionID, command.CommandID, command.TargetUserID, ledger.AssetPoint, hostPointAdded, 0, metadata.HostPointBalanceAfter, targetPointState.account.FrozenAmount, targetPointState.account.Version, metadata, nowMs, bizType)) events = append(events, hostPointCreditedEvent(transactionID, command.CommandID, metadata, nowMs)) } + if agencyPointAdded > 0 { + events = append(events, balanceChangedEvent(transactionID, command.CommandID, command.TargetAgencyOwnerUserID, ledger.AssetPoint, agencyPointAdded, 0, metadata.AgencyPointBalanceAfter, agencyPointState.account.FrozenAmount, agencyPointState.account.Version, metadata, nowMs, bizType)) + events = append(events, agencyPointCreditedEvent(transactionID, command.CommandID, metadata, nowMs)) + } } if hostPeriodDiamondAdded > 0 { events = append(events, hostPeriodDiamondCreditedEvent(transactionID, command.CommandID, metadata, nowMs)) diff --git a/services/wallet-service/internal/storage/mysql/host_revenue_stats.go b/services/wallet-service/internal/storage/mysql/host_revenue_stats.go new file mode 100644 index 00000000..e4a0823d --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/host_revenue_stats.go @@ -0,0 +1,31 @@ +package mysql + +import ( + "context" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// GetHostRevenueStats 聚合 POINT 分录;兑换按 available 侧冻结扣减计数,审核结算不会再次累计。 +func (r *Repository) GetHostRevenueStats(ctx context.Context, query ledger.HostRevenueStatsQuery) (ledger.HostRevenueStats, error) { + if r == nil || r.db == nil { + return ledger.HostRevenueStats{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + var stats ledger.HostRevenueStats + err := r.db.QueryRowContext(ctx, ` + SELECT + COALESCE(SUM(CASE WHEN e.available_delta > 0 AND t.biz_type <> ? THEN e.available_delta ELSE 0 END), 0), + COALESCE(SUM(CASE WHEN e.available_delta < 0 THEN -e.available_delta ELSE 0 END), 0), + COUNT(DISTINCT CASE WHEN e.available_delta > 0 AND e.counterparty_user_id > 0 THEN e.counterparty_user_id END) + FROM wallet_entries e + INNER JOIN wallet_transactions t + ON t.app_code = e.app_code AND t.transaction_id = e.transaction_id + WHERE e.app_code = ? AND e.user_id = ? AND e.asset_type = ? + AND e.created_at_ms >= ? AND e.created_at_ms < ?`, + bizTypeSalaryWithdrawalRelease, + appcode.FromContext(ctx), query.HostUserID, ledger.AssetPoint, query.StartAtMS, query.EndAtMS, + ).Scan(&stats.DiamondEarnings, &stats.DiamondExchanged, &stats.GiftSenders) + return stats, err +} diff --git a/services/wallet-service/internal/storage/mysql/host_revenue_stats_test.go b/services/wallet-service/internal/storage/mysql/host_revenue_stats_test.go new file mode 100644 index 00000000..426dacfc --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/host_revenue_stats_test.go @@ -0,0 +1,48 @@ +package mysql + +import ( + "context" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "hyapp/pkg/appcode" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +func TestGetHostRevenueStatsAggregatesPointLedger(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("create sqlmock: %v", err) + } + defer db.Close() + + mock.ExpectQuery(regexp.QuoteMeta(` + SELECT + COALESCE(SUM(CASE WHEN e.available_delta > 0 AND t.biz_type <> ? THEN e.available_delta ELSE 0 END), 0), + COALESCE(SUM(CASE WHEN e.available_delta < 0 THEN -e.available_delta ELSE 0 END), 0), + COUNT(DISTINCT CASE WHEN e.available_delta > 0 AND e.counterparty_user_id > 0 THEN e.counterparty_user_id END) + FROM wallet_entries e + INNER JOIN wallet_transactions t + ON t.app_code = e.app_code AND t.transaction_id = e.transaction_id + WHERE e.app_code = ? AND e.user_id = ? AND e.asset_type = ? + AND e.created_at_ms >= ? AND e.created_at_ms < ?`)). + WithArgs(bizTypeSalaryWithdrawalRelease, "fami", int64(42), ledger.AssetPoint, int64(1000), int64(2000)). + WillReturnRows(sqlmock.NewRows([]string{"earnings", "exchanged", "senders"}).AddRow(int64(8800), int64(1200), int64(7))) + + repo := &Repository{db: db} + stats, err := repo.GetHostRevenueStats(appcode.WithContext(context.Background(), "fami"), ledger.HostRevenueStatsQuery{ + HostUserID: 42, + StartAtMS: 1000, + EndAtMS: 2000, + }) + if err != nil { + t.Fatalf("GetHostRevenueStats failed: %v", err) + } + if stats.DiamondEarnings != 8800 || stats.DiamondExchanged != 1200 || stats.GiftSenders != 7 { + t.Fatalf("unexpected host revenue stats: %+v", stats) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Fatalf("unmet SQL expectations: %v", err) + } +} diff --git a/services/wallet-service/internal/storage/mysql/metadata.go b/services/wallet-service/internal/storage/mysql/metadata.go index ae586759..4ec68068 100644 --- a/services/wallet-service/internal/storage/mysql/metadata.go +++ b/services/wallet-service/internal/storage/mysql/metadata.go @@ -56,6 +56,9 @@ type giftMetadata struct { HostPointTemplateCode string `json:"host_point_template_code,omitempty"` HostPointTemplateVersion string `json:"host_point_template_version,omitempty"` HostPointRatioPPM int64 `json:"host_point_ratio_ppm,omitempty"` + AgencyPointAdded int64 `json:"agency_point_added,omitempty"` + AgencyPointBalanceAfter int64 `json:"agency_point_balance_after,omitempty"` + AgencyPointRatioPPM int64 `json:"agency_point_ratio_ppm,omitempty"` PointsPerUSD int64 `json:"points_per_usd,omitempty"` RoomID string `json:"room_id"` RoomRegionID int64 `json:"room_region_id"` diff --git a/services/wallet-service/internal/storage/mysql/outbox.go b/services/wallet-service/internal/storage/mysql/outbox.go index 3232dfc7..c96be517 100644 --- a/services/wallet-service/internal/storage/mysql/outbox.go +++ b/services/wallet-service/internal/storage/mysql/outbox.go @@ -792,3 +792,37 @@ func hostPointCreditedEvent(transactionID string, commandID string, metadata gif CreatedAtMS: nowMs, } } + +func agencyPointCreditedEvent(transactionID string, commandID string, metadata giftMetadata, nowMs int64) walletOutboxEvent { + return walletOutboxEvent{ + EventID: eventID(transactionID, "AgencyPointCredited", metadata.TargetAgencyOwnerUserID, ledger.AssetPoint), + EventType: "AgencyPointCredited", + TransactionID: transactionID, + CommandID: commandID, + UserID: metadata.TargetAgencyOwnerUserID, + AssetType: ledger.AssetPoint, + AvailableDelta: metadata.AgencyPointAdded, + FrozenDelta: 0, + Payload: map[string]any{ + "transaction_id": transactionID, + "command_id": commandID, + "host_user_id": metadata.TargetUserID, + "agency_owner_user_id": metadata.TargetAgencyOwnerUserID, + "sender_user_id": metadata.SenderUserID, + "room_id": metadata.RoomID, + "asset_type": ledger.AssetPoint, + "point_delta": metadata.AgencyPointAdded, + "point_balance_after": metadata.AgencyPointBalanceAfter, + "gift_charge_asset_type": metadata.ChargeAssetType, + "gift_charge_amount": metadata.ChargeAmount, + "gift_id": metadata.GiftID, + "gift_count": metadata.GiftCount, + "policy_instance_code": metadata.HostPointPolicyInstanceCode, + "policy_template_code": metadata.HostPointTemplateCode, + "policy_template_version": metadata.HostPointTemplateVersion, + "agency_point_ratio_ppm": metadata.AgencyPointRatioPPM, + "created_at_ms": nowMs, + }, + CreatedAtMS: nowMs, + } +} diff --git a/services/wallet-service/internal/storage/mysql/point_coin_seller.go b/services/wallet-service/internal/storage/mysql/point_coin_seller.go new file mode 100644 index 00000000..37a0156e --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/point_coin_seller.go @@ -0,0 +1,268 @@ +package mysql + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +const pointWithdrawalMinimumPoints int64 = 1_000_000 + +type pointToCoinSellerMetadata struct { + AppCode string `json:"app_code"` + SourceUserID int64 `json:"source_user_id"` + SellerUserID int64 `json:"seller_user_id"` + SourceCountryCode string `json:"source_country_code"` + SourceAssetType string `json:"source_asset_type"` + SellerAssetType string `json:"seller_asset_type"` + PointAmount int64 `json:"point_amount"` + SellerCoinAmount int64 `json:"seller_coin_amount"` + RatioPointAmount int64 `json:"ratio_point_amount"` + RatioSellerCoinAmount int64 `json:"ratio_seller_coin_amount"` + SourcePointBalanceAfter int64 `json:"source_point_balance_after"` + SellerBalanceAfter int64 `json:"seller_balance_after"` + Reason string `json:"reason"` + CreatedAtMS int64 `json:"created_at_ms"` +} + +// ListPointWithdrawalCoinSellers 返回当前 App 的白名单;国家过滤在 wallet 内执行,gateway 不能绕过服务范围。 +func (r *Repository) ListPointWithdrawalCoinSellers(ctx context.Context, appCode string, countryCode string, includeDisabled bool) ([]ledger.PointWithdrawalCoinSellerConfig, error) { + if r == nil || r.db == nil { + return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + ctx = contextWithCommandApp(ctx, appCode) + where := "app_code = ?" + args := []any{appcode.FromContext(ctx)} + if !includeDisabled { + where += " AND status = 'active'" + } + rows, err := r.db.QueryContext(ctx, ` + SELECT app_code, seller_user_id, sort_order, point_amount, seller_coin_amount, + service_country_codes, status, created_at_ms, updated_at_ms + FROM point_withdrawal_coin_seller_configs + WHERE `+where+` + ORDER BY sort_order ASC, seller_user_id ASC`, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + countryCode = strings.ToUpper(strings.TrimSpace(countryCode)) + items := make([]ledger.PointWithdrawalCoinSellerConfig, 0) + for rows.Next() { + var item ledger.PointWithdrawalCoinSellerConfig + var countriesJSON []byte + if err := rows.Scan(&item.AppCode, &item.SellerUserID, &item.SortOrder, &item.PointAmount, &item.SellerCoinAmount, &countriesJSON, &item.Status, &item.CreatedAtMS, &item.UpdatedAtMS); err != nil { + return nil, err + } + if err := json.Unmarshal(countriesJSON, &item.ServiceCountryCodes); err != nil { + return nil, xerr.New(xerr.Internal, "point withdrawal seller country config is invalid") + } + item.ServiceCountryCodes = normalizeCountryCodes(item.ServiceCountryCodes) + if item.PointAmount <= 0 || item.SellerCoinAmount <= 0 { + return nil, xerr.New(xerr.Internal, "point withdrawal seller ratio is invalid") + } + if countryCode != "" && !countryAllowed(item.ServiceCountryCodes, countryCode) { + continue + } + items = append(items, item) + } + return items, rows.Err() +} + +// TransferPointToCoinSeller 在一个事务中锁定白名单配置和双方账户;任何比例更新只影响新 command_id。 +func (r *Repository) TransferPointToCoinSeller(ctx context.Context, command ledger.PointToCoinSellerCommand) (ledger.PointToCoinSellerReceipt, error) { + if r == nil || r.db == nil { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + ctx = contextWithCommandApp(ctx, command.AppCode) + command.AppCode = appcode.FromContext(ctx) + tx, err := r.db.BeginTx(ctx, nil) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + defer func() { _ = tx.Rollback() }() + + requestHash := stableHash(fmt.Sprintf("point_transfer_coin_seller|%s|%d|%d|%d|%s|%s", + command.AppCode, command.SourceUserID, command.SellerUserID, command.PointAmount, + strings.ToUpper(strings.TrimSpace(command.SourceCountryCode)), strings.TrimSpace(command.Reason))) + if txRow, exists, lookupErr := r.lookupTransactionWithConflictCode(ctx, tx, command.CommandID, requestHash, bizTypePointTransferToCoinSeller, xerr.IdempotencyConflict); lookupErr != nil || exists { + if lookupErr != nil || !exists { + return ledger.PointToCoinSellerReceipt{}, lookupErr + } + return r.receiptForPointToCoinSellerTransaction(ctx, tx, txRow.TransactionID) + } + + config, err := r.lockPointWithdrawalCoinSellerConfig(ctx, tx, command.SellerUserID) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + countryCode := strings.ToUpper(strings.TrimSpace(command.SourceCountryCode)) + if !countryAllowed(config.ServiceCountryCodes, countryCode) { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.PermissionDenied, "coin seller does not serve user country") + } + numerator, err := checkedMul(command.PointAmount, config.SellerCoinAmount) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + sellerCoinAmount := numerator / config.PointAmount + if sellerCoinAmount <= 0 { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.InvalidArgument, "point amount is below exchange precision") + } + + nowMS := time.Now().UnixMilli() + source, err := r.lockAccount(ctx, tx, command.SourceUserID, ledger.AssetPoint, false, nowMS) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if source.AvailableAmount < command.PointAmount { + return ledger.PointToCoinSellerReceipt{}, xerr.New(xerr.InsufficientBalance, "insufficient POINT balance") + } + seller, err := r.lockAccount(ctx, tx, command.SellerUserID, ledger.AssetCoinSellerCoin, true, nowMS) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + sourceAfter := source.AvailableAmount - command.PointAmount + sellerAfter, err := checkedAdd(seller.AvailableAmount, sellerCoinAmount) + if err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + transactionID := transactionID(command.AppCode, command.CommandID) + metadata := pointToCoinSellerMetadata{ + AppCode: command.AppCode, SourceUserID: command.SourceUserID, SellerUserID: command.SellerUserID, + SourceCountryCode: countryCode, SourceAssetType: ledger.AssetPoint, SellerAssetType: ledger.AssetCoinSellerCoin, + PointAmount: command.PointAmount, SellerCoinAmount: sellerCoinAmount, + RatioPointAmount: config.PointAmount, RatioSellerCoinAmount: config.SellerCoinAmount, + SourcePointBalanceAfter: sourceAfter, SellerBalanceAfter: sellerAfter, Reason: command.Reason, CreatedAtMS: nowMS, + } + if err := r.insertTransaction(ctx, tx, transactionID, command.CommandID, bizTypePointTransferToCoinSeller, requestHash, fmt.Sprintf("point_coin_seller:%d:%d", command.SourceUserID, command.SellerUserID), metadata, nowMS); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := r.applyAccountDelta(ctx, tx, source, -command.PointAmount, 0, nowMS); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := r.insertEntry(ctx, tx, walletEntry{TransactionID: transactionID, UserID: command.SourceUserID, AssetType: ledger.AssetPoint, AvailableDelta: -command.PointAmount, AvailableAfter: sourceAfter, FrozenAfter: source.FrozenAmount, CounterpartyUserID: command.SellerUserID, CreatedAtMS: nowMS}); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := r.applyAccountDelta(ctx, tx, seller, sellerCoinAmount, 0, nowMS); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := r.insertEntry(ctx, tx, walletEntry{TransactionID: transactionID, UserID: command.SellerUserID, AssetType: ledger.AssetCoinSellerCoin, AvailableDelta: sellerCoinAmount, AvailableAfter: sellerAfter, FrozenAfter: seller.FrozenAmount, CounterpartyUserID: command.SourceUserID, CreatedAtMS: nowMS}); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := r.insertWalletOutbox(ctx, tx, []walletOutboxEvent{ + balanceChangedEvent(transactionID, command.CommandID, command.SourceUserID, ledger.AssetPoint, -command.PointAmount, 0, sourceAfter, source.FrozenAmount, source.Version+1, metadata, nowMS, bizTypePointTransferToCoinSeller), + balanceChangedEvent(transactionID, command.CommandID, command.SellerUserID, ledger.AssetCoinSellerCoin, sellerCoinAmount, 0, sellerAfter, seller.FrozenAmount, seller.Version+1, metadata, nowMS, bizTypePointTransferToCoinSeller), + }); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + if err := tx.Commit(); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + return receiptFromPointToCoinSellerMetadata(transactionID, metadata), nil +} + +// GetPointWithdrawalConfig 只读取已发布钱包政策;不存在时显式 found=false,gateway 不回退到猜测参数。 +func (r *Repository) GetPointWithdrawalConfig(ctx context.Context, appCode string, regionID int64, nowMS int64) (ledger.PointWithdrawalRuntimeConfig, error) { + if r == nil || r.db == nil { + return ledger.PointWithdrawalRuntimeConfig{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + ctx = contextWithCommandApp(ctx, appCode) + tx, err := r.db.BeginTx(ctx, &sql.TxOptions{ReadOnly: true}) + if err != nil { + return ledger.PointWithdrawalRuntimeConfig{}, err + } + defer func() { _ = tx.Rollback() }() + policy, found, err := r.resolveActiveWalletPolicy(ctx, tx, appcode.FromContext(ctx), regionID, nowMS) + if err != nil || !found { + return ledger.PointWithdrawalRuntimeConfig{Found: false}, err + } + return ledger.PointWithdrawalRuntimeConfig{Found: true, PointsPerUSD: policy.PointsPerUSD, FeeBPS: policy.WithdrawFeeBPS, MinimumPoints: pointWithdrawalMinimumPoints, PolicyInstanceCode: policy.InstanceCode}, nil +} + +func (r *Repository) lockPointWithdrawalCoinSellerConfig(ctx context.Context, tx *sql.Tx, sellerUserID int64) (ledger.PointWithdrawalCoinSellerConfig, error) { + var item ledger.PointWithdrawalCoinSellerConfig + var countriesJSON []byte + err := tx.QueryRowContext(ctx, ` + SELECT app_code, seller_user_id, sort_order, point_amount, seller_coin_amount, + service_country_codes, status, created_at_ms, updated_at_ms + FROM point_withdrawal_coin_seller_configs + WHERE app_code = ? AND seller_user_id = ? AND status = 'active' + FOR UPDATE`, appcode.FromContext(ctx), sellerUserID).Scan( + &item.AppCode, &item.SellerUserID, &item.SortOrder, &item.PointAmount, &item.SellerCoinAmount, + &countriesJSON, &item.Status, &item.CreatedAtMS, &item.UpdatedAtMS, + ) + if errors.Is(err, sql.ErrNoRows) { + return item, xerr.New(xerr.NotFound, "point withdrawal coin seller is not available") + } + if err != nil { + return item, err + } + if err := json.Unmarshal(countriesJSON, &item.ServiceCountryCodes); err != nil || item.PointAmount <= 0 || item.SellerCoinAmount <= 0 { + return item, xerr.New(xerr.Internal, "point withdrawal coin seller config is invalid") + } + item.ServiceCountryCodes = normalizeCountryCodes(item.ServiceCountryCodes) + return item, nil +} + +func (r *Repository) receiptForPointToCoinSellerTransaction(ctx context.Context, tx *sql.Tx, transactionID string) (ledger.PointToCoinSellerReceipt, error) { + var metadataJSON string + if err := tx.QueryRowContext(ctx, `SELECT COALESCE(CAST(metadata_json AS CHAR), '{}') FROM wallet_transactions WHERE app_code = ? AND transaction_id = ?`, appcode.FromContext(ctx), transactionID).Scan(&metadataJSON); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + var metadata pointToCoinSellerMetadata + if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil { + return ledger.PointToCoinSellerReceipt{}, err + } + return receiptFromPointToCoinSellerMetadata(transactionID, metadata), nil +} + +func receiptFromPointToCoinSellerMetadata(transactionID string, metadata pointToCoinSellerMetadata) ledger.PointToCoinSellerReceipt { + return ledger.PointToCoinSellerReceipt{ + TransactionID: transactionID, SourceUserID: metadata.SourceUserID, SellerUserID: metadata.SellerUserID, + SourcePointBalanceAfter: metadata.SourcePointBalanceAfter, SellerBalanceAfter: metadata.SellerBalanceAfter, + PointAmount: metadata.PointAmount, SellerCoinAmount: metadata.SellerCoinAmount, + RatioPointAmount: metadata.RatioPointAmount, RatioSellerCoinAmount: metadata.RatioSellerCoinAmount, CreatedAtMS: metadata.CreatedAtMS, + } +} + +func normalizeCountryCodes(values []string) []string { + seen := make(map[string]struct{}, len(values)) + out := make([]string, 0, len(values)) + for _, value := range values { + value = strings.ToUpper(strings.TrimSpace(value)) + if value == "" { + continue + } + if _, exists := seen[value]; exists { + continue + } + seen[value] = struct{}{} + out = append(out, value) + } + return out +} + +func countryAllowed(configured []string, countryCode string) bool { + if len(configured) == 0 { + return true + } + countryCode = strings.ToUpper(strings.TrimSpace(countryCode)) + if countryCode == "" { + return false + } + for _, configuredCode := range configured { + if strings.EqualFold(configuredCode, countryCode) { + return true + } + } + return false +} diff --git a/services/wallet-service/internal/storage/mysql/policy_instance.go b/services/wallet-service/internal/storage/mysql/policy_instance.go index 8cefd734..47a518bd 100644 --- a/services/wallet-service/internal/storage/mysql/policy_instance.go +++ b/services/wallet-service/internal/storage/mysql/policy_instance.go @@ -12,14 +12,15 @@ import ( ) type walletPolicyInstance struct { - InstanceCode string - TemplateCode string - TemplateVersion string - RegionID int64 - HostPointAsset string - HostPointRatioPPM int64 - PointsPerUSD int64 - WithdrawFeeBPS int64 + InstanceCode string + TemplateCode string + TemplateVersion string + RegionID int64 + HostPointAsset string + HostPointRatioPPM int64 + AgencyPointRatioPPM int64 + PointsPerUSD int64 + WithdrawFeeBPS int64 } func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, appCode string, regionID int64, nowMS int64) (walletPolicyInstance, bool, error) { @@ -29,7 +30,7 @@ func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, } row := tx.QueryRowContext(ctx, ` SELECT instance_code, template_code, template_version, region_id, host_point_asset_type, - host_point_ratio_ppm, points_per_usd, withdraw_fee_bps + host_point_ratio_ppm, agency_point_ratio_ppm, points_per_usd, withdraw_fee_bps FROM wallet_policy_instances WHERE app_code = ? AND region_id IN (?, 0) @@ -41,7 +42,7 @@ func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, appCode, regionID, nowMS, nowMS, regionID, ) var item walletPolicyInstance - if err := row.Scan(&item.InstanceCode, &item.TemplateCode, &item.TemplateVersion, &item.RegionID, &item.HostPointAsset, &item.HostPointRatioPPM, &item.PointsPerUSD, &item.WithdrawFeeBPS); err != nil { + if err := row.Scan(&item.InstanceCode, &item.TemplateCode, &item.TemplateVersion, &item.RegionID, &item.HostPointAsset, &item.HostPointRatioPPM, &item.AgencyPointRatioPPM, &item.PointsPerUSD, &item.WithdrawFeeBPS); err != nil { if errors.Is(err, sql.ErrNoRows) { return walletPolicyInstance{}, false, nil } @@ -51,7 +52,7 @@ func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, if item.HostPointAsset == "" { item.HostPointAsset = ledger.AssetPoint } - if item.HostPointAsset != ledger.AssetPoint || item.HostPointRatioPPM <= 0 || item.HostPointRatioPPM > 1_000_000 || item.PointsPerUSD <= 0 || item.WithdrawFeeBPS < 0 || item.WithdrawFeeBPS > 10_000 { + if item.HostPointAsset != ledger.AssetPoint || item.HostPointRatioPPM <= 0 || item.HostPointRatioPPM > 1_000_000 || item.AgencyPointRatioPPM < 0 || item.AgencyPointRatioPPM > 1_000_000 || item.HostPointRatioPPM+item.AgencyPointRatioPPM > 1_000_000 || item.PointsPerUSD <= 0 || item.WithdrawFeeBPS < 0 || item.WithdrawFeeBPS > 10_000 { return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy instance is invalid") } return item, true, nil diff --git a/services/wallet-service/internal/storage/mysql/repository.go b/services/wallet-service/internal/storage/mysql/repository.go index edca9b97..27258f6d 100644 --- a/services/wallet-service/internal/storage/mysql/repository.go +++ b/services/wallet-service/internal/storage/mysql/repository.go @@ -71,6 +71,10 @@ func Open(ctx context.Context, dsn string) (*Repository, error) { _ = db.Close() return nil, err } + if err := ensurePointWithdrawalCoinSellerSchema(ctx, db); err != nil { + _ = db.Close() + return nil, err + } return &Repository{db: db}, nil } diff --git a/services/wallet-service/internal/storage/mysql/schema.go b/services/wallet-service/internal/storage/mysql/schema.go index 3e76b3b4..e602e671 100644 --- a/services/wallet-service/internal/storage/mysql/schema.go +++ b/services/wallet-service/internal/storage/mysql/schema.go @@ -207,6 +207,7 @@ func ensureWalletPolicyInstanceSchema(ctx context.Context, db *sql.DB) error { effective_to_ms BIGINT NOT NULL DEFAULT 0 COMMENT '0 表示长期有效', host_point_asset_type VARCHAR(32) NOT NULL DEFAULT 'POINT' COMMENT '主播收益积分资产', host_point_ratio_ppm BIGINT NOT NULL DEFAULT 700000 COMMENT '有效付费礼物转 POINT 比例,ppm', + agency_point_ratio_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '有效付费礼物给 Agency owner 的 POINT 分成比例,ppm', points_per_usd BIGINT NOT NULL DEFAULT 100000 COMMENT 'POINT/USD 展示换算比例', withdraw_fee_bps INT NOT NULL DEFAULT 500 COMMENT '提现手续费 bps', rule_json JSON NOT NULL COMMENT '完整政策快照', @@ -217,6 +218,50 @@ func ensureWalletPolicyInstanceSchema(ctx context.Context, db *sql.DB) error { PRIMARY KEY (app_code, instance_code, region_id), KEY idx_wallet_policy_active (app_code, region_id, status, effective_from_ms, effective_to_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包运行侧收益政策实例表'`) + if err != nil { + return err + } + if _, err := db.ExecContext(ctx, `ALTER TABLE wallet_policy_instances ADD COLUMN agency_point_ratio_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '有效付费礼物给 Agency owner 的 POINT 分成比例,ppm' AFTER host_point_ratio_ppm`); err != nil && !isDuplicateColumnError(err) { + return err + } + _, err = db.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS agency_point_share_entries ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', + transaction_id VARCHAR(96) NOT NULL, + host_user_id BIGINT NOT NULL, + agency_owner_user_id BIGINT NOT NULL, + sender_user_id BIGINT NOT NULL, + room_id VARCHAR(96) NOT NULL DEFAULT '', + point_delta BIGINT NOT NULL, + ratio_ppm BIGINT NOT NULL, + policy_instance_code VARCHAR(96) NOT NULL DEFAULT '', + created_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, transaction_id, agency_owner_user_id), + KEY idx_agency_point_share_owner_time (app_code, agency_owner_user_id, created_at_ms), + KEY idx_agency_point_share_host_time (app_code, host_user_id, created_at_ms) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Agency POINT 礼物分成流水'`) + return err +} + +// ensurePointWithdrawalCoinSellerSchema 创建跨 Fami/Huwaa/Lalu 共用、按 app_code 隔离的提现币商配置。 +// 表放在 wallet 数据库,保证兑换时读取比例和写账本处于同一可信服务边界,H5 不能自报比例。 +func ensurePointWithdrawalCoinSellerSchema(ctx context.Context, db *sql.DB) error { + _, err := db.ExecContext(ctx, ` + CREATE TABLE IF NOT EXISTS point_withdrawal_coin_seller_configs ( + app_code VARCHAR(32) NOT NULL COMMENT '应用编码', + seller_user_id BIGINT NOT NULL COMMENT '币商用户 ID', + sort_order INT NOT NULL DEFAULT 0 COMMENT '展示顺序,越小越靠前', + point_amount BIGINT NOT NULL COMMENT '兑换比例中的 POINT 分母', + seller_coin_amount BIGINT NOT NULL COMMENT '兑换比例中的币商金币分子', + service_country_codes JSON NOT NULL COMMENT '服务国家码数组;空数组表示不限国家', + status VARCHAR(24) NOT NULL DEFAULT 'active' COMMENT 'active/disabled', + created_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + updated_by_admin_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, seller_user_id), + KEY idx_point_withdraw_seller_list (app_code, status, sort_order, seller_user_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='POINT 提现币商白名单与兑换比例'`) return err } diff --git a/services/wallet-service/internal/testutil/mysqltest/mysqltest.go b/services/wallet-service/internal/testutil/mysqltest/mysqltest.go index f9a5bc00..fa7ce38a 100644 --- a/services/wallet-service/internal/testutil/mysqltest/mysqltest.go +++ b/services/wallet-service/internal/testutil/mysqltest/mysqltest.go @@ -4,6 +4,7 @@ package mysqltest import ( "context" "database/sql" + "encoding/json" "fmt" "strings" "testing" @@ -14,6 +15,31 @@ import ( mysqlstorage "hyapp/services/wallet-service/internal/storage/mysql" ) +// SetPointWithdrawalCoinSellerConfig seeds one app-scoped whitelist row for real ledger tests. +func (r *Repository) SetPointWithdrawalCoinSellerConfig(appCode string, sellerUserID int64, pointAmount int64, sellerCoinAmount int64, countryCodes []string, status string, sortOrder int) { + r.t.Helper() + countriesJSON, err := json.Marshal(countryCodes) + if err != nil { + r.t.Fatalf("marshal point withdrawal countries failed: %v", err) + } + if status == "" { + status = "active" + } + nowMS := time.Now().UnixMilli() + if _, err := r.schema.DB.ExecContext(context.Background(), ` + INSERT INTO point_withdrawal_coin_seller_configs ( + app_code, seller_user_id, sort_order, point_amount, seller_coin_amount, service_country_codes, + status, created_by_admin_id, updated_by_admin_id, created_at_ms, updated_at_ms + ) VALUES (?, ?, ?, ?, ?, ?, ?, 0, 0, ?, ?) + ON DUPLICATE KEY UPDATE + sort_order = VALUES(sort_order), point_amount = VALUES(point_amount), seller_coin_amount = VALUES(seller_coin_amount), + service_country_codes = VALUES(service_country_codes), status = VALUES(status), updated_at_ms = VALUES(updated_at_ms)`, + appCode, sellerUserID, sortOrder, pointAmount, sellerCoinAmount, countriesJSON, status, nowMS, nowMS, + ); err != nil { + r.t.Fatalf("seed point withdrawal coin seller config failed: %v", err) + } +} + // Repository wraps the production MySQL wallet repository with test seed helpers. type Repository struct { *mysqlstorage.Repository @@ -371,22 +397,28 @@ func (r *Repository) SetAssetBalanceForApp(appCode string, userID int64, assetTy // SeedWalletPolicyInstance writes the wallet runtime policy row consumed by gift settlement tests. func (r *Repository) SeedWalletPolicyInstance(appCode string, instanceCode string, regionID int64, status string, hostPointRatioPPM int64) { + r.SeedWalletPolicyInstanceWithAgency(appCode, instanceCode, regionID, status, hostPointRatioPPM, 0) +} + +// SeedWalletPolicyInstanceWithAgency 让账务测试显式声明 Agency 比例,避免普通 policy fixture 意外改变旧用例语义。 +func (r *Repository) SeedWalletPolicyInstanceWithAgency(appCode string, instanceCode string, regionID int64, status string, hostPointRatioPPM int64, agencyPointRatioPPM int64) { r.t.Helper() nowMs := time.Now().UnixMilli() _, err := r.schema.DB.ExecContext(context.Background(), ` INSERT INTO wallet_policy_instances ( app_code, instance_code, template_code, template_version, region_id, status, - effective_from_ms, effective_to_ms, host_point_asset_type, host_point_ratio_ppm, + effective_from_ms, effective_to_ms, host_point_asset_type, host_point_ratio_ppm, agency_point_ratio_ppm, points_per_usd, withdraw_fee_bps, rule_json, published_by_admin_id, published_at_ms, created_at_ms, updated_at_ms - ) VALUES (?, ?, ?, 'v1', ?, ?, 0, 0, 'POINT', ?, 100000, 500, JSON_OBJECT(), 90001, ?, ?, ?) + ) VALUES (?, ?, ?, 'v1', ?, ?, 0, 0, 'POINT', ?, ?, 100000, 500, JSON_OBJECT(), 90001, ?, ?, ?) ON DUPLICATE KEY UPDATE status = VALUES(status), host_point_ratio_ppm = VALUES(host_point_ratio_ppm), + agency_point_ratio_ppm = VALUES(agency_point_ratio_ppm), published_at_ms = VALUES(published_at_ms), updated_at_ms = VALUES(updated_at_ms) - `, strings.TrimSpace(appCode), strings.TrimSpace(instanceCode), strings.TrimSpace(instanceCode)+"_template", regionID, strings.TrimSpace(status), hostPointRatioPPM, nowMs, nowMs, nowMs) + `, strings.TrimSpace(appCode), strings.TrimSpace(instanceCode), strings.TrimSpace(instanceCode)+"_template", regionID, strings.TrimSpace(status), hostPointRatioPPM, agencyPointRatioPPM, nowMs, nowMs, nowMs) if err != nil { r.t.Fatalf("seed wallet policy instance failed: %v", err) } diff --git a/services/wallet-service/internal/transport/grpc/agency_host_gift_stats.go b/services/wallet-service/internal/transport/grpc/agency_host_gift_stats.go new file mode 100644 index 00000000..30c276ad --- /dev/null +++ b/services/wallet-service/internal/transport/grpc/agency_host_gift_stats.go @@ -0,0 +1,23 @@ +package grpc + +import ( + "context" + + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +func (s *Server) GetAgencyHostGiftStats(ctx context.Context, req *walletv1.GetAgencyHostGiftStatsRequest) (*walletv1.GetAgencyHostGiftStatsResponse, error) { + ctx = appcode.WithContext(ctx, req.GetAppCode()) + stats, err := s.svc.GetAgencyHostGiftStats(ctx, req.GetAppCode(), ledger.AgencyHostGiftStatsQuery{ + HostUserIDs: req.GetHostUserIds(), StartAtMS: req.GetStartAtMs(), EndAtMS: req.GetEndAtMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.GetAgencyHostGiftStatsResponse{Stats: &walletv1.AgencyHostGiftStats{ + GiftIncome: stats.GiftIncome, GiftedHostCount: stats.GiftedHostCount, + }}, nil +} diff --git a/services/wallet-service/internal/transport/grpc/agency_point_share_stats.go b/services/wallet-service/internal/transport/grpc/agency_point_share_stats.go new file mode 100644 index 00000000..50c7da9f --- /dev/null +++ b/services/wallet-service/internal/transport/grpc/agency_point_share_stats.go @@ -0,0 +1,26 @@ +package grpc + +import ( + "context" + + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +func (s *Server) GetAgencyPointShareStats(ctx context.Context, req *walletv1.GetAgencyPointShareStatsRequest) (*walletv1.GetAgencyPointShareStatsResponse, error) { + ctx = appcode.WithContext(ctx, req.GetAppCode()) + stats, err := s.svc.GetAgencyPointShareStats(ctx, req.GetAppCode(), ledger.AgencyPointShareStatsQuery{ + AgencyOwnerUserID: req.GetAgencyOwnerUserId(), + StartAtMS: req.GetStartAtMs(), + EndAtMS: req.GetEndAtMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.GetAgencyPointShareStatsResponse{Stats: &walletv1.AgencyPointShareStats{ + ShareIncome: stats.ShareIncome, + GiftedHostCount: stats.GiftedHostCount, + }}, nil +} diff --git a/services/wallet-service/internal/transport/grpc/host_revenue_stats.go b/services/wallet-service/internal/transport/grpc/host_revenue_stats.go new file mode 100644 index 00000000..dcdd34e5 --- /dev/null +++ b/services/wallet-service/internal/transport/grpc/host_revenue_stats.go @@ -0,0 +1,28 @@ +package grpc + +import ( + "context" + + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// GetHostRevenueStats 返回钱包账本内的 POINT 收益、兑换和去重送礼用户。 +func (s *Server) GetHostRevenueStats(ctx context.Context, req *walletv1.GetHostRevenueStatsRequest) (*walletv1.GetHostRevenueStatsResponse, error) { + ctx = appcode.WithContext(ctx, req.GetAppCode()) + stats, err := s.svc.GetHostRevenueStats(ctx, req.GetAppCode(), ledger.HostRevenueStatsQuery{ + HostUserID: req.GetHostUserId(), + StartAtMS: req.GetStartAtMs(), + EndAtMS: req.GetEndAtMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.GetHostRevenueStatsResponse{Stats: &walletv1.HostRevenueStats{ + DiamondEarnings: stats.DiamondEarnings, + DiamondExchanged: stats.DiamondExchanged, + GiftSenders: stats.GiftSenders, + }}, nil +} diff --git a/services/wallet-service/internal/transport/grpc/point_coin_seller.go b/services/wallet-service/internal/transport/grpc/point_coin_seller.go new file mode 100644 index 00000000..8df61b3e --- /dev/null +++ b/services/wallet-service/internal/transport/grpc/point_coin_seller.go @@ -0,0 +1,57 @@ +package grpc + +import ( + "context" + + walletv1 "hyapp.local/api/proto/wallet/v1" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// ListPointWithdrawalCoinSellers 返回 wallet 侧已执行 app/status/国家过滤的可信白名单。 +func (s *Server) ListPointWithdrawalCoinSellers(ctx context.Context, req *walletv1.ListPointWithdrawalCoinSellersRequest) (*walletv1.ListPointWithdrawalCoinSellersResponse, error) { + items, err := s.svc.ListPointWithdrawalCoinSellers(ctx, req.GetAppCode(), req.GetCountryCode(), req.GetIncludeDisabled()) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + response := &walletv1.ListPointWithdrawalCoinSellersResponse{Sellers: make([]*walletv1.PointWithdrawalCoinSellerConfig, 0, len(items))} + for _, item := range items { + response.Sellers = append(response.Sellers, &walletv1.PointWithdrawalCoinSellerConfig{ + AppCode: item.AppCode, SellerUserId: item.SellerUserID, SortOrder: int32(item.SortOrder), + PointAmount: item.PointAmount, SellerCoinAmount: item.SellerCoinAmount, + ServiceCountryCodes: append([]string(nil), item.ServiceCountryCodes...), Status: item.Status, + CreatedAtMs: item.CreatedAtMS, UpdatedAtMs: item.UpdatedAtMS, + }) + } + return response, nil +} + +// TransferPointToCoinSeller 不接受兑换比例字段,确保所有调用方都只能使用数据库白名单快照。 +func (s *Server) TransferPointToCoinSeller(ctx context.Context, req *walletv1.TransferPointToCoinSellerRequest) (*walletv1.TransferPointToCoinSellerResponse, error) { + receipt, err := s.svc.TransferPointToCoinSeller(ctx, ledger.PointToCoinSellerCommand{ + AppCode: req.GetAppCode(), CommandID: req.GetCommandId(), SourceUserID: req.GetSourceUserId(), + SellerUserID: req.GetSellerUserId(), PointAmount: req.GetPointAmount(), + SourceCountryCode: req.GetSourceCountryCode(), Reason: req.GetReason(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.TransferPointToCoinSellerResponse{ + TransactionId: receipt.TransactionID, SourcePointBalanceAfter: receipt.SourcePointBalanceAfter, + SellerBalanceAfter: receipt.SellerBalanceAfter, PointAmount: receipt.PointAmount, + SellerCoinAmount: receipt.SellerCoinAmount, RatioPointAmount: receipt.RatioPointAmount, + RatioSellerCoinAmount: receipt.RatioSellerCoinAmount, + }, nil +} + +// GetPointWithdrawalConfig 暴露政策编译后的最小运行参数,H5 不解析 Admin rule_json。 +func (s *Server) GetPointWithdrawalConfig(ctx context.Context, req *walletv1.GetPointWithdrawalConfigRequest) (*walletv1.GetPointWithdrawalConfigResponse, error) { + config, err := s.svc.GetPointWithdrawalConfig(ctx, req.GetAppCode(), req.GetRegionId(), req.GetNowMs()) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.GetPointWithdrawalConfigResponse{ + Found: config.Found, PointsPerUsd: config.PointsPerUSD, FeeBps: int32(config.FeeBPS), + MinimumPoints: config.MinimumPoints, PolicyInstanceCode: config.PolicyInstanceCode, + }, nil +}