101 lines
3.5 KiB
TypeScript
101 lines
3.5 KiB
TypeScript
import { contextBridge, ipcRenderer } from 'electron';
|
|
|
|
// 事件订阅管理
|
|
const eventSubscriptions: Map<string, (event: unknown, ...args: unknown[]) => void> = new Map();
|
|
|
|
// 暴露给渲染进程的 API
|
|
contextBridge.exposeInMainWorld('electronAPI', {
|
|
// gRPC 相关 - Keygen
|
|
grpc: {
|
|
createSession: (params: {
|
|
walletName: string;
|
|
thresholdT: number;
|
|
thresholdN: number;
|
|
initiatorName: string;
|
|
}) => ipcRenderer.invoke('grpc:createSession', params),
|
|
|
|
joinSession: (sessionId: string, participantName: string) =>
|
|
ipcRenderer.invoke('grpc:joinSession', { sessionId, participantName }),
|
|
|
|
validateInviteCode: (code: string) =>
|
|
ipcRenderer.invoke('grpc:validateInviteCode', { code }),
|
|
|
|
getSessionStatus: (sessionId: string) =>
|
|
ipcRenderer.invoke('grpc:getSessionStatus', { sessionId }),
|
|
|
|
subscribeSessionEvents: (sessionId: string, callback: (event: unknown) => void) => {
|
|
const channel = `session:events:${sessionId}`;
|
|
const listener = (_event: unknown, data: unknown) => callback(data);
|
|
eventSubscriptions.set(channel, listener);
|
|
ipcRenderer.on(channel, listener);
|
|
ipcRenderer.send('grpc:subscribeSessionEvents', { sessionId });
|
|
|
|
return () => {
|
|
ipcRenderer.removeListener(channel, listener);
|
|
eventSubscriptions.delete(channel);
|
|
ipcRenderer.send('grpc:unsubscribeSessionEvents', { sessionId });
|
|
};
|
|
},
|
|
|
|
testConnection: (url: string) =>
|
|
ipcRenderer.invoke('grpc:testConnection', { url }),
|
|
|
|
// 签名相关
|
|
validateSigningSession: (code: string) =>
|
|
ipcRenderer.invoke('grpc:validateSigningSession', { code }),
|
|
|
|
joinSigningSession: (params: {
|
|
sessionId: string;
|
|
shareId: string;
|
|
password: string;
|
|
}) => ipcRenderer.invoke('grpc:joinSigningSession', params),
|
|
|
|
subscribeSigningProgress: (sessionId: string, callback: (event: unknown) => void) => {
|
|
const channel = `signing:progress:${sessionId}`;
|
|
const listener = (_event: unknown, data: unknown) => callback(data);
|
|
eventSubscriptions.set(channel, listener);
|
|
ipcRenderer.on(channel, listener);
|
|
ipcRenderer.send('grpc:subscribeSigningProgress', { sessionId });
|
|
|
|
return () => {
|
|
ipcRenderer.removeListener(channel, listener);
|
|
eventSubscriptions.delete(channel);
|
|
ipcRenderer.send('grpc:unsubscribeSigningProgress', { sessionId });
|
|
};
|
|
},
|
|
},
|
|
|
|
// 存储相关
|
|
storage: {
|
|
listShares: () => ipcRenderer.invoke('storage:listShares'),
|
|
|
|
getShare: (id: string, password: string) =>
|
|
ipcRenderer.invoke('storage:getShare', { id, password }),
|
|
|
|
exportShare: (id: string, password: string) =>
|
|
ipcRenderer.invoke('storage:exportShare', { id, password }),
|
|
|
|
importShare: (filePath: string, password: string) =>
|
|
ipcRenderer.invoke('storage:importShare', { filePath, password }),
|
|
|
|
deleteShare: (id: string) =>
|
|
ipcRenderer.invoke('storage:deleteShare', { id }),
|
|
|
|
getSettings: () => ipcRenderer.invoke('storage:getSettings'),
|
|
|
|
saveSettings: (settings: unknown) =>
|
|
ipcRenderer.invoke('storage:saveSettings', { settings }),
|
|
},
|
|
|
|
// 对话框相关
|
|
dialog: {
|
|
selectDirectory: () => ipcRenderer.invoke('dialog:selectDirectory'),
|
|
|
|
selectFile: (filters?: { name: string; extensions: string[] }[]) =>
|
|
ipcRenderer.invoke('dialog:selectFile', { filters }),
|
|
|
|
saveFile: (defaultPath?: string, filters?: { name: string; extensions: string[] }[]) =>
|
|
ipcRenderer.invoke('dialog:saveFile', { defaultPath, filters }),
|
|
},
|
|
});
|