From e81757ad832d88ecf4db4a30ed61db2e752c532d Mon Sep 17 00:00:00 2001 From: hailin Date: Wed, 31 Dec 2025 07:44:17 -0800 Subject: [PATCH] fix(co-sign): convert user-friendly threshold to tss-lib format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename thresholdT/thresholdN to requiredSigners/totalParties in Create.tsx - Add parameter conversion in main.ts: threshold_t = requiredSigners - 1 - In tss-lib, threshold t means t+1 parties needed to sign - For 3-of-5: requiredSigners=3 → threshold_t=2 (t+1=3 signers) - externalCount = requiredSigners (user parties) - persistentCount = totalParties - requiredSigners (server parties) - Backward compatible with legacy thresholdT/thresholdN format BREAKING: Existing co-managed wallets need re-keygen with new params 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../service-party-app/electron/main.ts | 56 ++++++++++++++--- .../service-party-app/src/pages/Create.tsx | 60 +++++++++++-------- .../service-party-app/src/types/electron.d.ts | 8 ++- 3 files changed, 88 insertions(+), 36 deletions(-) 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 a760ac9a..086af62c 100644 --- a/backend/mpc-system/services/service-party-app/electron/main.ts +++ b/backend/mpc-system/services/service-party-app/electron/main.ts @@ -1226,16 +1226,54 @@ function setupIpcHandlers() { return { success: false, error: '请先连接到消息路由器' }; } - // 动态计算 server-party 数量: persistent = n - t - // 例如: 2-of-3 -> persistent=1, 3-of-5 -> persistent=2, 4-of-7 -> persistent=3 - // 这样平台备份方数量等于"允许丢失的份额数",确保用户丢失密钥后仍可恢复 - const persistentCount = params.thresholdN - params.thresholdT; - const externalCount = params.thresholdT; // 用户持有的份额数量 + // Support both old format (thresholdT, thresholdN) and new format (requiredSigners, totalParties) + // New format uses user-friendly "required signers" which needs conversion to tss-lib threshold + let thresholdT: number; + let thresholdN: number; + let externalCount: number; + let persistentCount: number; + + if (params.requiredSigners !== undefined && params.totalParties !== undefined) { + // New format: Convert user-friendly parameters to tss-lib parameters + // In tss-lib, threshold_t means you need (t+1) parties to sign + // So if user wants 3 signers, threshold_t = 3 - 1 = 2 + const requiredSigners = params.requiredSigners; + const totalParties = params.totalParties; + + thresholdT = requiredSigners - 1; // tss-lib threshold + thresholdN = totalParties; + externalCount = requiredSigners; // user parties = required signers + persistentCount = totalParties - requiredSigners; // server backup parties + + console.log('[CreateSession] Converting user-friendly params to tss-lib:', { + requiredSigners, + totalParties, + 'tss-lib threshold_t': thresholdT, + 'tss-lib threshold_n': thresholdN, + externalCount, + persistentCount, + }); + } else { + // Old format: Use thresholdT and thresholdN directly (backward compatible) + thresholdT = params.thresholdT; + thresholdN = params.thresholdN; + // 动态计算 server-party 数量: persistent = n - t + // 例如: 2-of-3 -> persistent=1, 3-of-5 -> persistent=2, 4-of-7 -> persistent=3 + persistentCount = thresholdN - thresholdT; + externalCount = thresholdT; + + console.log('[CreateSession] Using legacy params (backward compatible):', { + thresholdT, + thresholdN, + externalCount, + persistentCount, + }); + } const result = await accountClient?.createKeygenSession({ wallet_name: params.walletName, - threshold_t: params.thresholdT, - threshold_n: params.thresholdN, + threshold_t: thresholdT, + threshold_n: thresholdN, initiator_party_id: partyId, initiator_name: params.initiatorName || '发起者', persistent_count: persistentCount, @@ -1271,8 +1309,8 @@ function setupIpcHandlers() { partyIndex: joinResult.party_index, participants: participants, threshold: { - t: params.thresholdT, - n: params.thresholdN, + t: thresholdT, + n: thresholdN, }, walletName: params.walletName, encryptionPassword: '', // 不使用加密密码 diff --git a/backend/mpc-system/services/service-party-app/src/pages/Create.tsx b/backend/mpc-system/services/service-party-app/src/pages/Create.tsx index 76e7226a..f0a62433 100644 --- a/backend/mpc-system/services/service-party-app/src/pages/Create.tsx +++ b/backend/mpc-system/services/service-party-app/src/pages/Create.tsx @@ -13,8 +13,11 @@ export default function Create() { const navigate = useNavigate(); const [walletName, setWalletName] = useState(''); - const [thresholdT, setThresholdT] = useState(3); - const [thresholdN, setThresholdN] = useState(5); + // requiredSigners: 用户选择的"需要几人签名"(用户直观理解) + // 例如:用户选择 3 表示需要 3 人签名 + // 在 tss-lib 中,threshold_t = requiredSigners - 1(因为 tss-lib 需要 t+1 人签名) + const [requiredSigners, setRequiredSigners] = useState(3); + const [totalParties, setTotalParties] = useState(5); const [participantName, setParticipantName] = useState(''); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); @@ -30,15 +33,15 @@ export default function Create() { setError('请输入您的名称'); return; } - if (thresholdT > thresholdN) { - setError('签名阈值不能大于参与方总数'); + if (requiredSigners > totalParties) { + setError('签名人数不能大于参与方总数'); return; } - if (thresholdT < 1) { - setError('签名阈值至少为 1'); + if (requiredSigners < 2) { + setError('签名人数至少为 2'); return; } - if (thresholdN < 2) { + if (totalParties < 2) { setError('参与方总数至少为 2'); return; } @@ -48,10 +51,17 @@ export default function Create() { setError(null); try { + // Pass user-friendly parameters directly + // main.ts will convert to tss-lib parameters + console.log('[Create] Sending parameters:', { + requiredSigners, + totalParties, + }); + const createResult = await window.electronAPI.grpc.createSession({ walletName: walletName.trim(), - thresholdT, - thresholdN, + requiredSigners, + totalParties, initiatorName: participantName.trim(), }); @@ -122,23 +132,23 @@ export default function Create() {
- +
- 签名阈值 (T) + 需要签名人数
- {thresholdT} + {requiredSigners} @@ -146,24 +156,24 @@ export default function Create() {
of
- 参与方总数 (N) + 参与方总数
- {thresholdN} + {totalParties} @@ -171,7 +181,7 @@ export default function Create() {

- 需要 {thresholdT} 个参与方共同签名才能执行交易 (其中 2 个由平台托管用于备份) + 需要 {requiredSigners} 个参与方共同签名才能执行交易 (其中 {totalParties - requiredSigners} 个由平台托管用于备份)

diff --git a/backend/mpc-system/services/service-party-app/src/types/electron.d.ts b/backend/mpc-system/services/service-party-app/src/types/electron.d.ts index 85d57ae0..16b44694 100644 --- a/backend/mpc-system/services/service-party-app/src/types/electron.d.ts +++ b/backend/mpc-system/services/service-party-app/src/types/electron.d.ts @@ -112,8 +112,12 @@ interface Settings { interface CreateSessionParams { walletName: string; - thresholdT: number; - thresholdN: number; + // New format: user-friendly parameters (preferred) + requiredSigners?: number; // Number of signers needed (e.g., 3 for "3-of-5") + totalParties?: number; // Total parties (e.g., 5 for "3-of-5") + // Legacy format: tss-lib parameters (backward compatible) + thresholdT?: number; // tss-lib threshold (requiredSigners - 1) + thresholdN?: number; // Same as totalParties initiatorName: string; }