fix(mpc-service): 确保 keygen 会话包含完整的参与者列表

问题:account-service 要求 participants 数量必须等于 threshold_n
原因:createKeygenSession 传入的 participants 可能不足 3 个

修复:
- 在 createKeygenSession 中自动补全参与者列表
- 对于 2-of-3 配置,确保有 3 个参与者:
  - user-party (用户端)
  - server-party-1 (服务端)
  - server-party-2 (备份)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Developer 2025-12-04 06:04:47 -08:00
parent e23af5d4ad
commit c26a24b544
1 changed files with 35 additions and 4 deletions

View File

@ -255,20 +255,51 @@ export class TSSWrapper implements TSSProtocolDomainService {
/**
* Create a keygen session via account-service.
* This will also notify server-party-1/2/3 to participate.
*
* Note: account-service requires exactly threshold_n participants.
* For a 2-of-3 setup, we need 3 participants:
* - user-party (the user's share, returned to client)
* - server-party-1 (stored on server)
* - server-party-2 (backup, stored on server)
*/
private async createKeygenSession(
participants: TSSParticipant[],
threshold: Threshold,
): Promise<CreateKeygenSessionResponse> {
// Build the full participant list for threshold_n parties
// If we have fewer participants, add the default server parties
const allParticipants: Array<{ party_id: string; device_type: string }> = [];
// Add provided participants
for (const p of participants) {
allParticipants.push({
party_id: p.partyId,
device_type: 'server',
});
}
// Ensure we have exactly threshold_n participants
// Default server party IDs for 2-of-3 setup
const defaultPartyIds = ['user-party', 'server-party-1', 'server-party-2'];
const existingPartyIds = new Set(allParticipants.map(p => p.party_id));
for (const partyId of defaultPartyIds) {
if (!existingPartyIds.has(partyId) && allParticipants.length < threshold.n) {
allParticipants.push({
party_id: partyId,
device_type: partyId === 'user-party' ? 'client' : 'server',
});
}
}
this.logger.log(`Creating keygen session with ${allParticipants.length} participants: ${allParticipants.map(p => p.party_id).join(', ')}`);
const response = await this.axiosClient.post<CreateKeygenSessionResponse>(
`${this.accountServiceUrl}/api/v1/mpc/keygen`,
{
threshold_n: threshold.n,
threshold_t: threshold.t,
participants: participants.map(p => ({
party_id: p.partyId,
device_type: 'server',
})),
participants: allParticipants,
},
);
return response.data;