feat: complete keygen_session_id implementation for signing sessions

- Regenerate protobuf Go code with KeygenSessionId fields
- Session Coordinator correctly parses, stores, and returns keygen_session_id
- Message Router Client parses keygen_session_id in JoinSession response
- participate_signing.go uses keygen_session_id for precise share lookup
- Database schema already includes keygen_session_id column

This fixes the signing issue where wrong keyshares were loaded for multi-account scenarios.
This commit is contained in:
hailin 2025-12-06 08:57:30 -08:00
parent 23eff00d76
commit 3d176e1132
16 changed files with 3662 additions and 2225 deletions

View File

@ -28,7 +28,8 @@
"Bash(bash scripts/deploy.sh:*)",
"Bash(go run:*)",
"Bash(timeout /t 5 /nobreak)",
"Bash(bash:*)"
"Bash(bash:*)",
"Bash(docker compose:*)"
],
"deny": [],
"ask": []

View File

@ -33,8 +33,10 @@ type CreateSessionRequest struct {
PartyComposition *PartyComposition `protobuf:"bytes,7,opt,name=party_composition,json=partyComposition,proto3" json:"party_composition,omitempty"` // Optional: party composition requirements for auto-selection
// For sign sessions with delegate party: user must provide their encrypted share
DelegateUserShare *DelegateUserShare `protobuf:"bytes,8,opt,name=delegate_user_share,json=delegateUserShare,proto3" json:"delegate_user_share,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
// For sign sessions: which keygen session's shares to use
KeygenSessionId string `protobuf:"bytes,9,opt,name=keygen_session_id,json=keygenSessionId,proto3" json:"keygen_session_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CreateSessionRequest) Reset() {
@ -123,6 +125,13 @@ func (x *CreateSessionRequest) GetDelegateUserShare() *DelegateUserShare {
return nil
}
func (x *CreateSessionRequest) GetKeygenSessionId() string {
if x != nil {
return x.KeygenSessionId
}
return ""
}
// DelegateUserShare contains user's share for delegate party to use in signing
type DelegateUserShare struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -584,15 +593,17 @@ func (x *JoinSessionResponse) GetPartyIndex() int32 {
// SessionInfo contains session information
type SessionInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionType string `protobuf:"bytes,2,opt,name=session_type,json=sessionType,proto3" json:"session_type,omitempty"`
ThresholdN int32 `protobuf:"varint,3,opt,name=threshold_n,json=thresholdN,proto3" json:"threshold_n,omitempty"`
ThresholdT int32 `protobuf:"varint,4,opt,name=threshold_t,json=thresholdT,proto3" json:"threshold_t,omitempty"`
MessageHash []byte `protobuf:"bytes,5,opt,name=message_hash,json=messageHash,proto3" json:"message_hash,omitempty"`
Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionType string `protobuf:"bytes,2,opt,name=session_type,json=sessionType,proto3" json:"session_type,omitempty"`
ThresholdN int32 `protobuf:"varint,3,opt,name=threshold_n,json=thresholdN,proto3" json:"threshold_n,omitempty"`
ThresholdT int32 `protobuf:"varint,4,opt,name=threshold_t,json=thresholdT,proto3" json:"threshold_t,omitempty"`
MessageHash []byte `protobuf:"bytes,5,opt,name=message_hash,json=messageHash,proto3" json:"message_hash,omitempty"`
Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
// For sign sessions: which keygen session's shares to use
KeygenSessionId string `protobuf:"bytes,7,opt,name=keygen_session_id,json=keygenSessionId,proto3" json:"keygen_session_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SessionInfo) Reset() {
@ -667,6 +678,13 @@ func (x *SessionInfo) GetStatus() string {
return ""
}
func (x *SessionInfo) GetKeygenSessionId() string {
if x != nil {
return x.KeygenSessionId
}
return ""
}
// PartyInfo contains party information
type PartyInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -1497,7 +1515,7 @@ var File_api_proto_session_coordinator_proto protoreflect.FileDescriptor
const file_api_proto_session_coordinator_proto_rawDesc = "" +
"\n" +
"#api/proto/session_coordinator.proto\x12\x12mpc.coordinator.v1\"\xbf\x03\n" +
"#api/proto/session_coordinator.proto\x12\x12mpc.coordinator.v1\"\xeb\x03\n" +
"\x14CreateSessionRequest\x12!\n" +
"\fsession_type\x18\x01 \x01(\tR\vsessionType\x12\x1f\n" +
"\vthreshold_n\x18\x02 \x01(\x05R\n" +
@ -1508,7 +1526,8 @@ const file_api_proto_session_coordinator_proto_rawDesc = "" +
"\fmessage_hash\x18\x05 \x01(\fR\vmessageHash\x12,\n" +
"\x12expires_in_seconds\x18\x06 \x01(\x03R\x10expiresInSeconds\x12Q\n" +
"\x11party_composition\x18\a \x01(\v2$.mpc.coordinator.v1.PartyCompositionR\x10partyComposition\x12U\n" +
"\x13delegate_user_share\x18\b \x01(\v2%.mpc.coordinator.v1.DelegateUserShareR\x11delegateUserShare\"\x89\x01\n" +
"\x13delegate_user_share\x18\b \x01(\v2%.mpc.coordinator.v1.DelegateUserShareR\x11delegateUserShare\x12*\n" +
"\x11keygen_session_id\x18\t \x01(\tR\x0fkeygenSessionId\"\x89\x01\n" +
"\x11DelegateUserShare\x12*\n" +
"\x11delegate_party_id\x18\x01 \x01(\tR\x0fdelegatePartyId\x12'\n" +
"\x0fencrypted_share\x18\x02 \x01(\fR\x0eencryptedShare\x12\x1f\n" +
@ -1555,7 +1574,7 @@ const file_api_proto_session_coordinator_proto_rawDesc = "" +
"\fsession_info\x18\x02 \x01(\v2\x1f.mpc.coordinator.v1.SessionInfoR\vsessionInfo\x12B\n" +
"\rother_parties\x18\x03 \x03(\v2\x1d.mpc.coordinator.v1.PartyInfoR\fotherParties\x12\x1f\n" +
"\vparty_index\x18\x04 \x01(\x05R\n" +
"partyIndex\"\xcc\x01\n" +
"partyIndex\"\xf8\x01\n" +
"\vSessionInfo\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12!\n" +
@ -1565,7 +1584,8 @@ const file_api_proto_session_coordinator_proto_rawDesc = "" +
"\vthreshold_t\x18\x04 \x01(\x05R\n" +
"thresholdT\x12!\n" +
"\fmessage_hash\x18\x05 \x01(\fR\vmessageHash\x12\x16\n" +
"\x06status\x18\x06 \x01(\tR\x06status\"\x88\x01\n" +
"\x06status\x18\x06 \x01(\tR\x06status\x12*\n" +
"\x11keygen_session_id\x18\a \x01(\tR\x0fkeygenSessionId\"\x88\x01\n" +
"\tPartyInfo\x12\x19\n" +
"\bparty_id\x18\x01 \x01(\tR\apartyId\x12\x1f\n" +
"\vparty_index\x18\x02 \x01(\x05R\n" +

View File

@ -1716,15 +1716,16 @@ func (x *PartyInfo) GetDeviceInfo() *DeviceInfo {
// SessionInfo contains session information
type SessionInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionType string `protobuf:"bytes,2,opt,name=session_type,json=sessionType,proto3" json:"session_type,omitempty"` // keygen, sign
ThresholdN int32 `protobuf:"varint,3,opt,name=threshold_n,json=thresholdN,proto3" json:"threshold_n,omitempty"`
ThresholdT int32 `protobuf:"varint,4,opt,name=threshold_t,json=thresholdT,proto3" json:"threshold_t,omitempty"`
MessageHash []byte `protobuf:"bytes,5,opt,name=message_hash,json=messageHash,proto3" json:"message_hash,omitempty"` // For sign sessions
Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionType string `protobuf:"bytes,2,opt,name=session_type,json=sessionType,proto3" json:"session_type,omitempty"` // keygen, sign
ThresholdN int32 `protobuf:"varint,3,opt,name=threshold_n,json=thresholdN,proto3" json:"threshold_n,omitempty"`
ThresholdT int32 `protobuf:"varint,4,opt,name=threshold_t,json=thresholdT,proto3" json:"threshold_t,omitempty"`
MessageHash []byte `protobuf:"bytes,5,opt,name=message_hash,json=messageHash,proto3" json:"message_hash,omitempty"` // For sign sessions
Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
KeygenSessionId string `protobuf:"bytes,7,opt,name=keygen_session_id,json=keygenSessionId,proto3" json:"keygen_session_id,omitempty"` // For sign sessions: which keygen session's shares to use
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SessionInfo) Reset() {
@ -1799,6 +1800,13 @@ func (x *SessionInfo) GetStatus() string {
return ""
}
func (x *SessionInfo) GetKeygenSessionId() string {
if x != nil {
return x.KeygenSessionId
}
return ""
}
// JoinSessionRequest joins a session
type JoinSessionRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -2574,7 +2582,7 @@ const file_api_proto_message_router_proto_rawDesc = "" +
"\vparty_index\x18\x02 \x01(\x05R\n" +
"partyIndex\x12:\n" +
"\vdevice_info\x18\x03 \x01(\v2\x19.mpc.router.v1.DeviceInfoR\n" +
"deviceInfo\"\xcc\x01\n" +
"deviceInfo\"\xf8\x01\n" +
"\vSessionInfo\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12!\n" +
@ -2584,7 +2592,8 @@ const file_api_proto_message_router_proto_rawDesc = "" +
"\vthreshold_t\x18\x04 \x01(\x05R\n" +
"thresholdT\x12!\n" +
"\fmessage_hash\x18\x05 \x01(\fR\vmessageHash\x12\x16\n" +
"\x06status\x18\x06 \x01(\tR\x06status\"\xa9\x01\n" +
"\x06status\x18\x06 \x01(\tR\x06status\x12*\n" +
"\x11keygen_session_id\x18\a \x01(\tR\x0fkeygenSessionId\"\xa9\x01\n" +
"\x12JoinSessionRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\x12\x19\n" +

File diff suppressed because it is too large Load Diff

View File

@ -286,6 +286,7 @@ message SessionInfo {
int32 threshold_t = 4;
bytes message_hash = 5; // For sign sessions
string status = 6;
string keygen_session_id = 7; // For sign sessions: which keygen session's shares to use
}
// JoinSessionRequest joins a session

View File

@ -0,0 +1,700 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.0
// - protoc v6.33.1
// 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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
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"
MessageRouter_AcknowledgeMessage_FullMethodName = "/mpc.router.v1.MessageRouter/AcknowledgeMessage"
MessageRouter_GetMessageStatus_FullMethodName = "/mpc.router.v1.MessageRouter/GetMessageStatus"
MessageRouter_RegisterParty_FullMethodName = "/mpc.router.v1.MessageRouter/RegisterParty"
MessageRouter_Heartbeat_FullMethodName = "/mpc.router.v1.MessageRouter/Heartbeat"
MessageRouter_SubscribeSessionEvents_FullMethodName = "/mpc.router.v1.MessageRouter/SubscribeSessionEvents"
MessageRouter_PublishSessionEvent_FullMethodName = "/mpc.router.v1.MessageRouter/PublishSessionEvent"
MessageRouter_GetRegisteredParties_FullMethodName = "/mpc.router.v1.MessageRouter/GetRegisteredParties"
MessageRouter_JoinSession_FullMethodName = "/mpc.router.v1.MessageRouter/JoinSession"
MessageRouter_MarkPartyReady_FullMethodName = "/mpc.router.v1.MessageRouter/MarkPartyReady"
MessageRouter_ReportCompletion_FullMethodName = "/mpc.router.v1.MessageRouter/ReportCompletion"
MessageRouter_GetSessionStatus_FullMethodName = "/mpc.router.v1.MessageRouter/GetSessionStatus"
MessageRouter_SubmitDelegateShare_FullMethodName = "/mpc.router.v1.MessageRouter/SubmitDelegateShare"
)
// 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.
//
// MessageRouter service handles MPC message routing
// This is the ONLY service that server-parties need to connect to.
// All session operations are proxied through Message Router to Session Coordinator.
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) (grpc.ServerStreamingClient[MPCMessage], error)
// GetPendingMessages retrieves pending messages (polling alternative)
GetPendingMessages(ctx context.Context, in *GetPendingMessagesRequest, opts ...grpc.CallOption) (*GetPendingMessagesResponse, error)
// AcknowledgeMessage acknowledges receipt of a message
// Must be called after processing a message to confirm delivery
AcknowledgeMessage(ctx context.Context, in *AcknowledgeMessageRequest, opts ...grpc.CallOption) (*AcknowledgeMessageResponse, error)
// GetMessageStatus gets the delivery status of a message
GetMessageStatus(ctx context.Context, in *GetMessageStatusRequest, opts ...grpc.CallOption) (*GetMessageStatusResponse, error)
// RegisterParty registers a party with the message router (party actively connects)
RegisterParty(ctx context.Context, in *RegisterPartyRequest, opts ...grpc.CallOption) (*RegisterPartyResponse, error)
// Heartbeat sends a heartbeat to keep the party alive
Heartbeat(ctx context.Context, in *HeartbeatRequest, opts ...grpc.CallOption) (*HeartbeatResponse, error)
// SubscribeSessionEvents subscribes to session lifecycle events (session start, etc.)
SubscribeSessionEvents(ctx context.Context, in *SubscribeSessionEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SessionEvent], error)
// PublishSessionEvent publishes a session event (called by Session Coordinator)
PublishSessionEvent(ctx context.Context, in *PublishSessionEventRequest, opts ...grpc.CallOption) (*PublishSessionEventResponse, error)
// GetRegisteredParties returns all registered parties (for Session Coordinator party discovery)
GetRegisteredParties(ctx context.Context, in *GetRegisteredPartiesRequest, opts ...grpc.CallOption) (*GetRegisteredPartiesResponse, error)
// JoinSession joins a session (proxied to Session Coordinator)
JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error)
// MarkPartyReady marks a party as ready (proxied to Session Coordinator)
MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error)
// ReportCompletion reports completion (proxied to Session Coordinator)
ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error)
// GetSessionStatus gets session status (proxied to Session Coordinator)
GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error)
// SubmitDelegateShare submits user's share from delegate party (proxied to Session Coordinator)
SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, 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) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RouteMessageResponse)
err := c.cc.Invoke(ctx, MessageRouter_RouteMessage_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) SubscribeMessages(ctx context.Context, in *SubscribeMessagesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[MPCMessage], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &MessageRouter_ServiceDesc.Streams[0], MessageRouter_SubscribeMessages_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[SubscribeMessagesRequest, MPCMessage]{ClientStream: 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
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type MessageRouter_SubscribeMessagesClient = grpc.ServerStreamingClient[MPCMessage]
func (c *messageRouterClient) GetPendingMessages(ctx context.Context, in *GetPendingMessagesRequest, opts ...grpc.CallOption) (*GetPendingMessagesResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetPendingMessagesResponse)
err := c.cc.Invoke(ctx, MessageRouter_GetPendingMessages_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) AcknowledgeMessage(ctx context.Context, in *AcknowledgeMessageRequest, opts ...grpc.CallOption) (*AcknowledgeMessageResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AcknowledgeMessageResponse)
err := c.cc.Invoke(ctx, MessageRouter_AcknowledgeMessage_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) GetMessageStatus(ctx context.Context, in *GetMessageStatusRequest, opts ...grpc.CallOption) (*GetMessageStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetMessageStatusResponse)
err := c.cc.Invoke(ctx, MessageRouter_GetMessageStatus_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) RegisterParty(ctx context.Context, in *RegisterPartyRequest, opts ...grpc.CallOption) (*RegisterPartyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RegisterPartyResponse)
err := c.cc.Invoke(ctx, MessageRouter_RegisterParty_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) Heartbeat(ctx context.Context, in *HeartbeatRequest, opts ...grpc.CallOption) (*HeartbeatResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(HeartbeatResponse)
err := c.cc.Invoke(ctx, MessageRouter_Heartbeat_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) SubscribeSessionEvents(ctx context.Context, in *SubscribeSessionEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SessionEvent], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &MessageRouter_ServiceDesc.Streams[1], MessageRouter_SubscribeSessionEvents_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[SubscribeSessionEventsRequest, SessionEvent]{ClientStream: 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
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type MessageRouter_SubscribeSessionEventsClient = grpc.ServerStreamingClient[SessionEvent]
func (c *messageRouterClient) PublishSessionEvent(ctx context.Context, in *PublishSessionEventRequest, opts ...grpc.CallOption) (*PublishSessionEventResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(PublishSessionEventResponse)
err := c.cc.Invoke(ctx, MessageRouter_PublishSessionEvent_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) GetRegisteredParties(ctx context.Context, in *GetRegisteredPartiesRequest, opts ...grpc.CallOption) (*GetRegisteredPartiesResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetRegisteredPartiesResponse)
err := c.cc.Invoke(ctx, MessageRouter_GetRegisteredParties_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(JoinSessionResponse)
err := c.cc.Invoke(ctx, MessageRouter_JoinSession_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(MarkPartyReadyResponse)
err := c.cc.Invoke(ctx, MessageRouter_MarkPartyReady_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ReportCompletionResponse)
err := c.cc.Invoke(ctx, MessageRouter_ReportCompletion_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetSessionStatusResponse)
err := c.cc.Invoke(ctx, MessageRouter_GetSessionStatus_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messageRouterClient) SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SubmitDelegateShareResponse)
err := c.cc.Invoke(ctx, MessageRouter_SubmitDelegateShare_FullMethodName, in, out, cOpts...)
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.
//
// MessageRouter service handles MPC message routing
// This is the ONLY service that server-parties need to connect to.
// All session operations are proxied through Message Router to Session Coordinator.
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, grpc.ServerStreamingServer[MPCMessage]) error
// GetPendingMessages retrieves pending messages (polling alternative)
GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error)
// AcknowledgeMessage acknowledges receipt of a message
// Must be called after processing a message to confirm delivery
AcknowledgeMessage(context.Context, *AcknowledgeMessageRequest) (*AcknowledgeMessageResponse, error)
// GetMessageStatus gets the delivery status of a message
GetMessageStatus(context.Context, *GetMessageStatusRequest) (*GetMessageStatusResponse, error)
// RegisterParty registers a party with the message router (party actively connects)
RegisterParty(context.Context, *RegisterPartyRequest) (*RegisterPartyResponse, error)
// Heartbeat sends a heartbeat to keep the party alive
Heartbeat(context.Context, *HeartbeatRequest) (*HeartbeatResponse, error)
// SubscribeSessionEvents subscribes to session lifecycle events (session start, etc.)
SubscribeSessionEvents(*SubscribeSessionEventsRequest, grpc.ServerStreamingServer[SessionEvent]) error
// PublishSessionEvent publishes a session event (called by Session Coordinator)
PublishSessionEvent(context.Context, *PublishSessionEventRequest) (*PublishSessionEventResponse, error)
// GetRegisteredParties returns all registered parties (for Session Coordinator party discovery)
GetRegisteredParties(context.Context, *GetRegisteredPartiesRequest) (*GetRegisteredPartiesResponse, error)
// JoinSession joins a session (proxied to Session Coordinator)
JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error)
// MarkPartyReady marks a party as ready (proxied to Session Coordinator)
MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error)
// ReportCompletion reports completion (proxied to Session Coordinator)
ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error)
// GetSessionStatus gets session status (proxied to Session Coordinator)
GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error)
// SubmitDelegateShare submits user's share from delegate party (proxied to Session Coordinator)
SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error)
mustEmbedUnimplementedMessageRouterServer()
}
// UnimplementedMessageRouterServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedMessageRouterServer struct{}
func (UnimplementedMessageRouterServer) RouteMessage(context.Context, *RouteMessageRequest) (*RouteMessageResponse, error) {
return nil, status.Error(codes.Unimplemented, "method RouteMessage not implemented")
}
func (UnimplementedMessageRouterServer) SubscribeMessages(*SubscribeMessagesRequest, grpc.ServerStreamingServer[MPCMessage]) error {
return status.Error(codes.Unimplemented, "method SubscribeMessages not implemented")
}
func (UnimplementedMessageRouterServer) GetPendingMessages(context.Context, *GetPendingMessagesRequest) (*GetPendingMessagesResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetPendingMessages not implemented")
}
func (UnimplementedMessageRouterServer) AcknowledgeMessage(context.Context, *AcknowledgeMessageRequest) (*AcknowledgeMessageResponse, error) {
return nil, status.Error(codes.Unimplemented, "method AcknowledgeMessage not implemented")
}
func (UnimplementedMessageRouterServer) GetMessageStatus(context.Context, *GetMessageStatusRequest) (*GetMessageStatusResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetMessageStatus not implemented")
}
func (UnimplementedMessageRouterServer) RegisterParty(context.Context, *RegisterPartyRequest) (*RegisterPartyResponse, error) {
return nil, status.Error(codes.Unimplemented, "method RegisterParty not implemented")
}
func (UnimplementedMessageRouterServer) Heartbeat(context.Context, *HeartbeatRequest) (*HeartbeatResponse, error) {
return nil, status.Error(codes.Unimplemented, "method Heartbeat not implemented")
}
func (UnimplementedMessageRouterServer) SubscribeSessionEvents(*SubscribeSessionEventsRequest, grpc.ServerStreamingServer[SessionEvent]) error {
return status.Error(codes.Unimplemented, "method SubscribeSessionEvents not implemented")
}
func (UnimplementedMessageRouterServer) PublishSessionEvent(context.Context, *PublishSessionEventRequest) (*PublishSessionEventResponse, error) {
return nil, status.Error(codes.Unimplemented, "method PublishSessionEvent not implemented")
}
func (UnimplementedMessageRouterServer) GetRegisteredParties(context.Context, *GetRegisteredPartiesRequest) (*GetRegisteredPartiesResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetRegisteredParties not implemented")
}
func (UnimplementedMessageRouterServer) JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method JoinSession not implemented")
}
func (UnimplementedMessageRouterServer) MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error) {
return nil, status.Error(codes.Unimplemented, "method MarkPartyReady not implemented")
}
func (UnimplementedMessageRouterServer) ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ReportCompletion not implemented")
}
func (UnimplementedMessageRouterServer) GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetSessionStatus not implemented")
}
func (UnimplementedMessageRouterServer) SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error) {
return nil, status.Error(codes.Unimplemented, "method SubmitDelegateShare not implemented")
}
func (UnimplementedMessageRouterServer) mustEmbedUnimplementedMessageRouterServer() {}
func (UnimplementedMessageRouterServer) testEmbeddedByValue() {}
// 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) {
// If the following call panics, it indicates UnimplementedMessageRouterServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
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, &grpc.GenericServerStream[SubscribeMessagesRequest, MPCMessage]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type MessageRouter_SubscribeMessagesServer = grpc.ServerStreamingServer[MPCMessage]
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)
}
func _MessageRouter_AcknowledgeMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AcknowledgeMessageRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).AcknowledgeMessage(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_AcknowledgeMessage_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).AcknowledgeMessage(ctx, req.(*AcknowledgeMessageRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_GetMessageStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetMessageStatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).GetMessageStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_GetMessageStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).GetMessageStatus(ctx, req.(*GetMessageStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_RegisterParty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RegisterPartyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).RegisterParty(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_RegisterParty_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).RegisterParty(ctx, req.(*RegisterPartyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_Heartbeat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HeartbeatRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).Heartbeat(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_Heartbeat_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).Heartbeat(ctx, req.(*HeartbeatRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_SubscribeSessionEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeSessionEventsRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(MessageRouterServer).SubscribeSessionEvents(m, &grpc.GenericServerStream[SubscribeSessionEventsRequest, SessionEvent]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type MessageRouter_SubscribeSessionEventsServer = grpc.ServerStreamingServer[SessionEvent]
func _MessageRouter_PublishSessionEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PublishSessionEventRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).PublishSessionEvent(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_PublishSessionEvent_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).PublishSessionEvent(ctx, req.(*PublishSessionEventRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_GetRegisteredParties_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetRegisteredPartiesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).GetRegisteredParties(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_GetRegisteredParties_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).GetRegisteredParties(ctx, req.(*GetRegisteredPartiesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_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.(MessageRouterServer).JoinSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_JoinSession_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).JoinSession(ctx, req.(*JoinSessionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_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.(MessageRouterServer).MarkPartyReady(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_MarkPartyReady_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).MarkPartyReady(ctx, req.(*MarkPartyReadyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_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.(MessageRouterServer).ReportCompletion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_ReportCompletion_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).ReportCompletion(ctx, req.(*ReportCompletionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_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.(MessageRouterServer).GetSessionStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_GetSessionStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).GetSessionStatus(ctx, req.(*GetSessionStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MessageRouter_SubmitDelegateShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SubmitDelegateShareRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MessageRouterServer).SubmitDelegateShare(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MessageRouter_SubmitDelegateShare_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MessageRouterServer).SubmitDelegateShare(ctx, req.(*SubmitDelegateShareRequest))
}
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,
},
{
MethodName: "AcknowledgeMessage",
Handler: _MessageRouter_AcknowledgeMessage_Handler,
},
{
MethodName: "GetMessageStatus",
Handler: _MessageRouter_GetMessageStatus_Handler,
},
{
MethodName: "RegisterParty",
Handler: _MessageRouter_RegisterParty_Handler,
},
{
MethodName: "Heartbeat",
Handler: _MessageRouter_Heartbeat_Handler,
},
{
MethodName: "PublishSessionEvent",
Handler: _MessageRouter_PublishSessionEvent_Handler,
},
{
MethodName: "GetRegisteredParties",
Handler: _MessageRouter_GetRegisteredParties_Handler,
},
{
MethodName: "JoinSession",
Handler: _MessageRouter_JoinSession_Handler,
},
{
MethodName: "MarkPartyReady",
Handler: _MessageRouter_MarkPartyReady_Handler,
},
{
MethodName: "ReportCompletion",
Handler: _MessageRouter_ReportCompletion_Handler,
},
{
MethodName: "GetSessionStatus",
Handler: _MessageRouter_GetSessionStatus_Handler,
},
{
MethodName: "SubmitDelegateShare",
Handler: _MessageRouter_SubmitDelegateShare_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SubscribeMessages",
Handler: _MessageRouter_SubscribeMessages_Handler,
ServerStreams: true,
},
{
StreamName: "SubscribeSessionEvents",
Handler: _MessageRouter_SubscribeSessionEvents_Handler,
ServerStreams: true,
},
},
Metadata: "api/proto/message_router.proto",
}

File diff suppressed because it is too large Load Diff

View File

@ -1,395 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.0
// - protoc v6.33.1
// 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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
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"
SessionCoordinator_SubmitDelegateShare_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/SubmitDelegateShare"
)
// 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.
//
// SessionCoordinator service manages MPC sessions
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)
// Delegate party share submission (delegate party submits user's share after keygen)
SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, 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) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CreateSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_CreateSession_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(JoinSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_JoinSession_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetSessionStatusResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_GetSessionStatus_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(MarkPartyReadyResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_MarkPartyReady_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) StartSession(ctx context.Context, in *StartSessionRequest, opts ...grpc.CallOption) (*StartSessionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StartSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_StartSession_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ReportCompletionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_ReportCompletion_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) CloseSession(ctx context.Context, in *CloseSessionRequest, opts ...grpc.CallOption) (*CloseSessionResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CloseSessionResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_CloseSession_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sessionCoordinatorClient) SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SubmitDelegateShareResponse)
err := c.cc.Invoke(ctx, SessionCoordinator_SubmitDelegateShare_FullMethodName, in, out, cOpts...)
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.
//
// SessionCoordinator service manages MPC sessions
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)
// Delegate party share submission (delegate party submits user's share after keygen)
SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error)
mustEmbedUnimplementedSessionCoordinatorServer()
}
// UnimplementedSessionCoordinatorServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedSessionCoordinatorServer struct{}
func (UnimplementedSessionCoordinatorServer) CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method CreateSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method JoinSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetSessionStatus not implemented")
}
func (UnimplementedSessionCoordinatorServer) MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error) {
return nil, status.Error(codes.Unimplemented, "method MarkPartyReady not implemented")
}
func (UnimplementedSessionCoordinatorServer) StartSession(context.Context, *StartSessionRequest) (*StartSessionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method StartSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ReportCompletion not implemented")
}
func (UnimplementedSessionCoordinatorServer) CloseSession(context.Context, *CloseSessionRequest) (*CloseSessionResponse, error) {
return nil, status.Error(codes.Unimplemented, "method CloseSession not implemented")
}
func (UnimplementedSessionCoordinatorServer) SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error) {
return nil, status.Error(codes.Unimplemented, "method SubmitDelegateShare not implemented")
}
func (UnimplementedSessionCoordinatorServer) mustEmbedUnimplementedSessionCoordinatorServer() {}
func (UnimplementedSessionCoordinatorServer) testEmbeddedByValue() {}
// 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) {
// If the following call panics, it indicates UnimplementedSessionCoordinatorServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
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)
}
func _SessionCoordinator_SubmitDelegateShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SubmitDelegateShareRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionCoordinatorServer).SubmitDelegateShare(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SessionCoordinator_SubmitDelegateShare_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionCoordinatorServer).SubmitDelegateShare(ctx, req.(*SubmitDelegateShareRequest))
}
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,
},
{
MethodName: "SubmitDelegateShare",
Handler: _SessionCoordinator_SubmitDelegateShare_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/proto/session_coordinator.proto",
}

View File

@ -510,11 +510,12 @@ func (s *MessageRouterServer) JoinSession(
if coordResp.SessionInfo != nil {
resp.SessionInfo = &pb.SessionInfo{
SessionId: req.SessionId,
SessionType: coordResp.SessionInfo.SessionType,
ThresholdN: coordResp.SessionInfo.ThresholdN,
ThresholdT: coordResp.SessionInfo.ThresholdT,
MessageHash: coordResp.SessionInfo.MessageHash,
SessionId: req.SessionId,
SessionType: coordResp.SessionInfo.SessionType,
ThresholdN: coordResp.SessionInfo.ThresholdN,
ThresholdT: coordResp.SessionInfo.ThresholdT,
MessageHash: coordResp.SessionInfo.MessageHash,
KeygenSessionId: coordResp.SessionInfo.KeygenSessionId,
}
}

View File

@ -673,6 +673,13 @@ func (c *MessageRouterClient) JoinSession(
sessionInfo.ThresholdN = int(resp.SessionInfo.ThresholdN)
sessionInfo.ThresholdT = int(resp.SessionInfo.ThresholdT)
sessionInfo.MessageHash = resp.SessionInfo.MessageHash
// Parse keygen_session_id if provided (for signing sessions)
if resp.SessionInfo.KeygenSessionId != "" {
if keygenID, err := uuid.Parse(resp.SessionInfo.KeygenSessionId); err == nil {
sessionInfo.KeygenSessionID = keygenID
}
}
}
logger.Info("Joined session via Message Router",

View File

@ -160,6 +160,18 @@ func (s *SessionCoordinatorServer) CreateSession(
ExpiresIn: time.Duration(req.ExpiresInSeconds) * time.Second,
}
// Parse and set keygen_session_id if provided (for signing sessions)
if req.KeygenSessionId != "" {
keygenSessionID, err := uuid.Parse(req.KeygenSessionId)
if err == nil {
inputData.KeygenSessionID = keygenSessionID
} else {
logger.Warn("Invalid keygen_session_id format",
zap.String("keygen_session_id", req.KeygenSessionId),
zap.Error(err))
}
}
// Add party composition if provided (for automatic party selection)
if req.PartyComposition != nil {
inputData.PartyComposition = &input.PartyComposition{
@ -270,15 +282,22 @@ func (s *SessionCoordinatorServer) JoinSession(
zap.Int32("proto_party_index", otherParties[i].PartyIndex))
}
// Convert keygen_session_id to string (empty if nil)
keygenSessionIDStr := ""
if output.SessionInfo.KeygenSessionID != uuid.Nil {
keygenSessionIDStr = output.SessionInfo.KeygenSessionID.String()
}
return &pb.JoinSessionResponse{
Success: output.Success,
SessionInfo: &pb.SessionInfo{
SessionId: output.SessionInfo.SessionID.String(),
SessionType: output.SessionInfo.SessionType,
ThresholdN: int32(output.SessionInfo.ThresholdN),
ThresholdT: int32(output.SessionInfo.ThresholdT),
MessageHash: output.SessionInfo.MessageHash,
Status: output.SessionInfo.Status,
SessionId: output.SessionInfo.SessionID.String(),
SessionType: output.SessionInfo.SessionType,
ThresholdN: int32(output.SessionInfo.ThresholdN),
ThresholdT: int32(output.SessionInfo.ThresholdT),
MessageHash: output.SessionInfo.MessageHash,
Status: output.SessionInfo.Status,
KeygenSessionId: keygenSessionIDStr,
},
OtherParties: otherParties,
PartyIndex: int32(output.PartyIndex),

View File

@ -37,13 +37,14 @@ func (r *SessionPostgresRepo) Save(ctx context.Context, session *entities.MPCSes
_, err = tx.ExecContext(ctx, `
INSERT INTO mpc_sessions (
id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, delegate_party_id, created_by, created_at, updated_at, expires_at, completed_at, version
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
ON CONFLICT (id) DO UPDATE SET
status = EXCLUDED.status,
message_hash = EXCLUDED.message_hash,
public_key = EXCLUDED.public_key,
delegate_party_id = EXCLUDED.delegate_party_id,
keygen_session_id = EXCLUDED.keygen_session_id,
updated_at = EXCLUDED.updated_at,
completed_at = EXCLUDED.completed_at,
version = EXCLUDED.version
@ -56,6 +57,7 @@ func (r *SessionPostgresRepo) Save(ctx context.Context, session *entities.MPCSes
session.MessageHash,
session.PublicKey,
session.DelegatePartyID,
nullUUID(session.KeygenSessionID),
session.CreatedBy,
session.CreatedAt,
session.UpdatedAt,
@ -118,7 +120,7 @@ func (r *SessionPostgresRepo) FindByUUID(ctx context.Context, id uuid.UUID) (*en
var session sessionRow
err := r.db.QueryRowContext(ctx, `
SELECT id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, delegate_party_id, created_by, created_at, updated_at, expires_at, completed_at, version
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
FROM mpc_sessions WHERE id = $1
`, id).Scan(
&session.ID,
@ -129,6 +131,7 @@ func (r *SessionPostgresRepo) FindByUUID(ctx context.Context, id uuid.UUID) (*en
&session.MessageHash,
&session.PublicKey,
&session.DelegatePartyID,
&session.KeygenSessionID,
&session.CreatedBy,
&session.CreatedAt,
&session.UpdatedAt,
@ -149,6 +152,12 @@ func (r *SessionPostgresRepo) FindByUUID(ctx context.Context, id uuid.UUID) (*en
return nil, err
}
// Convert nullable KeygenSessionID
var keygenSessionID uuid.UUID
if session.KeygenSessionID != nil {
keygenSessionID = *session.KeygenSessionID
}
return entities.ReconstructSession(
session.ID,
session.SessionType,
@ -158,6 +167,7 @@ func (r *SessionPostgresRepo) FindByUUID(ctx context.Context, id uuid.UUID) (*en
session.MessageHash,
session.PublicKey,
session.DelegatePartyID,
keygenSessionID,
session.CreatedBy,
session.CreatedAt,
session.UpdatedAt,
@ -172,7 +182,7 @@ func (r *SessionPostgresRepo) FindByUUID(ctx context.Context, id uuid.UUID) (*en
func (r *SessionPostgresRepo) FindByStatus(ctx context.Context, status value_objects.SessionStatus) ([]*entities.MPCSession, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, delegate_party_id, created_by, created_at, updated_at, expires_at, completed_at, version
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
FROM mpc_sessions WHERE status = $1
`, status.String())
if err != nil {
@ -187,7 +197,7 @@ func (r *SessionPostgresRepo) FindByStatus(ctx context.Context, status value_obj
func (r *SessionPostgresRepo) FindExpired(ctx context.Context) ([]*entities.MPCSession, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, delegate_party_id, created_by, created_at, updated_at, expires_at, completed_at, version
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
FROM mpc_sessions
WHERE expires_at < NOW() AND status IN ('created', 'in_progress')
`)
@ -203,7 +213,7 @@ func (r *SessionPostgresRepo) FindExpired(ctx context.Context) ([]*entities.MPCS
func (r *SessionPostgresRepo) FindActive(ctx context.Context) ([]*entities.MPCSession, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, delegate_party_id, created_by, created_at, updated_at, expires_at, completed_at, version
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
FROM mpc_sessions
WHERE status IN ('created', 'in_progress')
ORDER BY created_at ASC
@ -220,7 +230,7 @@ func (r *SessionPostgresRepo) FindActive(ctx context.Context) ([]*entities.MPCSe
func (r *SessionPostgresRepo) FindByCreator(ctx context.Context, creatorID string) ([]*entities.MPCSession, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, session_type, threshold_n, threshold_t, status,
message_hash, public_key, created_by, created_at, updated_at, expires_at, completed_at, version
message_hash, public_key, delegate_party_id, keygen_session_id, created_by, created_at, updated_at, expires_at, completed_at, version
FROM mpc_sessions WHERE created_by = $1
ORDER BY created_at DESC
`, creatorID)
@ -236,7 +246,7 @@ func (r *SessionPostgresRepo) FindByCreator(ctx context.Context, creatorID strin
func (r *SessionPostgresRepo) FindActiveByParticipant(ctx context.Context, partyID value_objects.PartyID) ([]*entities.MPCSession, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT s.id, s.session_type, s.threshold_n, s.threshold_t, s.status,
s.message_hash, s.public_key, s.created_by, s.created_at, s.updated_at, s.expires_at, s.completed_at, s.version
s.message_hash, s.public_key, s.delegate_party_id, s.keygen_session_id, s.created_by, s.created_at, s.updated_at, s.expires_at, s.completed_at, s.version
FROM mpc_sessions s
JOIN participants p ON s.id = p.session_id
WHERE p.party_id = $1 AND s.status IN ('created', 'in_progress')
@ -487,6 +497,7 @@ func (r *SessionPostgresRepo) scanSessions(ctx context.Context, rows *sql.Rows)
&s.MessageHash,
&s.PublicKey,
&s.DelegatePartyID,
&s.KeygenSessionID,
&s.CreatedBy,
&s.CreatedAt,
&s.UpdatedAt,
@ -503,6 +514,12 @@ func (r *SessionPostgresRepo) scanSessions(ctx context.Context, rows *sql.Rows)
return nil, err
}
// Convert nullable KeygenSessionID
var keygenSessionID uuid.UUID
if s.KeygenSessionID != nil {
keygenSessionID = *s.KeygenSessionID
}
session, err := entities.ReconstructSession(
s.ID,
s.SessionType,
@ -512,6 +529,7 @@ func (r *SessionPostgresRepo) scanSessions(ctx context.Context, rows *sql.Rows)
s.MessageHash,
s.PublicKey,
s.DelegatePartyID,
keygenSessionID,
s.CreatedBy,
s.CreatedAt,
s.UpdatedAt,
@ -539,6 +557,7 @@ type sessionRow struct {
MessageHash []byte
PublicKey []byte
DelegatePartyID string
KeygenSessionID *uuid.UUID
CreatedBy string
CreatedAt time.Time
UpdatedAt time.Time
@ -565,3 +584,11 @@ var _ repositories.SessionRepository = (*SessionPostgresRepo)(nil)
// Use pq for array handling
var _ = pq.Array
// nullUUID converts a UUID to a nullable database value
func nullUUID(u uuid.UUID) interface{} {
if u == uuid.Nil {
return nil
}
return u
}

View File

@ -54,6 +54,7 @@ type CreateSessionInput struct {
MessageHash []byte // For sign sessions
ExpiresIn time.Duration
DelegateUserShare *DelegateUserShare // For sign sessions with delegate party
KeygenSessionID uuid.UUID // For sign sessions: which keygen session's shares to use
}
// ParticipantInfo contains information about a participant
@ -87,12 +88,13 @@ type JoinSessionOutput struct {
// SessionInfo contains session information
type SessionInfo struct {
SessionID uuid.UUID
SessionType string
ThresholdN int
ThresholdT int
MessageHash []byte
Status string
SessionID uuid.UUID
SessionType string
ThresholdN int
ThresholdT int
MessageHash []byte
Status string
KeygenSessionID uuid.UUID // For sign sessions: which keygen session's shares to use
}
// PartyInfo contains party information

View File

@ -130,6 +130,14 @@ func (uc *CreateSessionUseCase) Execute(
return nil, err
}
// 4.1 Set keygen_session_id for sign sessions
if req.KeygenSessionID != uuid.Nil {
session.KeygenSessionID = req.KeygenSessionID
logger.Info("Sign session created with keygen_session_id",
zap.String("session_id", session.ID.String()),
zap.String("keygen_session_id", req.KeygenSessionID.String()))
}
// 5. Add participants and generate join tokens
tokens := make(map[string]string)
if len(req.Participants) == 0 {

View File

@ -166,12 +166,13 @@ func (uc *JoinSessionUseCase) Execute(
Success: true,
PartyIndex: participant.PartyIndex,
SessionInfo: input.SessionInfo{
SessionID: session.ID.UUID(),
SessionType: string(session.SessionType),
ThresholdN: session.Threshold.N(),
ThresholdT: session.Threshold.T(),
MessageHash: session.MessageHash,
Status: session.Status.String(),
SessionID: session.ID.UUID(),
SessionType: string(session.SessionType),
ThresholdN: session.Threshold.N(),
ThresholdT: session.Threshold.T(),
MessageHash: session.MessageHash,
Status: session.Status.String(),
KeygenSessionID: session.KeygenSessionID,
},
OtherParties: partyInfos,
}, nil

View File

@ -385,6 +385,7 @@ func ReconstructSession(
status string,
messageHash, publicKey []byte,
delegatePartyID string,
keygenSessionID uuid.UUID,
createdBy string,
createdAt, updatedAt, expiresAt time.Time,
completedAt *time.Time,
@ -403,18 +404,19 @@ func ReconstructSession(
return &MPCSession{
ID: value_objects.SessionIDFromUUID(id),
SessionType: SessionType(sessionType),
Threshold: threshold,
Participants: participants,
Status: sessionStatus,
MessageHash: messageHash,
PublicKey: publicKey,
SessionType: SessionType(sessionType),
Threshold: threshold,
Participants: participants,
Status: sessionStatus,
MessageHash: messageHash,
PublicKey: publicKey,
DelegatePartyID: delegatePartyID,
CreatedBy: createdBy,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
ExpiresAt: expiresAt,
CompletedAt: completedAt,
Version: version,
KeygenSessionID: keygenSessionID,
CreatedBy: createdBy,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
ExpiresAt: expiresAt,
CompletedAt: completedAt,
Version: version,
}, nil
}