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 69b20bb9..73cd08f9 100644 --- a/backend/mpc-system/services/service-party-app/electron/main.ts +++ b/backend/mpc-system/services/service-party-app/electron/main.ts @@ -217,6 +217,16 @@ function setupIpcHandlers() { } }); + // gRPC - 获取已注册的参与方列表 + ipcMain.handle('grpc:getRegisteredParties', async (_event, { roleFilter, onlyOnline }) => { + try { + const parties = await grpcClient?.getRegisteredParties(roleFilter, onlyOnline); + return { success: true, parties: parties || [] }; + } catch (error) { + return { success: false, error: (error as Error).message, parties: [] }; + } + }); + // gRPC - 验证签名会话 (通过 Account 服务 HTTP API) ipcMain.handle('grpc:validateSigningSession', async (_event, { code }) => { try { diff --git a/backend/mpc-system/services/service-party-app/electron/modules/grpc-client.ts b/backend/mpc-system/services/service-party-app/electron/modules/grpc-client.ts index 3ac1881a..9b6a7023 100644 --- a/backend/mpc-system/services/service-party-app/electron/modules/grpc-client.ts +++ b/backend/mpc-system/services/service-party-app/electron/modules/grpc-client.ts @@ -78,6 +78,18 @@ interface SessionEvent { messageHash?: Buffer; } +interface RegisteredParty { + partyId: string; + role: string; + online: boolean; + registeredAt: string; + lastSeenAt: string; +} + +interface GetRegisteredPartiesResponse { + parties: RegisteredParty[]; +} + /** * gRPC 客户端 - 连接到 Message Router * @@ -390,4 +402,40 @@ export class GrpcClient extends EventEmitter { ); }); } + + /** + * 获取已注册的参与方列表 + * @param roleFilter 可选,按角色过滤 (persistent/delegate/temporary) + * @param onlyOnline 可选,只返回在线的参与方 + */ + async getRegisteredParties(roleFilter?: string, onlyOnline?: boolean): Promise { + if (!this.client) { + throw new Error('Not connected'); + } + + return new Promise((resolve, reject) => { + (this.client as grpc.Client & { getRegisteredParties: (req: unknown, callback: (err: Error | null, res: GetRegisteredPartiesResponse) => void) => void }) + .getRegisteredParties( + { + role_filter: roleFilter || '', + only_online: onlyOnline || false, + }, + (err: Error | null, response: GetRegisteredPartiesResponse) => { + if (err) { + reject(err); + } else { + // 转换字段名从 snake_case 到 camelCase + const parties = (response.parties || []).map((p: { party_id?: string; partyId?: string; role?: string; party_role?: string; online?: boolean; registered_at?: string; registeredAt?: string; last_seen_at?: string; lastSeenAt?: string }) => ({ + partyId: p.party_id || p.partyId || '', + role: p.role || p.party_role || '', + online: p.online || false, + registeredAt: p.registered_at || p.registeredAt || '', + lastSeenAt: p.last_seen_at || p.lastSeenAt || '', + })); + resolve(parties); + } + } + ); + }); + } } diff --git a/backend/mpc-system/services/service-party-app/electron/preload.ts b/backend/mpc-system/services/service-party-app/electron/preload.ts index 9520c7b8..2a903fb7 100644 --- a/backend/mpc-system/services/service-party-app/electron/preload.ts +++ b/backend/mpc-system/services/service-party-app/electron/preload.ts @@ -42,6 +42,10 @@ contextBridge.exposeInMainWorld('electronAPI', { testConnection: (url: string) => ipcRenderer.invoke('grpc:testConnection', { url }), + // 获取已注册的参与方列表 + getRegisteredParties: (roleFilter?: string, onlyOnline?: boolean) => + ipcRenderer.invoke('grpc:getRegisteredParties', { roleFilter, onlyOnline }), + // 签名相关 validateSigningSession: (code: string) => ipcRenderer.invoke('grpc:validateSigningSession', { code }), 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 0909d45b..11d1ce9e 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 @@ -146,6 +146,21 @@ interface TestConnectionResult { error?: string; } +// 已注册的参与方 +interface RegisteredParty { + partyId: string; + role: string; + online: boolean; + registeredAt: string; + lastSeenAt: string; +} + +interface GetRegisteredPartiesResult { + success: boolean; + parties: RegisteredParty[]; + error?: string; +} + interface SessionEvent { type: 'participant_joined' | 'status_changed' | 'completed' | 'failed'; participant?: Participant; @@ -413,6 +428,8 @@ interface ElectronAPI { getSessionStatus: (sessionId: string) => Promise; subscribeSessionEvents: (sessionId: string, callback: (event: SessionEvent) => void) => () => void; testConnection: (url: string) => Promise; + // 获取已注册的参与方列表 + getRegisteredParties: (roleFilter?: string, onlyOnline?: boolean) => Promise; // 签名相关 validateSigningSession: (code: string) => Promise; joinSigningSession: (params: JoinSigningSessionParams) => Promise;