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 6be70714..e0b5d372 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 @@ -574,17 +574,18 @@ func (h *CoManagedHTTPHandler) CreateSignSession(c *gin.Context) { zap.Int("num_parties", len(resp.SelectedParties))) c.JSON(http.StatusCreated, gin.H{ - "session_id": resp.SessionID, - "keygen_session_id": req.KeygenSessionID, - "wallet_name": req.WalletName, - "invite_code": inviteCode, - "join_token": wildcardToken, - "threshold_t": req.ThresholdT, - "selected_parties": resp.SelectedParties, - "status": "waiting_for_participants", - "current_participants": 0, + "session_id": resp.SessionID, + "keygen_session_id": req.KeygenSessionID, + "wallet_name": req.WalletName, + "invite_code": inviteCode, + "join_token": wildcardToken, + "threshold_t": req.ThresholdT, + "parties": req.Parties, // 返回完整的 parties (包含 party_id 和 party_index) + "selected_parties": resp.SelectedParties, + "status": "waiting_for_participants", + "current_participants": 0, "required_participants": len(req.Parties), - "expires_at": resp.ExpiresAt, + "expires_at": resp.ExpiresAt, }) } diff --git a/backend/mpc-system/services/service-party-app/electron/main.ts b/backend/mpc-system/services/service-party-app/electron/main.ts index c0f9e2ce..8bd105e9 100644 --- a/backend/mpc-system/services/service-party-app/electron/main.ts +++ b/backend/mpc-system/services/service-party-app/electron/main.ts @@ -564,10 +564,10 @@ async function handleKeygenComplete(result: KeygenResult) { try { // 1. 保存 share 到本地数据库 const publicKeyHex = result.publicKey.toString('hex'); - // 转换 participants 格式:保存 partyId, partyIndex, name + // 转换 participants 格式:从 { partyId, partyIndex, name } 到 { partyId, name } + // 注意:partyIndex 不保存到本地,签名时需要从 Account Service 获取 const participantsForSave = activeKeygenSession.participants.map(p => ({ partyId: p.partyId, - partyIndex: p.partyIndex, name: p.name, })); const saved = database.saveShare({ @@ -1219,11 +1219,16 @@ function setupIpcHandlers() { return { success: false, error: 'Share not found or incorrect password' }; } - // 解析 participants_json 获取参与方列表 - const participants = JSON.parse(share.participants_json || '[]'); - const parties = participants.map((p: { partyId: string; partyIndex?: number }, index: number) => ({ - party_id: p.partyId, - party_index: p.partyIndex ?? index, // 优先使用保存的 partyIndex,否则使用数组索引 + // 从 Account Service 查询 keygen session 获取正确的 participants(包含 party_index) + const sessionStatus = await accountClient?.getSessionStatus(share.session_id); + if (!sessionStatus?.participants || sessionStatus.participants.length === 0) { + return { success: false, error: 'Failed to get participants from keygen session' }; + } + + // 使用后端返回的 participants(包含正确的 party_index) + const parties = sessionStatus.participants.map(p => ({ + party_id: p.party_id, + party_index: p.party_index, })); const result = await accountClient?.createSignSession({ @@ -1241,6 +1246,7 @@ function setupIpcHandlers() { inviteCode: result?.invite_code, expiresAt: result?.expires_at, joinToken: result?.join_token, + parties: result?.parties, // 包含正确的 party_id 和 party_index }; } catch (error) { return { success: false, error: (error as Error).message }; diff --git a/backend/mpc-system/services/service-party-app/electron/modules/database.ts b/backend/mpc-system/services/service-party-app/electron/modules/database.ts index 4498733d..239db4c7 100644 --- a/backend/mpc-system/services/service-party-app/electron/modules/database.ts +++ b/backend/mpc-system/services/service-party-app/electron/modules/database.ts @@ -339,7 +339,7 @@ export class DatabaseManager { thresholdN: number; publicKeyHex: string; rawShare: string; - participants: Array<{ partyId: string; name: string }>; + participants: Array<{ partyId: string; partyIndex?: number; name: string }>; }, password: string): ShareRecord { if (!this.db) throw new Error('Database not initialized'); diff --git a/backend/mpc-system/services/service-party-app/src/pages/Transfer.tsx b/backend/mpc-system/services/service-party-app/src/pages/Transfer.tsx index 3c8568fd..b332e63e 100644 --- a/backend/mpc-system/services/service-party-app/src/pages/Transfer.tsx +++ b/backend/mpc-system/services/service-party-app/src/pages/Transfer.tsx @@ -60,6 +60,7 @@ export default function Transfer() { // 签名会话 const [inviteCode, setInviteCode] = useState(''); const [signSessionId, setSignSessionId] = useState(''); + const [signParties, setSignParties] = useState>([]); // 错误信息 const [error, setError] = useState(''); @@ -215,6 +216,7 @@ export default function Transfer() { setInviteCode(result.inviteCode || ''); setSignSessionId(result.sessionId || ''); + setSignParties(result.parties || []); setTxHash(messageHash); // 显示邀请码,等待用户通知其他参与方 @@ -231,11 +233,17 @@ export default function Transfer() { if (!txParams || !share || !txHash || !signSessionId) return; try { - // 构建 participants 列表 - const participants = (share.participants || []).map((p, index) => ({ - partyId: p.partyId, - partyIndex: p.partyIndex ?? index, // 优先使用保存的 partyIndex - })); + // 使用创建签名会话时返回的 parties(包含正确的 party_index) + // 如果没有,则 fallback 到本地 share 的 participants + const participants = signParties.length > 0 + ? signParties.map(p => ({ + partyId: p.party_id, + partyIndex: p.party_index, + })) + : (share.participants || []).map((p, index) => ({ + partyId: p.partyId, + partyIndex: p.partyIndex ?? index, + })); // 执行 TSS 签名 if (window.electronAPI) {