fix(co-sign): pass complete parties list to joinSession
Problem: Participants joining early only got incomplete participant list from other_parties (only those who had joined), causing partyIndex mismatch. Solution: - Add parties field to SessionInfo (from validateInviteCode response) - Pass parties to joinSession call from frontend - Backend joinSession uses params.parties (complete list) instead of result.other_parties (incomplete list) - Add debug logging to track participant list state Now all participants have the complete parties list with correct partyIndex. 🤖 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
8193549aba
commit
e284a46e83
|
|
@ -821,22 +821,44 @@ async function handleCoSignStart(event: {
|
||||||
// 标记签名开始
|
// 标记签名开始
|
||||||
signInProgressSessionId = event.sessionId;
|
signInProgressSessionId = event.sessionId;
|
||||||
|
|
||||||
// 从 event.selectedParties 更新参与者列表(类似 keygen 的 handleSessionStart)
|
// 打印当前 activeCoSignSession.participants 状态
|
||||||
// 这确保我们使用的是实际加入会话的参与者,而不是预设的列表
|
console.log('[CO-SIGN] Current activeCoSignSession.participants before update:',
|
||||||
|
activeCoSignSession.participants.map(p => ({
|
||||||
|
partyId: p.partyId.substring(0, 8),
|
||||||
|
partyIndex: p.partyIndex,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
console.log('[CO-SIGN] event.selectedParties:', event.selectedParties?.map(id => id.substring(0, 8)));
|
||||||
|
|
||||||
|
// 从 event.selectedParties 更新参与者列表
|
||||||
|
// 优先使用 activeCoSignSession.participants 中的 partyIndex(来自 signingParties 或 other_parties)
|
||||||
if (event.selectedParties && event.selectedParties.length > 0) {
|
if (event.selectedParties && event.selectedParties.length > 0) {
|
||||||
const myPartyId = grpcClient?.getPartyId();
|
const myPartyId = grpcClient?.getPartyId();
|
||||||
const updatedParticipants: Array<{ partyId: string; partyIndex: number; name: string }> = [];
|
const updatedParticipants: Array<{ partyId: string; partyIndex: number; name: string }> = [];
|
||||||
|
|
||||||
event.selectedParties.forEach((partyId, index) => {
|
event.selectedParties.forEach((partyId) => {
|
||||||
// 查找已有的参与者信息
|
// 查找已有的参与者信息
|
||||||
const existingParticipant = activeCoSignSession?.participants.find(p => p.partyId === partyId);
|
const existingParticipant = activeCoSignSession?.participants.find(p => p.partyId === partyId);
|
||||||
updatedParticipants.push({
|
if (existingParticipant) {
|
||||||
partyId: partyId,
|
// 使用已有的 partyIndex
|
||||||
partyIndex: existingParticipant?.partyIndex ?? (index + 1),
|
updatedParticipants.push({
|
||||||
name: partyId === myPartyId ? '我' : (existingParticipant?.name || `参与方 ${index + 1}`),
|
partyId: partyId,
|
||||||
});
|
partyIndex: existingParticipant.partyIndex,
|
||||||
|
name: partyId === myPartyId ? '我' : existingParticipant.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 找不到已有信息,这不应该发生 - 记录警告
|
||||||
|
console.warn(`[CO-SIGN] WARNING: Party ${partyId.substring(0, 8)} not found in activeCoSignSession.participants!`);
|
||||||
|
// 不使用 fallback index,直接跳过,这会导致参与者数量不足,签名会失败
|
||||||
|
// 这样可以更早发现问题
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 检查参与者数量是否符合预期
|
||||||
|
if (updatedParticipants.length !== event.selectedParties.length) {
|
||||||
|
console.error(`[CO-SIGN] ERROR: Participant count mismatch! Expected ${event.selectedParties.length}, got ${updatedParticipants.length}`);
|
||||||
|
}
|
||||||
|
|
||||||
// 按 partyIndex 排序
|
// 按 partyIndex 排序
|
||||||
updatedParticipants.sort((a, b) => a.partyIndex - b.partyIndex);
|
updatedParticipants.sort((a, b) => a.partyIndex - b.partyIndex);
|
||||||
|
|
||||||
|
|
@ -1651,15 +1673,17 @@ function setupIpcHandlers() {
|
||||||
|
|
||||||
if (joinResult?.success) {
|
if (joinResult?.success) {
|
||||||
// 设置活跃的 Co-Sign 会话信息
|
// 设置活跃的 Co-Sign 会话信息
|
||||||
// 注意:这里只初始化发起者自己,其他参与者会在 session_started 事件中从 selectedParties 更新
|
// 使用 signingParties 初始化完整的参与者列表(包含正确的 partyIndex)
|
||||||
const signParticipants: Array<{ partyId: string; partyIndex: number; name: string }> = [];
|
const signParticipants: Array<{ partyId: string; partyIndex: number; name: string }> = signingParties.map(p => ({
|
||||||
|
partyId: p.party_id,
|
||||||
|
partyIndex: p.party_index,
|
||||||
|
name: p.party_id === partyId ? (params.initiatorName || '发起者') : `参与方 ${p.party_index + 1}`,
|
||||||
|
}));
|
||||||
|
|
||||||
// 添加发起方
|
console.log('[CO-SIGN] Initiator signParticipants (from signingParties):', signParticipants.map(p => ({
|
||||||
signParticipants.push({
|
partyId: p.partyId.substring(0, 8),
|
||||||
partyId: partyId,
|
partyIndex: p.partyIndex,
|
||||||
partyIndex: joinResult.party_index,
|
})));
|
||||||
name: params.initiatorName || '发起者',
|
|
||||||
});
|
|
||||||
|
|
||||||
activeCoSignSession = {
|
activeCoSignSession = {
|
||||||
sessionId: result.session_id,
|
sessionId: result.session_id,
|
||||||
|
|
@ -1768,6 +1792,7 @@ function setupIpcHandlers() {
|
||||||
walletName?: string;
|
walletName?: string;
|
||||||
messageHash: string;
|
messageHash: string;
|
||||||
threshold: { t: number; n: number };
|
threshold: { t: number; n: number };
|
||||||
|
parties?: Array<{ party_id: string; party_index: number }>;
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
const partyId = grpcClient?.getPartyId();
|
const partyId = grpcClient?.getPartyId();
|
||||||
|
|
@ -1786,18 +1811,37 @@ function setupIpcHandlers() {
|
||||||
const result = await grpcClient?.joinSession(params.sessionId, partyId, params.joinToken);
|
const result = await grpcClient?.joinSession(params.sessionId, partyId, params.joinToken);
|
||||||
if (result?.success) {
|
if (result?.success) {
|
||||||
// 设置活跃的 Co-Sign 会话
|
// 设置活跃的 Co-Sign 会话
|
||||||
const participants: Array<{ partyId: string; partyIndex: number; name: string }> = result.other_parties?.map((p: { party_id: string; party_index: number }, idx: number) => ({
|
// 优先使用 params.parties(来自 validateInviteCode,包含所有预期参与者)
|
||||||
partyId: p.party_id,
|
// 而不是 result.other_parties(只包含已加入的参与者)
|
||||||
partyIndex: p.party_index,
|
let participants: Array<{ partyId: string; partyIndex: number; name: string }>;
|
||||||
name: `参与方 ${idx + 1}`,
|
|
||||||
})) || [];
|
|
||||||
|
|
||||||
// 添加自己
|
if (params.parties && params.parties.length > 0) {
|
||||||
participants.push({
|
// 使用完整的 parties 列表
|
||||||
partyId: partyId,
|
participants = params.parties.map(p => ({
|
||||||
partyIndex: result.party_index,
|
partyId: p.party_id,
|
||||||
name: '我',
|
partyIndex: p.party_index,
|
||||||
});
|
name: p.party_id === partyId ? '我' : `参与方 ${p.party_index + 1}`,
|
||||||
|
}));
|
||||||
|
console.log('[CO-SIGN] Participant using params.parties (complete list):', participants.map(p => ({
|
||||||
|
partyId: p.partyId.substring(0, 8),
|
||||||
|
partyIndex: p.partyIndex,
|
||||||
|
})));
|
||||||
|
} else {
|
||||||
|
// Fallback: 使用 other_parties + 自己(可能不完整)
|
||||||
|
console.warn('[CO-SIGN] WARNING: params.parties not available, using other_parties (may be incomplete)');
|
||||||
|
participants = result.other_parties?.map((p: { party_id: string; party_index: number }, idx: number) => ({
|
||||||
|
partyId: p.party_id,
|
||||||
|
partyIndex: p.party_index,
|
||||||
|
name: `参与方 ${idx + 1}`,
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
// 添加自己
|
||||||
|
participants.push({
|
||||||
|
partyId: partyId,
|
||||||
|
partyIndex: result.party_index,
|
||||||
|
name: '我',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 按 partyIndex 排序
|
// 按 partyIndex 排序
|
||||||
participants.sort((a, b) => a.partyIndex - b.partyIndex);
|
participants.sort((a, b) => a.partyIndex - b.partyIndex);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@ interface Share {
|
||||||
threshold: { t: number; n: number };
|
threshold: { t: number; n: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SignPartyInfo {
|
||||||
|
party_id: string;
|
||||||
|
party_index: number;
|
||||||
|
}
|
||||||
|
|
||||||
interface SessionInfo {
|
interface SessionInfo {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
keygenSessionId: string;
|
keygenSessionId: string;
|
||||||
|
|
@ -18,6 +23,7 @@ interface SessionInfo {
|
||||||
threshold: { t: number; n: number };
|
threshold: { t: number; n: number };
|
||||||
status: string;
|
status: string;
|
||||||
currentParticipants: number;
|
currentParticipants: number;
|
||||||
|
parties?: SignPartyInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ValidateResult {
|
interface ValidateResult {
|
||||||
|
|
@ -202,6 +208,7 @@ export default function CoSignJoin() {
|
||||||
walletName: sessionInfo.walletName,
|
walletName: sessionInfo.walletName,
|
||||||
messageHash: sessionInfo.messageHash,
|
messageHash: sessionInfo.messageHash,
|
||||||
threshold: sessionInfo.threshold,
|
threshold: sessionInfo.threshold,
|
||||||
|
parties: sessionInfo.parties,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -213,6 +220,7 @@ export default function CoSignJoin() {
|
||||||
walletName: sessionInfo.walletName,
|
walletName: sessionInfo.walletName,
|
||||||
messageHash: sessionInfo.messageHash,
|
messageHash: sessionInfo.messageHash,
|
||||||
threshold: sessionInfo.threshold,
|
threshold: sessionInfo.threshold,
|
||||||
|
parties: sessionInfo.parties,
|
||||||
});
|
});
|
||||||
console.log('[CoSignJoin] joinSession result:', result);
|
console.log('[CoSignJoin] joinSession result:', result);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,7 @@ interface JoinCoSignSessionParams {
|
||||||
walletName?: string;
|
walletName?: string;
|
||||||
messageHash: string;
|
messageHash: string;
|
||||||
threshold: { t: number; n: number };
|
threshold: { t: number; n: number };
|
||||||
|
parties?: Array<{ party_id: string; party_index: number }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JoinCoSignSessionResult {
|
interface JoinCoSignSessionResult {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue