From 2365a50b1b738ba741081291e3c5b3fcf4297721 Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 1 Jan 2026 22:41:51 -0800 Subject: [PATCH] feat(tss): add real-time round progress from msg.Type() parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract current round number from tss-lib message type string using regex pattern `Round(\d+)`. This enables real-time progress updates (1/4, 2/4... for keygen, 1/9, 2/9... for signing) instead of only showing completion status. Changes across all three platforms: - tss-wasm/main.go: Add extractRoundFromMessageType() and call OnProgress with parsed round on each outgoing message - service-party-android/tsslib/tsslib.go: Same implementation for Android gomobile binding - service-party-app/tss-party/main.go: Same implementation for Electron subprocess, with isKeygen parameter to distinguish keygen (4 rounds) vs signing (9 rounds) Safe fallback: Returns 0 if parsing fails, which doesn't affect protocol execution - only UI display. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../service-party-android/tsslib/tsslib.go | 28 +++++++++++++++ .../service-party-app/tss-party/main.go | 36 ++++++++++++++++--- backend/mpc-system/services/tss-wasm/main.go | 25 +++++++++++-- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/backend/mpc-system/services/service-party-android/tsslib/tsslib.go b/backend/mpc-system/services/service-party-android/tsslib/tsslib.go index d2784439..abdc731c 100644 --- a/backend/mpc-system/services/service-party-android/tsslib/tsslib.go +++ b/backend/mpc-system/services/service-party-android/tsslib/tsslib.go @@ -11,6 +11,8 @@ import ( "encoding/json" "fmt" "math/big" + "regexp" + "strconv" "sync" "time" @@ -20,6 +22,11 @@ import ( "github.com/bnb-chain/tss-lib/v2/tss" ) +// Regex to extract round number from tss-lib message type +// Message types look like: "binance.tsslib.ecdsa.keygen.KGRound1Message" +// or "binance.tsslib.ecdsa.signing.SignRound3Message" +var roundRegex = regexp.MustCompile(`Round(\d+)`) + // MessageCallback is the interface for receiving TSS protocol messages // Android side implements this interface to handle message routing type MessageCallback interface { @@ -531,6 +538,19 @@ func CancelSession() { } } +// extractRoundFromMessageType parses the round number from a tss-lib message type string. +// Returns 0 if parsing fails (safe fallback). +// Example: "binance.tsslib.ecdsa.keygen.KGRound2Message1" -> 2 +func extractRoundFromMessageType(msgType string) int { + matches := roundRegex.FindStringSubmatch(msgType) + if len(matches) >= 2 { + if round, err := strconv.Atoi(matches[1]); err == nil { + return round + } + } + return 0 // Safe fallback - doesn't affect protocol, just shows 0 in UI +} + func (s *tssSession) handleOutgoingMessage(msg tss.Message) { msgBytes, _, err := msg.WireBytes() if err != nil { @@ -558,6 +578,14 @@ func (s *tssSession) handleOutgoingMessage(msg tss.Message) { data, _ := json.Marshal(outMsg) s.callback.OnOutgoingMessage(string(data)) + + // Extract current round from message type and send progress update + totalRounds := 4 // GG20 keygen has 4 rounds + if !s.isKeygen { + totalRounds = 9 // GG20 signing has 9 rounds + } + currentRound := extractRoundFromMessageType(msg.Type()) + s.callback.OnProgress(currentRound, totalRounds) } func isDuplicateError(err error) bool { diff --git a/backend/mpc-system/services/service-party-app/tss-party/main.go b/backend/mpc-system/services/service-party-app/tss-party/main.go index 66bc367c..2e6ab20b 100644 --- a/backend/mpc-system/services/service-party-app/tss-party/main.go +++ b/backend/mpc-system/services/service-party-app/tss-party/main.go @@ -15,6 +15,8 @@ import ( "math/big" "os" "os/signal" + "regexp" + "strconv" "sync" "syscall" "time" @@ -25,6 +27,11 @@ import ( "github.com/bnb-chain/tss-lib/v2/tss" ) +// Regex to extract round number from tss-lib message type +// Message types look like: "binance.tsslib.ecdsa.keygen.KGRound1Message" +// or "binance.tsslib.ecdsa.signing.SignRound3Message" +var roundRegex = regexp.MustCompile(`Round(\d+)`) + // Message types for IPC type Message struct { Type string `json:"type"` @@ -290,7 +297,7 @@ func executeKeygen( if !ok { return } - handleOutgoingMessage(msg) + handleOutgoingMessage(msg, true) // isKeygen = true } } }() @@ -321,7 +328,7 @@ func executeKeygen( } }() - // Track progress + // Track progress (final completion reporting) totalRounds := 4 // GG20 keygen has 4 rounds // Wait for completion @@ -357,7 +364,20 @@ func executeKeygen( } } -func handleOutgoingMessage(msg tss.Message) { +// extractRoundFromMessageType parses the round number from a tss-lib message type string. +// Returns 0 if parsing fails (safe fallback). +// Example: "binance.tsslib.ecdsa.keygen.KGRound2Message1" -> 2 +func extractRoundFromMessageType(msgType string) int { + matches := roundRegex.FindStringSubmatch(msgType) + if len(matches) >= 2 { + if round, err := strconv.Atoi(matches[1]); err == nil { + return round + } + } + return 0 // Safe fallback - doesn't affect protocol, just shows 0 in UI +} + +func handleOutgoingMessage(msg tss.Message, isKeygen bool) { msgBytes, _, err := msg.WireBytes() if err != nil { return @@ -379,6 +399,14 @@ func handleOutgoingMessage(msg tss.Message) { data, _ := json.Marshal(outMsg) fmt.Println(string(data)) + + // Extract current round from message type and send progress update + totalRounds := 4 // GG20 keygen has 4 rounds + if !isKeygen { + totalRounds = 9 // GG20 signing has 9 rounds + } + currentRound := extractRoundFromMessageType(msg.Type()) + sendProgress(currentRound, totalRounds) } func handleIncomingMessage( @@ -682,7 +710,7 @@ func executeSign( if !ok { return } - handleOutgoingMessage(msg) + handleOutgoingMessage(msg, false) // isKeygen = false (signing) } } }() diff --git a/backend/mpc-system/services/tss-wasm/main.go b/backend/mpc-system/services/tss-wasm/main.go index d7f4ef13..5fe2c2a8 100644 --- a/backend/mpc-system/services/tss-wasm/main.go +++ b/backend/mpc-system/services/tss-wasm/main.go @@ -10,6 +10,8 @@ import ( "encoding/json" "fmt" "math/big" + "regexp" + "strconv" "sync" "syscall/js" @@ -19,6 +21,11 @@ import ( "github.com/bnb-chain/tss-lib/v2/tss" ) +// Regex to extract round number from tss-lib message type +// Message types look like: "binance.tsslib.ecdsa.keygen.KGRound1Message" +// or "binance.tsslib.ecdsa.signing.SignRound3Message" +var roundRegex = regexp.MustCompile(`Round(\d+)`) + // Global state for active sessions var ( activeSessions = make(map[string]*TSSSession) @@ -401,6 +408,19 @@ func stopSession(this js.Value, args []js.Value) interface{} { return createSuccessResult(nil) } +// extractRoundFromMessageType parses the round number from a tss-lib message type string. +// Returns 0 if parsing fails (safe fallback). +// Example: "binance.tsslib.ecdsa.keygen.KGRound2Message1" -> 2 +func extractRoundFromMessageType(msgType string) int { + matches := roundRegex.FindStringSubmatch(msgType) + if len(matches) >= 2 { + if round, err := strconv.Atoi(matches[1]); err == nil { + return round + } + } + return 0 // Safe fallback - doesn't affect protocol, just shows 0 in UI +} + // handleOutgoingMessages processes messages from the TSS protocol func (s *TSSSession) handleOutgoingMessages() { totalRounds := 4 // GG20 keygen has 4 rounds @@ -440,8 +460,9 @@ func (s *TSSSession) handleOutgoingMessages() { jsMsgJSON, _ := json.Marshal(jsMsg) s.OnMessage.Invoke(string(jsMsgJSON)) - // Send progress update - s.OnProgress.Invoke(totalRounds, totalRounds) // Simplified progress + // Extract current round from message type and send progress update + currentRound := extractRoundFromMessageType(msg.Type()) + s.OnProgress.Invoke(currentRound, totalRounds) } } }