From cd1d2cf8d235aff88bd0ab7cb41d5e62708b8610 Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 30 Dec 2025 19:41:05 -0800 Subject: [PATCH] feat(account): add GET /sign/:sessionId endpoint for co-sign session status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../adapters/input/http/co_managed_handler.go | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go b/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go index 1df8112c..ddc05f3b 100644 --- a/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go +++ b/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go @@ -60,6 +60,7 @@ func (h *CoManagedHTTPHandler) RegisterRoutes(router *gin.RouterGroup) { // Sign session routes (new - does not affect existing functionality) coManaged.POST("/sign", h.CreateSignSession) + coManaged.GET("/sign/:sessionId", h.GetSignSessionStatus) coManaged.GET("/sign/by-invite-code/:inviteCode", h.GetSignSessionByInviteCode) } } @@ -588,6 +589,62 @@ func (h *CoManagedHTTPHandler) CreateSignSession(c *gin.Context) { }) } +// GetSignSessionStatus handles getting the status of a co-managed sign session +func (h *CoManagedHTTPHandler) GetSignSessionStatus(c *gin.Context) { + sessionID := c.Param("sessionId") + if sessionID == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "session_id is required"}) + return + } + + // Validate session ID format + if _, err := uuid.Parse(sessionID); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid session_id format"}) + return + } + + // 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 { + logger.Error("Failed to get sign session status", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + result := gin.H{ + "session_id": sessionID, + "status": resp.Status, + "session_type": resp.SessionType, + "threshold_t": resp.ThresholdT, + "threshold_n": resp.ThresholdN, + "completed_parties": resp.CompletedParties, + "total_parties": resp.TotalParties, + } + + // Add signature if sign completed + if resp.SessionType == "sign" && len(resp.Signature) > 0 { + result["signature"] = hex.EncodeToString(resp.Signature) + } + + // Include participants with party_index + if len(resp.Participants) > 0 { + participants := make([]gin.H, len(resp.Participants)) + for i, p := range resp.Participants { + participants[i] = gin.H{ + "party_id": p.PartyID, + "party_index": p.PartyIndex, + "status": p.Status, + } + } + result["participants"] = participants + } + + c.JSON(http.StatusOK, result) +} + // GetSignSessionByInviteCode handles looking up a sign session by its invite code // This is a completely new endpoint that does not affect existing functionality func (h *CoManagedHTTPHandler) GetSignSessionByInviteCode(c *gin.Context) {