fix(co-sign): use keygen session participants with correct party_index for signing
- Fetch keygen session status from backend to get accurate party_index - Filter out co-managed-party-* (server persistent parties) from signing - Only temporary/external user parties participate in signing - For 3-of-5 wallet: 3 user parties sign, 2 co-managed parties are backup only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4089b9da6c
commit
ebbc483b35
|
|
@ -483,7 +483,29 @@
|
|||
"Bash(git cherry-pick:*)",
|
||||
"Bash(git stash:*)",
|
||||
"Bash(docker compose build:*)",
|
||||
"Bash(git log:*)"
|
||||
"Bash(git log:*)",
|
||||
"Bash(git tag -a v0.3.0-pre-transfer -m \"$\\(cat <<''EOF''\nPre-transfer development checkpoint\n\nCompleted features:\n- Co-keygen: Multi-party key generation with TSS \\(GG20\\)\n- Service-party-app: Electron desktop application\n - Create shared wallet \\(keygen initiator\\)\n - Join wallet creation \\(keygen participant\\)\n - Wallet management \\(list, export, delete\\)\n - Kava network switch \\(mainnet/testnet\\)\n - EVM address derivation and balance display\n\nNot yet implemented:\n- Co-sign: Multi-party transaction signing\n- Transfer functionality\n\nThis tag marks the stable state before transfer feature development.\nEOF\n\\)\")",
|
||||
"Bash(tasklist:*)",
|
||||
"Bash(docker port:*)",
|
||||
"Bash(docker rm:*)",
|
||||
"Bash(netstat:*)",
|
||||
"Bash(start \"\" \"C:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\\\\backend\\\\mpc-system\\\\services\\\\service-party-app\\\\release\\\\win-unpacked\\\\榴莲皇后绿积分共管账户服务.exe\")",
|
||||
"Bash(go test:*)",
|
||||
"Bash(./tss-party.exe sign:*)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian log --oneline --all)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian diff --name-only HEAD~5..HEAD)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian log --all --oneline --grep=\"co-sign\\\\|co-managed\\\\|CoManaged\")",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian show e038f178 --stat)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian show e114723a --stat)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian show c457d158 -- backend/mpc-system/services/account/adapters/input/http/account_handler.go)",
|
||||
"Bash(git -C /c/Users/dong/Desktop/rwadurian log --oneline -- backend/mpc-system/services/account/adapters/input/http/account_handler.go)",
|
||||
"Bash(git rev-list:*)",
|
||||
"Bash(dir /d \"C:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\")",
|
||||
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(service-party-app\\): implement co-sign multi-party signing\n\nAdd complete co-sign functionality for multi-party transaction signing:\n\nFrontend \\(React\\):\n- CoSignCreate.tsx: Create signing session with share selection\n- CoSignJoin.tsx: Join signing session via invite code\n- CoSignSession.tsx: Monitor signing progress and results\n- Add routes in App.tsx for new pages\n\nBackend \\(Electron\\):\n- main.ts: Add IPC handlers for co-sign operations\n- tss-handler.ts: Add participateSign\\(\\) for TSS signing\n- preload.ts: Expose cosign API to renderer\n- account-client.ts: Add sign session API types\n\nTSS Party \\(Go\\):\n- main.go: Implement ''sign'' command for GG20 signing protocol\n- integration_test.go: Add comprehensive tests for signing flow\n\nInfrastructure:\n- docker-compose.windows.yml: Expose gRPC port 50051\n\nThis is a pure additive change that does not affect existing\npersistent role keygen/sign functionality.\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
||||
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(service-party-app\\): add transfer functionality with co-sign integration\n\nAdd complete KAVA transfer feature to the wallet home page:\n\nFrontend \\(React\\):\n- Home.tsx: Add transfer modal with address/amount input, transaction\n confirmation, and co-sign session initiation\n- Home.module.css: Transfer modal styles \\(form, confirm, error states\\)\n- CoSignSession.tsx: Add transaction broadcast after signing completion,\n with block explorer link\n\nUtils:\n- transaction.ts: EIP-1559 transaction building, RLP encoding, Keccak-256\n hashing, nonce/gas fetching, transaction broadcast via JSON-RPC\n\nFlow: Wallet -> Transfer Modal -> Prepare TX -> Confirm -> Co-Sign ->\n Sign Session -> Broadcast -> Block Explorer\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
||||
"Bash(powershell -Command:*)",
|
||||
"Bash(powershell -Command \"\n$content = Get-Content ''main.ts'' -Raw\n\n# 修改 threshold 部分\n$old1 = @''\n threshold: {\n t: activeCoSignSession?.threshold?.t || 0,\n n: activeCoSignSession?.threshold?.n || 0,\n },\n''@\n\n$new1 = @''\n threshold: {\n // 优先使用 API 返回的阈值,回退到 activeCoSignSession\n t: result?.threshold_t || activeCoSignSession?.threshold?.t || 0,\n n: result?.threshold_n || activeCoSignSession?.threshold?.n || 0,\n },\n''@\n\n$content = $content.Replace\\($old1, $new1\\)\n\n# 修改 participants 部分\n$old2 = ''participants: result?.parties?.map\\(\\(p: { party_id: string; party_index: number }, idx: number\\) => \\({''\n$new2 = ''participants: \\(\\(result as { participants?: Array<{ party_id: string; party_index: number; status: string }> }\\)?.participants || []\\).map\\(\\(p, idx\\) => \\({''\n\n$content = $content.Replace\\($old2, $new2\\)\n\n# 修改 status 部分\n$old3 = \"\" status: ''ready'',\"\"\n$new3 = \"\" status: p.status || ''waiting'',\"\"\n\n$content = $content.Replace\\($old3, $new3\\)\n\n# 修改结尾部分\n$old4 = '' }\\)\\) || [],''\n$new4 = '' }\\)\\),''\n\n$content = $content.Replace\\($old4, $new4\\)\n\nSet-Content ''main.ts'' -Value $content -NoNewline\nWrite-Output ''Done''\n\")",
|
||||
"Bash(node fix_main.js:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
|
|
|||
|
|
@ -1566,19 +1566,40 @@ function setupIpcHandlers() {
|
|||
return { success: false, error: 'Share 不存在或密码错误' };
|
||||
}
|
||||
|
||||
// 解析参与者信息
|
||||
const participants = JSON.parse(share.participants_json || '[]');
|
||||
const parties = participants.map((p: { partyId: string }, index: number) => ({
|
||||
party_id: p.partyId,
|
||||
party_index: index,
|
||||
}));
|
||||
// 从后端获取 keygen 会话的参与者信息(包含正确的 party_index)
|
||||
const keygenStatus = await accountClient?.getSessionStatus(share.session_id);
|
||||
if (!keygenStatus?.participants || keygenStatus.participants.length === 0) {
|
||||
return { success: false, error: '无法获取 keygen 会话的参与者信息' };
|
||||
}
|
||||
|
||||
// 过滤掉 co-managed-party-*(服务器持久方),只保留 temporary/external 用户方
|
||||
// 只有用户方持有签名私钥份额,co-managed-party 是备份/恢复用的
|
||||
const signingParties = keygenStatus.participants
|
||||
.filter(p => !p.party_id.startsWith('co-managed-party-'))
|
||||
.map(p => ({
|
||||
party_id: p.party_id,
|
||||
party_index: p.party_index,
|
||||
}));
|
||||
|
||||
console.log('[CO-SIGN] Signing parties (excluding co-managed-party):', {
|
||||
total_keygen_participants: keygenStatus.participants.length,
|
||||
signing_parties_count: signingParties.length,
|
||||
signing_parties: signingParties.map(p => ({ id: p.party_id, index: p.party_index })),
|
||||
});
|
||||
|
||||
if (signingParties.length < share.threshold_t) {
|
||||
return {
|
||||
success: false,
|
||||
error: `签名参与方不足: 需要 ${share.threshold_t} 个,但只有 ${signingParties.length} 个用户方`
|
||||
};
|
||||
}
|
||||
|
||||
// 创建签名会话
|
||||
const result = await accountClient?.createSignSession({
|
||||
keygen_session_id: share.session_id,
|
||||
wallet_name: share.wallet_name,
|
||||
message_hash: params.messageHash,
|
||||
parties: parties,
|
||||
parties: signingParties,
|
||||
threshold_t: share.threshold_t,
|
||||
initiator_name: params.initiatorName || '发起者',
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue