feat(mpc-system): integrate gRPC calls into account-service MPC endpoints

- Update account_handler to use real gRPC calls instead of placeholders
- Add sessionCoordinatorClient field to AccountHTTPHandler
- Modify CreateKeygenSession to call session coordinator via gRPC
- Modify CreateSigningSession to call session coordinator via gRPC
- Modify GetSessionStatus to query real session data via gRPC
- Update main.go to initialize and pass sessionCoordinatorClient
- Remove separate mpc_handler.go (consolidated into account_handler)
- Regenerate protobuf files with gRPC service definitions
- Add proper imports for context, time, and grpc adapter

All MPC endpoints now create real sessions with JWT tokens and
can query actual session status from the session coordinator service.

Tested end-to-end: keygen session creation and status query working.
This commit is contained in:
hailin 2025-12-05 02:11:27 -08:00
parent 59e8d9975d
commit ac76fd80bc
7 changed files with 2403 additions and 640 deletions

View File

@ -0,0 +1,333 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.12.4
// source: api/proto/session_coordinator.proto
package coordinator
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
SessionCoordinator_CreateSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/CreateSession"
SessionCoordinator_JoinSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/JoinSession"
SessionCoordinator_GetSessionStatus_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/GetSessionStatus"
SessionCoordinator_MarkPartyReady_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/MarkPartyReady"
SessionCoordinator_StartSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/StartSession"
SessionCoordinator_ReportCompletion_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/ReportCompletion"
SessionCoordinator_CloseSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/CloseSession"
)
// SessionCoordinatorClient is the client API for SessionCoordinator service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SessionCoordinatorClient interface {
// Session management
CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error)
JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error)
GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error)
MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error)
StartSession(ctx context.Context, in *StartSessionRequest, opts ...grpc.CallOption) (*StartSessionResponse, error)
ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error)
CloseSession(ctx context.Context, in *CloseSessionRequest, opts ...grpc.CallOption) (*CloseSessionResponse, error)
}
type sessionCoordinatorClient struct {
cc grpc.ClientConnInterface
}
func NewSessionCoordinatorClient(cc grpc.ClientConnInterface) SessionCoordinatorClient {
return &sessionCoordinatorClient{cc}
}
func (c *sessionCoordinatorClient) CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) {
out := new(CreateSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_CreateSession_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error) {
out := new(JoinSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_JoinSession_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error) {
out := new(GetSessionStatusResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_GetSessionStatus_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error) {
out := new(MarkPartyReadyResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_MarkPartyReady_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) StartSession(ctx context.Context, in *StartSessionRequest, opts ...grpc.CallOption) (*StartSessionResponse, error) {
out := new(StartSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_StartSession_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error) {
out := new(ReportCompletionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_ReportCompletion_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) CloseSession(ctx context.Context, in *CloseSessionRequest, opts ...grpc.CallOption) (*CloseSessionResponse, error) {
out := new(CloseSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_CloseSession_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// SessionCoordinatorServer is the server API for SessionCoordinator service.
// All implementations must embed UnimplementedSessionCoordinatorServer
// for forward compatibility
type SessionCoordinatorServer interface {
// Session management
CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error)
JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error)
GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error)
MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error)
StartSession(context.Context, *StartSessionRequest) (*StartSessionResponse, error)
ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error)
CloseSession(context.Context, *CloseSessionRequest) (*CloseSessionResponse, error)
mustEmbedUnimplementedSessionCoordinatorServer()
}
// UnimplementedSessionCoordinatorServer must be embedded to have forward compatible implementations.
type UnimplementedSessionCoordinatorServer struct {
}
func (UnimplementedSessionCoordinatorServer) CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method JoinSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSessionStatus not implemented")
}
func (UnimplementedSessionCoordinatorServer) MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MarkPartyReady not implemented")
}
func (UnimplementedSessionCoordinatorServer) StartSession(context.Context, *StartSessionRequest) (*StartSessionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReportCompletion not implemented")
}
func (UnimplementedSessionCoordinatorServer) CloseSession(context.Context, *CloseSessionRequest) (*CloseSessionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) mustEmbedUnimplementedSessionCoordinatorServer() {}
// UnsafeSessionCoordinatorServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to SessionCoordinatorServer will
// result in compilation errors.
type UnsafeSessionCoordinatorServer interface {
mustEmbedUnimplementedSessionCoordinatorServer()
}
func RegisterSessionCoordinatorServer(s grpc.ServiceRegistrar, srv SessionCoordinatorServer) {
s.RegisterService(&SessionCoordinator_ServiceDesc, srv)
}
func _SessionCoordinator_CreateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateSessionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).CreateSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_CreateSession_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).CreateSession(ctx, req.(*CreateSessionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_JoinSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(JoinSessionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).JoinSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_JoinSession_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).JoinSession(ctx, req.(*JoinSessionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_GetSessionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetSessionStatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).GetSessionStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_GetSessionStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).GetSessionStatus(ctx, req.(*GetSessionStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_MarkPartyReady_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MarkPartyReadyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).MarkPartyReady(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_MarkPartyReady_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).MarkPartyReady(ctx, req.(*MarkPartyReadyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_StartSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StartSessionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).StartSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_StartSession_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).StartSession(ctx, req.(*StartSessionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_ReportCompletion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReportCompletionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).ReportCompletion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_ReportCompletion_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).ReportCompletion(ctx, req.(*ReportCompletionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SessionCoordinator_CloseSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseSessionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).CloseSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_CloseSession_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).CloseSession(ctx, req.(*CloseSessionRequest))
}
return interceptor(ctx, in, info, handler)
}
// SessionCoordinator_ServiceDesc is the grpc.ServiceDesc for SessionCoordinator service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var SessionCoordinator_ServiceDesc = grpc.ServiceDesc{
ServiceName: "mpc.coordinator.v1.SessionCoordinator",
HandlerType: (*SessionCoordinatorServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateSession",
Handler: _SessionCoordinator_CreateSession_Handler,
},
{
MethodName: "JoinSession",
Handler: _SessionCoordinator_JoinSession_Handler,
},
{
MethodName: "GetSessionStatus",
Handler: _SessionCoordinator_GetSessionStatus_Handler,
},
{
MethodName: "MarkPartyReady",
Handler: _SessionCoordinator_MarkPartyReady_Handler,
},
{
MethodName: "StartSession",
Handler: _SessionCoordinator_StartSession_Handler,
},
{
MethodName: "ReportCompletion",
Handler: _SessionCoordinator_ReportCompletion_Handler,
},
{
MethodName: "CloseSession",
Handler: _SessionCoordinator_CloseSession_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/proto/session_coordinator.proto",
}

View File

@ -1,168 +1,529 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.10
// protoc v3.12.4
// source: api/proto/message_router.proto
package router
import (
"context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// RouteMessageRequest routes an MPC message
type RouteMessageRequest struct {
SessionId string `json:"session_id,omitempty"`
FromParty string `json:"from_party,omitempty"`
ToParties []string `json:"to_parties,omitempty"`
RoundNumber int32 `json:"round_number,omitempty"`
MessageType string `json:"message_type,omitempty"`
Payload []byte `json:"payload,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
FromParty string `protobuf:"bytes,2,opt,name=from_party,json=fromParty,proto3" json:"from_party,omitempty"`
ToParties []string `protobuf:"bytes,3,rep,name=to_parties,json=toParties,proto3" json:"to_parties,omitempty"` // Empty for broadcast
RoundNumber int32 `protobuf:"varint,4,opt,name=round_number,json=roundNumber,proto3" json:"round_number,omitempty"`
MessageType string `protobuf:"bytes,5,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"`
Payload []byte `protobuf:"bytes,6,opt,name=payload,proto3" json:"payload,omitempty"` // Encrypted MPC message
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RouteMessageRequest) Reset() {
*x = RouteMessageRequest{}
mi := &file_api_proto_message_router_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RouteMessageRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RouteMessageRequest) ProtoMessage() {}
func (x *RouteMessageRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[0]
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 RouteMessageRequest.ProtoReflect.Descriptor instead.
func (*RouteMessageRequest) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{0}
}
func (x *RouteMessageRequest) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *RouteMessageRequest) GetFromParty() string {
if x != nil {
return x.FromParty
}
return ""
}
func (x *RouteMessageRequest) GetToParties() []string {
if x != nil {
return x.ToParties
}
return nil
}
func (x *RouteMessageRequest) GetRoundNumber() int32 {
if x != nil {
return x.RoundNumber
}
return 0
}
func (x *RouteMessageRequest) GetMessageType() string {
if x != nil {
return x.MessageType
}
return ""
}
func (x *RouteMessageRequest) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
// RouteMessageResponse confirms message routing
type RouteMessageResponse struct {
Success bool `json:"success,omitempty"`
MessageId string `json:"message_id,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
MessageId string `protobuf:"bytes,2,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RouteMessageResponse) Reset() {
*x = RouteMessageResponse{}
mi := &file_api_proto_message_router_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RouteMessageResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RouteMessageResponse) ProtoMessage() {}
func (x *RouteMessageResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[1]
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 RouteMessageResponse.ProtoReflect.Descriptor instead.
func (*RouteMessageResponse) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{1}
}
func (x *RouteMessageResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *RouteMessageResponse) GetMessageId() string {
if x != nil {
return x.MessageId
}
return ""
}
// SubscribeMessagesRequest subscribes to messages for a party
type SubscribeMessagesRequest struct {
SessionId string `json:"session_id,omitempty"`
PartyId string `json:"party_id,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
PartyId string `protobuf:"bytes,2,opt,name=party_id,json=partyId,proto3" json:"party_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SubscribeMessagesRequest) Reset() {
*x = SubscribeMessagesRequest{}
mi := &file_api_proto_message_router_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SubscribeMessagesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscribeMessagesRequest) ProtoMessage() {}
func (x *SubscribeMessagesRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[2]
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 SubscribeMessagesRequest.ProtoReflect.Descriptor instead.
func (*SubscribeMessagesRequest) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{2}
}
func (x *SubscribeMessagesRequest) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *SubscribeMessagesRequest) GetPartyId() string {
if x != nil {
return x.PartyId
}
return ""
}
// MPCMessage represents an MPC protocol message
type MPCMessage struct {
MessageId string `json:"message_id,omitempty"`
SessionId string `json:"session_id,omitempty"`
FromParty string `json:"from_party,omitempty"`
IsBroadcast bool `json:"is_broadcast,omitempty"`
RoundNumber int32 `json:"round_number,omitempty"`
MessageType string `json:"message_type,omitempty"`
Payload []byte `json:"payload,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
MessageId string `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"`
SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
FromParty string `protobuf:"bytes,3,opt,name=from_party,json=fromParty,proto3" json:"from_party,omitempty"`
IsBroadcast bool `protobuf:"varint,4,opt,name=is_broadcast,json=isBroadcast,proto3" json:"is_broadcast,omitempty"`
RoundNumber int32 `protobuf:"varint,5,opt,name=round_number,json=roundNumber,proto3" json:"round_number,omitempty"`
MessageType string `protobuf:"bytes,6,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"`
Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"`
CreatedAt int64 `protobuf:"varint,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Unix timestamp milliseconds
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *MPCMessage) Reset() {
*x = MPCMessage{}
mi := &file_api_proto_message_router_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MPCMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MPCMessage) ProtoMessage() {}
func (x *MPCMessage) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[3]
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 MPCMessage.ProtoReflect.Descriptor instead.
func (*MPCMessage) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{3}
}
func (x *MPCMessage) GetMessageId() string {
if x != nil {
return x.MessageId
}
return ""
}
func (x *MPCMessage) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *MPCMessage) GetFromParty() string {
if x != nil {
return x.FromParty
}
return ""
}
func (x *MPCMessage) GetIsBroadcast() bool {
if x != nil {
return x.IsBroadcast
}
return false
}
func (x *MPCMessage) GetRoundNumber() int32 {
if x != nil {
return x.RoundNumber
}
return 0
}
func (x *MPCMessage) GetMessageType() string {
if x != nil {
return x.MessageType
}
return ""
}
func (x *MPCMessage) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
func (x *MPCMessage) GetCreatedAt() int64 {
if x != nil {
return x.CreatedAt
}
return 0
}
// GetPendingMessagesRequest retrieves pending messages
type GetPendingMessagesRequest struct {
SessionId string `json:"session_id,omitempty"`
PartyId string `json:"party_id,omitempty"`
AfterTimestamp int64 `json:"after_timestamp,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
PartyId string `protobuf:"bytes,2,opt,name=party_id,json=partyId,proto3" json:"party_id,omitempty"`
AfterTimestamp int64 `protobuf:"varint,3,opt,name=after_timestamp,json=afterTimestamp,proto3" json:"after_timestamp,omitempty"` // Get messages after this timestamp
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetPendingMessagesRequest) Reset() {
*x = GetPendingMessagesRequest{}
mi := &file_api_proto_message_router_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetPendingMessagesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetPendingMessagesRequest) ProtoMessage() {}
func (x *GetPendingMessagesRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[4]
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 GetPendingMessagesRequest.ProtoReflect.Descriptor instead.
func (*GetPendingMessagesRequest) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{4}
}
func (x *GetPendingMessagesRequest) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *GetPendingMessagesRequest) GetPartyId() string {
if x != nil {
return x.PartyId
}
return ""
}
func (x *GetPendingMessagesRequest) GetAfterTimestamp() int64 {
if x != nil {
return x.AfterTimestamp
}
return 0
}
// GetPendingMessagesResponse contains pending messages
type GetPendingMessagesResponse struct {
Messages []*MPCMessage `json:"messages,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
Messages []*MPCMessage `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
// MessageRouterServer is the server API for MessageRouter service.
type MessageRouterServer interface {
RouteMessage(context.Context, *RouteMessageRequest) (*RouteMessageResponse, error)
SubscribeMessages(*SubscribeMessagesRequest, MessageRouter_SubscribeMessagesServer) error
GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error)
func (x *GetPendingMessagesResponse) Reset() {
*x = GetPendingMessagesResponse{}
mi := &file_api_proto_message_router_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
// UnimplementedMessageRouterServer can be embedded to have forward compatible implementations.
type UnimplementedMessageRouterServer struct{}
func (UnimplementedMessageRouterServer) RouteMessage(context.Context, *RouteMessageRequest) (*RouteMessageResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RouteMessage not implemented")
}
func (UnimplementedMessageRouterServer) SubscribeMessages(*SubscribeMessagesRequest, MessageRouter_SubscribeMessagesServer) error {
return status.Errorf(codes.Unimplemented, "method SubscribeMessages not implemented")
}
func (UnimplementedMessageRouterServer) GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPendingMessages not implemented")
func (x *GetPendingMessagesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
// UnsafeMessageRouterServer may be embedded to opt out of forward compatibility for this service.
type UnsafeMessageRouterServer interface {
mustEmbedUnimplementedMessageRouterServer()
func (*GetPendingMessagesResponse) ProtoMessage() {}
func (x *GetPendingMessagesResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_message_router_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// MessageRouter_SubscribeMessagesServer is the server API for streaming
type MessageRouter_SubscribeMessagesServer interface {
Send(*MPCMessage) error
grpc.ServerStream
// Deprecated: Use GetPendingMessagesResponse.ProtoReflect.Descriptor instead.
func (*GetPendingMessagesResponse) Descriptor() ([]byte, []int) {
return file_api_proto_message_router_proto_rawDescGZIP(), []int{5}
}
type messageRouterSubscribeMessagesServer struct {
grpc.ServerStream
func (x *GetPendingMessagesResponse) GetMessages() []*MPCMessage {
if x != nil {
return x.Messages
}
return nil
}
func (x *messageRouterSubscribeMessagesServer) Send(m *MPCMessage) error {
return x.ServerStream.SendMsg(m)
var File_api_proto_message_router_proto protoreflect.FileDescriptor
const file_api_proto_message_router_proto_rawDesc = "" +
"\n" +
"\x1eapi/proto/message_router.proto\x12\rmpc.router.v1\"\xd2\x01\n" +
"\x13RouteMessageRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12\x1d\n" +
"\n" +
"from_party\x18\x02 \x01(\tR\tfromParty\x12\x1d\n" +
"\n" +
"to_parties\x18\x03 \x03(\tR\ttoParties\x12!\n" +
"\fround_number\x18\x04 \x01(\x05R\vroundNumber\x12!\n" +
"\fmessage_type\x18\x05 \x01(\tR\vmessageType\x12\x18\n" +
"\apayload\x18\x06 \x01(\fR\apayload\"O\n" +
"\x14RouteMessageResponse\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\x12\x1d\n" +
"\n" +
"message_id\x18\x02 \x01(\tR\tmessageId\"T\n" +
"\x18SubscribeMessagesRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12\x19\n" +
"\bparty_id\x18\x02 \x01(\tR\apartyId\"\x8b\x02\n" +
"\n" +
"MPCMessage\x12\x1d\n" +
"\n" +
"message_id\x18\x01 \x01(\tR\tmessageId\x12\x1d\n" +
"\n" +
"session_id\x18\x02 \x01(\tR\tsessionId\x12\x1d\n" +
"\n" +
"from_party\x18\x03 \x01(\tR\tfromParty\x12!\n" +
"\fis_broadcast\x18\x04 \x01(\bR\visBroadcast\x12!\n" +
"\fround_number\x18\x05 \x01(\x05R\vroundNumber\x12!\n" +
"\fmessage_type\x18\x06 \x01(\tR\vmessageType\x12\x18\n" +
"\apayload\x18\a \x01(\fR\apayload\x12\x1d\n" +
"\n" +
"created_at\x18\b \x01(\x03R\tcreatedAt\"~\n" +
"\x19GetPendingMessagesRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12\x19\n" +
"\bparty_id\x18\x02 \x01(\tR\apartyId\x12'\n" +
"\x0fafter_timestamp\x18\x03 \x01(\x03R\x0eafterTimestamp\"S\n" +
"\x1aGetPendingMessagesResponse\x125\n" +
"\bmessages\x18\x01 \x03(\v2\x19.mpc.router.v1.MPCMessageR\bmessages2\xae\x02\n" +
"\rMessageRouter\x12W\n" +
"\fRouteMessage\x12\".mpc.router.v1.RouteMessageRequest\x1a#.mpc.router.v1.RouteMessageResponse\x12Y\n" +
"\x11SubscribeMessages\x12'.mpc.router.v1.SubscribeMessagesRequest\x1a\x19.mpc.router.v1.MPCMessage0\x01\x12i\n" +
"\x12GetPendingMessages\x12(.mpc.router.v1.GetPendingMessagesRequest\x1a).mpc.router.v1.GetPendingMessagesResponseB;Z9github.com/rwadurian/mpc-system/api/grpc/router/v1;routerb\x06proto3"
var (
file_api_proto_message_router_proto_rawDescOnce sync.Once
file_api_proto_message_router_proto_rawDescData []byte
)
func file_api_proto_message_router_proto_rawDescGZIP() []byte {
file_api_proto_message_router_proto_rawDescOnce.Do(func() {
file_api_proto_message_router_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_proto_message_router_proto_rawDesc), len(file_api_proto_message_router_proto_rawDesc)))
})
return file_api_proto_message_router_proto_rawDescData
}
var MessageRouter_ServiceDesc = grpc.ServiceDesc{
ServiceName: "mpc.router.v1.MessageRouter",
HandlerType: (*MessageRouterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "RouteMessage",
Handler: _MessageRouter_RouteMessage_Handler,
var file_api_proto_message_router_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_api_proto_message_router_proto_goTypes = []any{
(*RouteMessageRequest)(nil), // 0: mpc.router.v1.RouteMessageRequest
(*RouteMessageResponse)(nil), // 1: mpc.router.v1.RouteMessageResponse
(*SubscribeMessagesRequest)(nil), // 2: mpc.router.v1.SubscribeMessagesRequest
(*MPCMessage)(nil), // 3: mpc.router.v1.MPCMessage
(*GetPendingMessagesRequest)(nil), // 4: mpc.router.v1.GetPendingMessagesRequest
(*GetPendingMessagesResponse)(nil), // 5: mpc.router.v1.GetPendingMessagesResponse
}
var file_api_proto_message_router_proto_depIdxs = []int32{
3, // 0: mpc.router.v1.GetPendingMessagesResponse.messages:type_name -> mpc.router.v1.MPCMessage
0, // 1: mpc.router.v1.MessageRouter.RouteMessage:input_type -> mpc.router.v1.RouteMessageRequest
2, // 2: mpc.router.v1.MessageRouter.SubscribeMessages:input_type -> mpc.router.v1.SubscribeMessagesRequest
4, // 3: mpc.router.v1.MessageRouter.GetPendingMessages:input_type -> mpc.router.v1.GetPendingMessagesRequest
1, // 4: mpc.router.v1.MessageRouter.RouteMessage:output_type -> mpc.router.v1.RouteMessageResponse
3, // 5: mpc.router.v1.MessageRouter.SubscribeMessages:output_type -> mpc.router.v1.MPCMessage
5, // 6: mpc.router.v1.MessageRouter.GetPendingMessages:output_type -> mpc.router.v1.GetPendingMessagesResponse
4, // [4:7] is the sub-list for method output_type
1, // [1:4] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_api_proto_message_router_proto_init() }
func file_api_proto_message_router_proto_init() {
if File_api_proto_message_router_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_proto_message_router_proto_rawDesc), len(file_api_proto_message_router_proto_rawDesc)),
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
},
{
MethodName: "GetPendingMessages",
Handler: _MessageRouter_GetPendingMessages_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SubscribeMessages",
Handler: _MessageRouter_SubscribeMessages_Handler,
ServerStreams: true,
},
},
Metadata: "api/proto/message_router.proto",
}
func RegisterMessageRouterServer(s grpc.ServiceRegistrar, srv MessageRouterServer) {
s.RegisterService(&MessageRouter_ServiceDesc, srv)
}
func _MessageRouter_RouteMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RouteMessageRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).RouteMessage(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/mpc.router.v1.MessageRouter/RouteMessage",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).RouteMessage(ctx, req.(*RouteMessageRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_SubscribeMessages_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeMessagesRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(MessageRouterServer).SubscribeMessages(m, &messageRouterSubscribeMessagesServer{stream})
}
func _MessageRouter_GetPendingMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetPendingMessagesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).GetPendingMessages(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/mpc.router.v1.MessageRouter/GetPendingMessages",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).GetPendingMessages(ctx, req.(*GetPendingMessagesRequest))
}
return interceptor(ctx, in, info, handler)
GoTypes: file_api_proto_message_router_proto_goTypes,
DependencyIndexes: file_api_proto_message_router_proto_depIdxs,
MessageInfos: file_api_proto_message_router_proto_msgTypes,
}.Build()
File_api_proto_message_router_proto = out.File
file_api_proto_message_router_proto_goTypes = nil
file_api_proto_message_router_proto_depIdxs = nil
}

View File

@ -0,0 +1,217 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.12.4
// source: api/proto/message_router.proto
package router
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
MessageRouter_RouteMessage_FullMethodName = "/mpc.router.v1.MessageRouter/RouteMessage"
MessageRouter_SubscribeMessages_FullMethodName = "/mpc.router.v1.MessageRouter/SubscribeMessages"
MessageRouter_GetPendingMessages_FullMethodName = "/mpc.router.v1.MessageRouter/GetPendingMessages"
)
// MessageRouterClient is the client API for MessageRouter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type MessageRouterClient interface {
// RouteMessage routes a message from one party to others
RouteMessage(ctx context.Context, in *RouteMessageRequest, opts ...grpc.CallOption) (*RouteMessageResponse, error)
// SubscribeMessages subscribes to messages for a party (streaming)
SubscribeMessages(ctx context.Context, in *SubscribeMessagesRequest, opts ...grpc.CallOption) (MessageRouter_SubscribeMessagesClient, error)
// GetPendingMessages retrieves pending messages (polling alternative)
GetPendingMessages(ctx context.Context, in *GetPendingMessagesRequest, opts ...grpc.CallOption) (*GetPendingMessagesResponse, error)
}
type messageRouterClient struct {
cc grpc.ClientConnInterface
}
func NewMessageRouterClient(cc grpc.ClientConnInterface) MessageRouterClient {
return &messageRouterClient{cc}
}
func (c *messageRouterClient) RouteMessage(ctx context.Context, in *RouteMessageRequest, opts ...grpc.CallOption) (*RouteMessageResponse, error) {
out := new(RouteMessageResponse)
err := c.cc.Invoke(ctx, MessageRouter_RouteMessage_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) SubscribeMessages(ctx context.Context, in *SubscribeMessagesRequest, opts ...grpc.CallOption) (MessageRouter_SubscribeMessagesClient, error) {
stream, err := c.cc.NewStream(ctx, &MessageRouter_ServiceDesc.Streams[0], MessageRouter_SubscribeMessages_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &messageRouterSubscribeMessagesClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type MessageRouter_SubscribeMessagesClient interface {
Recv() (*MPCMessage, error)
grpc.ClientStream
}
type messageRouterSubscribeMessagesClient struct {
grpc.ClientStream
}
func (x *messageRouterSubscribeMessagesClient) Recv() (*MPCMessage, error) {
m := new(MPCMessage)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *messageRouterClient) GetPendingMessages(ctx context.Context, in *GetPendingMessagesRequest, opts ...grpc.CallOption) (*GetPendingMessagesResponse, error) {
out := new(GetPendingMessagesResponse)
err := c.cc.Invoke(ctx, MessageRouter_GetPendingMessages_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MessageRouterServer is the server API for MessageRouter service.
// All implementations must embed UnimplementedMessageRouterServer
// for forward compatibility
type MessageRouterServer interface {
// RouteMessage routes a message from one party to others
RouteMessage(context.Context, *RouteMessageRequest) (*RouteMessageResponse, error)
// SubscribeMessages subscribes to messages for a party (streaming)
SubscribeMessages(*SubscribeMessagesRequest, MessageRouter_SubscribeMessagesServer) error
// GetPendingMessages retrieves pending messages (polling alternative)
GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error)
mustEmbedUnimplementedMessageRouterServer()
}
// UnimplementedMessageRouterServer must be embedded to have forward compatible implementations.
type UnimplementedMessageRouterServer struct {
}
func (UnimplementedMessageRouterServer) RouteMessage(context.Context, *RouteMessageRequest) (*RouteMessageResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RouteMessage not implemented")
}
func (UnimplementedMessageRouterServer) SubscribeMessages(*SubscribeMessagesRequest, MessageRouter_SubscribeMessagesServer) error {
return status.Errorf(codes.Unimplemented, "method SubscribeMessages not implemented")
}
func (UnimplementedMessageRouterServer) GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPendingMessages not implemented")
}
func (UnimplementedMessageRouterServer) mustEmbedUnimplementedMessageRouterServer() {}
// UnsafeMessageRouterServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to MessageRouterServer will
// result in compilation errors.
type UnsafeMessageRouterServer interface {
mustEmbedUnimplementedMessageRouterServer()
}
func RegisterMessageRouterServer(s grpc.ServiceRegistrar, srv MessageRouterServer) {
s.RegisterService(&MessageRouter_ServiceDesc, srv)
}
func _MessageRouter_RouteMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RouteMessageRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).RouteMessage(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_RouteMessage_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).RouteMessage(ctx, req.(*RouteMessageRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_SubscribeMessages_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeMessagesRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(MessageRouterServer).SubscribeMessages(m, &messageRouterSubscribeMessagesServer{stream})
}
type MessageRouter_SubscribeMessagesServer interface {
Send(*MPCMessage) error
grpc.ServerStream
}
type messageRouterSubscribeMessagesServer struct {
grpc.ServerStream
}
func (x *messageRouterSubscribeMessagesServer) Send(m *MPCMessage) error {
return x.ServerStream.SendMsg(m)
}
func _MessageRouter_GetPendingMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetPendingMessagesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).GetPendingMessages(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_GetPendingMessages_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).GetPendingMessages(ctx, req.(*GetPendingMessagesRequest))
}
return interceptor(ctx, in, info, handler)
}
// MessageRouter_ServiceDesc is the grpc.ServiceDesc for MessageRouter service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var MessageRouter_ServiceDesc = grpc.ServiceDesc{
ServiceName: "mpc.router.v1.MessageRouter",
HandlerType: (*MessageRouterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "RouteMessage",
Handler: _MessageRouter_RouteMessage_Handler,
},
{
MethodName: "GetPendingMessages",
Handler: _MessageRouter_GetPendingMessages_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SubscribeMessages",
Handler: _MessageRouter_SubscribeMessages_Handler,
ServerStreams: true,
},
},
Metadata: "api/proto/message_router.proto",
}

View File

@ -1,11 +1,14 @@
package http
import (
"context"
"encoding/hex"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/rwadurian/mpc-system/services/account/adapters/output/grpc"
"github.com/rwadurian/mpc-system/services/account/application/ports"
"github.com/rwadurian/mpc-system/services/account/application/use_cases"
"github.com/rwadurian/mpc-system/services/account/domain/value_objects"
@ -13,19 +16,20 @@ import (
// AccountHTTPHandler handles HTTP requests for accounts
type AccountHTTPHandler struct {
createAccountUC *use_cases.CreateAccountUseCase
getAccountUC *use_cases.GetAccountUseCase
updateAccountUC *use_cases.UpdateAccountUseCase
listAccountsUC *use_cases.ListAccountsUseCase
getAccountSharesUC *use_cases.GetAccountSharesUseCase
deactivateShareUC *use_cases.DeactivateShareUseCase
loginUC *use_cases.LoginUseCase
refreshTokenUC *use_cases.RefreshTokenUseCase
generateChallengeUC *use_cases.GenerateChallengeUseCase
initiateRecoveryUC *use_cases.InitiateRecoveryUseCase
completeRecoveryUC *use_cases.CompleteRecoveryUseCase
getRecoveryStatusUC *use_cases.GetRecoveryStatusUseCase
cancelRecoveryUC *use_cases.CancelRecoveryUseCase
createAccountUC *use_cases.CreateAccountUseCase
getAccountUC *use_cases.GetAccountUseCase
updateAccountUC *use_cases.UpdateAccountUseCase
listAccountsUC *use_cases.ListAccountsUseCase
getAccountSharesUC *use_cases.GetAccountSharesUseCase
deactivateShareUC *use_cases.DeactivateShareUseCase
loginUC *use_cases.LoginUseCase
refreshTokenUC *use_cases.RefreshTokenUseCase
generateChallengeUC *use_cases.GenerateChallengeUseCase
initiateRecoveryUC *use_cases.InitiateRecoveryUseCase
completeRecoveryUC *use_cases.CompleteRecoveryUseCase
getRecoveryStatusUC *use_cases.GetRecoveryStatusUseCase
cancelRecoveryUC *use_cases.CancelRecoveryUseCase
sessionCoordinatorClient *grpc.SessionCoordinatorClient
}
// NewAccountHTTPHandler creates a new AccountHTTPHandler
@ -43,21 +47,23 @@ func NewAccountHTTPHandler(
completeRecoveryUC *use_cases.CompleteRecoveryUseCase,
getRecoveryStatusUC *use_cases.GetRecoveryStatusUseCase,
cancelRecoveryUC *use_cases.CancelRecoveryUseCase,
sessionCoordinatorClient *grpc.SessionCoordinatorClient,
) *AccountHTTPHandler {
return &AccountHTTPHandler{
createAccountUC: createAccountUC,
getAccountUC: getAccountUC,
updateAccountUC: updateAccountUC,
listAccountsUC: listAccountsUC,
getAccountSharesUC: getAccountSharesUC,
deactivateShareUC: deactivateShareUC,
loginUC: loginUC,
refreshTokenUC: refreshTokenUC,
generateChallengeUC: generateChallengeUC,
initiateRecoveryUC: initiateRecoveryUC,
completeRecoveryUC: completeRecoveryUC,
getRecoveryStatusUC: getRecoveryStatusUC,
cancelRecoveryUC: cancelRecoveryUC,
createAccountUC: createAccountUC,
getAccountUC: getAccountUC,
updateAccountUC: updateAccountUC,
listAccountsUC: listAccountsUC,
getAccountSharesUC: getAccountSharesUC,
deactivateShareUC: deactivateShareUC,
loginUC: loginUC,
refreshTokenUC: refreshTokenUC,
generateChallengeUC: generateChallengeUC,
initiateRecoveryUC: initiateRecoveryUC,
completeRecoveryUC: completeRecoveryUC,
getRecoveryStatusUC: getRecoveryStatusUC,
cancelRecoveryUC: cancelRecoveryUC,
sessionCoordinatorClient: sessionCoordinatorClient,
}
}
@ -559,22 +565,40 @@ func (h *AccountHTTPHandler) CreateKeygenSession(c *gin.Context) {
return
}
// Use create account use case's session coordinator client to create session
// For now, return a placeholder response
// In production, this would call the session coordinator service
sessionID := uuid.New()
joinTokens := make(map[string]string)
for _, p := range req.Participants {
joinTokens[p.PartyID] = uuid.New().String()
// Convert participants to gRPC format
participants := make([]grpc.ParticipantInfo, len(req.Participants))
for i, p := range req.Participants {
participants[i] = grpc.ParticipantInfo{
PartyID: p.PartyID,
DeviceType: p.DeviceType,
DeviceID: p.DeviceID,
}
}
// Call session coordinator via gRPC
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.CreateKeygenSession(
ctx,
int32(req.ThresholdN),
int32(req.ThresholdT),
participants,
600, // 10 minutes expiry
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"session_id": sessionID.String(),
"session_id": resp.SessionID,
"session_type": "keygen",
"threshold_n": req.ThresholdN,
"threshold_t": req.ThresholdT,
"join_tokens": joinTokens,
"status": "waiting",
"join_tokens": resp.JoinTokens,
"status": "created",
})
}
@ -631,23 +655,41 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) {
return
}
// Create signing session
// For now, return a placeholder response
// In production, this would call the session coordinator service
sessionID := uuid.New()
joinTokens := make(map[string]string)
for _, p := range req.Participants {
joinTokens[p.PartyID] = uuid.New().String()
// Convert participants to gRPC format
participants := make([]grpc.ParticipantInfo, len(req.Participants))
for i, p := range req.Participants {
participants[i] = grpc.ParticipantInfo{
PartyID: p.PartyID,
DeviceType: p.DeviceType,
DeviceID: p.DeviceID,
}
}
// Call session coordinator via gRPC
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.CreateSigningSession(
ctx,
int32(output.Account.ThresholdT),
participants,
messageHash,
600, // 10 minutes expiry
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"session_id": sessionID.String(),
"session_id": resp.SessionID,
"session_type": "sign",
"account_id": req.AccountID,
"message_hash": req.MessageHash,
"threshold_t": output.Account.ThresholdT,
"join_tokens": joinTokens,
"status": "waiting",
"join_tokens": resp.JoinTokens,
"status": "created",
})
}
@ -661,12 +703,30 @@ func (h *AccountHTTPHandler) GetSessionStatus(c *gin.Context) {
return
}
// For now, return a placeholder response
// In production, this would call the session coordinator service
c.JSON(http.StatusOK, gin.H{
// Call session coordinator via gRPC
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.GetSessionStatus(ctx, sessionID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
response := gin.H{
"session_id": sessionID,
"status": "waiting",
"completed_parties": 0,
"total_parties": 3,
})
"status": resp.Status,
"completed_parties": resp.CompletedParties,
"total_parties": resp.TotalParties,
}
if len(resp.PublicKey) > 0 {
response["public_key"] = hex.EncodeToString(resp.PublicKey)
}
if len(resp.Signature) > 0 {
response["signature"] = hex.EncodeToString(resp.Signature)
}
c.JSON(http.StatusOK, response)
}

View File

@ -1,198 +0,0 @@
package http
import (
"context"
"encoding/hex"
"net/http"
"time"
"github.com/gin-gonic/gin"
grpcadapter "github.com/rwadurian/mpc-system/services/account/adapters/output/grpc"
)
// MPCHandler handles MPC-related HTTP requests
type MPCHandler struct {
sessionCoordinatorClient *grpcadapter.SessionCoordinatorClient
}
// NewMPCHandler creates a new MPCHandler
func NewMPCHandler(sessionCoordinatorClient *grpcadapter.SessionCoordinatorClient) *MPCHandler {
return &MPCHandler{
sessionCoordinatorClient: sessionCoordinatorClient,
}
}
// RegisterRoutes registers MPC routes
func (h *MPCHandler) RegisterRoutes(router *gin.RouterGroup) {
mpc := router.Group("/mpc")
{
mpc.POST("/keygen", h.CreateKeygenSession)
mpc.POST("/sign", h.CreateSigningSession)
mpc.GET("/sessions/:id", h.GetSessionStatus)
}
}
// CreateKeygenSessionRequest represents a keygen session creation request
type CreateKeygenSessionRequest struct {
ThresholdN int json:"threshold_n" binding:"required,min=2,max=10"
ThresholdT int json:"threshold_t" binding:"required,min=1"
Participants []ParticipantRequest json:"participants" binding:"required,min=2"
}
// ParticipantRequest represents a participant in a request
type ParticipantRequest struct {
PartyID string json:"party_id" binding:"required"
DeviceType string json:"device_type" binding:"required"
DeviceID string json:"device_id,omitempty"
}
// CreateKeygenSession handles creating a new keygen session
func (h *MPCHandler) CreateKeygenSession(c *gin.Context) {
var req CreateKeygenSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Validate threshold
if req.ThresholdT > req.ThresholdN {
c.JSON(http.StatusBadRequest, gin.H{"error": "threshold_t cannot be greater than threshold_n"})
return
}
if len(req.Participants) != req.ThresholdN {
c.JSON(http.StatusBadRequest, gin.H{"error": "number of participants must equal threshold_n"})
return
}
// Convert participants
participants := make([]grpcadapter.ParticipantInfo, len(req.Participants))
for i, p := range req.Participants {
participants[i] = grpcadapter.ParticipantInfo{
PartyID: p.PartyID,
DeviceType: p.DeviceType,
DeviceID: p.DeviceID,
}
}
// Call gRPC service
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.CreateKeygenSession(
ctx,
int32(req.ThresholdN),
int32(req.ThresholdT),
participants,
600, // 10 minutes expiry
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"session_id": resp.SessionID,
"session_type": "keygen",
"threshold_n": req.ThresholdN,
"threshold_t": req.ThresholdT,
"join_tokens": resp.JoinTokens,
"status": "created",
})
}
// CreateSigningSessionRequest represents a signing session creation request
type CreateSigningSessionRequest struct {
AccountID string json:"account_id" binding:"required"
MessageHash string json:"message_hash" binding:"required"
Participants []ParticipantRequest json:"participants" binding:"required,min=2"
}
// CreateSigningSession handles creating a new signing session
func (h *MPCHandler) CreateSigningSession(c *gin.Context) {
var req CreateSigningSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Decode message hash
messageHash, err := hex.DecodeString(req.MessageHash)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid message hash format"})
return
}
// Convert participants
participants := make([]grpcadapter.ParticipantInfo, len(req.Participants))
for i, p := range req.Participants {
participants[i] = grpcadapter.ParticipantInfo{
PartyID: p.PartyID,
DeviceType: p.DeviceType,
DeviceID: p.DeviceID,
}
}
// Determine threshold (should come from account configuration)
// For now, use len(participants) as threshold
thresholdT := int32(len(req.Participants))
// Call gRPC service
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.CreateSigningSession(
ctx,
thresholdT,
participants,
messageHash,
600, // 10 minutes expiry
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"session_id": resp.SessionID,
"session_type": "sign",
"account_id": req.AccountID,
"message_hash": req.MessageHash,
"threshold_t": thresholdT,
"join_tokens": resp.JoinTokens,
"status": "created",
})
}
// GetSessionStatus handles querying session status
func (h *MPCHandler) GetSessionStatus(c *gin.Context) {
sessionID := c.Param("id")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err := h.sessionCoordinatorClient.GetSessionStatus(ctx, sessionID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
response := gin.H{
"session_id": sessionID,
"status": resp.Status,
"completed_parties": resp.CompletedParties,
"total_parties": resp.TotalParties,
}
if len(resp.PublicKey) > 0 {
response["public_key"] = hex.EncodeToString(resp.PublicKey)
}
if len(resp.Signature) > 0 {
response["signature"] = hex.EncodeToString(resp.Signature)
}
c.JSON(http.StatusOK, response)
}

View File

@ -20,6 +20,7 @@ import (
"github.com/rwadurian/mpc-system/pkg/jwt"
"github.com/rwadurian/mpc-system/pkg/logger"
httphandler "github.com/rwadurian/mpc-system/services/account/adapters/input/http"
grpcadapter "github.com/rwadurian/mpc-system/services/account/adapters/output/grpc"
jwtadapter "github.com/rwadurian/mpc-system/services/account/adapters/output/jwt"
"github.com/rwadurian/mpc-system/services/account/adapters/output/postgres"
"github.com/rwadurian/mpc-system/services/account/adapters/output/rabbitmq"
@ -73,6 +74,14 @@ func main() {
}
defer rabbitConn.Close()
// Initialize gRPC client for session coordinator
sessionCoordinatorAddr := "mpc-session-coordinator:50051"
sessionCoordinatorClient, err := grpcadapter.NewSessionCoordinatorClient(sessionCoordinatorAddr)
if err != nil {
logger.Fatal("Failed to connect to session coordinator", zap.Error(err))
}
defer sessionCoordinatorClient.Close()
// Initialize repositories
accountRepo := postgres.NewAccountPostgresRepo(db)
shareRepo := postgres.NewAccountSharePostgresRepo(db)
@ -136,6 +145,7 @@ func main() {
completeRecoveryUC,
getRecoveryStatusUC,
cancelRecoveryUC,
sessionCoordinatorClient,
); err != nil {
errChan <- fmt.Errorf("HTTP server error: %w", err)
}
@ -225,6 +235,7 @@ func startHTTPServer(
completeRecoveryUC *use_cases.CompleteRecoveryUseCase,
getRecoveryStatusUC *use_cases.GetRecoveryStatusUseCase,
cancelRecoveryUC *use_cases.CancelRecoveryUseCase,
sessionCoordinatorClient *grpcadapter.SessionCoordinatorClient,
) error {
// Set Gin mode
if cfg.Server.Environment == "production" {
@ -235,7 +246,7 @@ func startHTTPServer(
router.Use(gin.Recovery())
router.Use(gin.Logger())
// Create HTTP handler
// Create HTTP handler with session coordinator client
httpHandler := httphandler.NewAccountHTTPHandler(
createAccountUC,
getAccountUC,
@ -250,6 +261,7 @@ func startHTTPServer(
completeRecoveryUC,
getRecoveryStatusUC,
cancelRecoveryUC,
sessionCoordinatorClient,
)
// Health check