diff --git a/backend/mpc-system/services/account/adapters/input/http/account_handler.go b/backend/mpc-system/services/account/adapters/input/http/account_handler.go index b8409344..8b0f9ce6 100644 --- a/backend/mpc-system/services/account/adapters/input/http/account_handler.go +++ b/backend/mpc-system/services/account/adapters/input/http/account_handler.go @@ -732,9 +732,10 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) { zap.String("username", req.Username), zap.Strings("configured_parties", partyIDs)) } else { - // For threshold signing, select minimum required parties (threshold_t) - // For 2-of-3, we need exactly 2 parties to sign (not all 3) - requiredParties := accountOutput.Account.ThresholdT + // For threshold signing, select minimum required parties (threshold_t + 1) + // TSS threshold semantics: for threshold t, we need t+1 signers + // For 2-of-3: t=1, so we need t+1=2 parties to sign + requiredParties := accountOutput.Account.ThresholdT + 1 if len(allActivePartyIDs) < requiredParties { c.JSON(http.StatusBadRequest, gin.H{ "error": "insufficient active parties for signing", @@ -744,12 +745,13 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) { return } - // Select first 'threshold_t' parties + // Select first 'threshold_t + 1' parties partyIDs = allActivePartyIDs[:requiredParties] logger.Info("Using minimum required parties for threshold signing", zap.String("username", req.Username), - zap.Int("threshold_t", requiredParties), + zap.Int("threshold_t", accountOutput.Account.ThresholdT), + zap.Int("required_signers", requiredParties), zap.Int("total_active", len(allActivePartyIDs)), zap.Strings("selected_parties", partyIDs)) }