rwadurian/backend/mpc-system/services/service-party-app/electron/preload.ts

330 lines
11 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: (params: {
sessionId: string;
partyId: string;
joinToken: string;
walletName?: string;
}) => ipcRenderer.invoke('grpc:joinSession', params),
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 }),
// 获取已注册的参与方列表
getRegisteredParties: (roleFilter?: string, onlyOnline?: boolean) =>
ipcRenderer.invoke('grpc:getRegisteredParties', { roleFilter, onlyOnline }),
// 获取当前 partyId
getPartyId: () => ipcRenderer.invoke('grpc:getPartyId'),
// 检查连接状态
isConnected: () => ipcRenderer.invoke('grpc:isConnected'),
// 连接到 Message Router
connect: (url: string) => ipcRenderer.invoke('grpc:connect', { url }),
// 注册为参与方
register: (partyId: string, role: string) =>
ipcRenderer.invoke('grpc:register', { partyId, role }),
// 签名相关 (旧版 - persistent 签名使用)
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 });
};
},
},
// ===========================================================================
// Co-Sign 相关 - 全新的多方协作签名 API
// ===========================================================================
cosign: {
// 创建 Co-Sign 会话
createSession: (params: {
shareId: string;
sharePassword: string;
messageHash: string;
initiatorName?: string;
}) => ipcRenderer.invoke('cosign:createSession', params),
// 验证邀请码
validateInviteCode: (code: string) =>
ipcRenderer.invoke('cosign:validateInviteCode', { code }),
// 加入 Co-Sign 会话
joinSession: (params: {
sessionId: string;
shareId: string;
sharePassword: string;
joinToken: string;
walletName?: string;
messageHash: string;
threshold: { t: number; n: number };
}) => ipcRenderer.invoke('cosign:joinSession', params),
// 获取会话状态
getSessionStatus: (sessionId: string) =>
ipcRenderer.invoke('cosign:getSessionStatus', { sessionId }),
// 订阅会话事件
subscribeSessionEvents: (sessionId: string, callback: (event: unknown) => void) => {
const channel = `cosign:events:${sessionId}`;
const listener = (_event: unknown, data: unknown) => callback(data);
eventSubscriptions.set(channel, listener);
ipcRenderer.on(channel, listener);
ipcRenderer.send('cosign:subscribeSessionEvents', { sessionId });
return () => {
ipcRenderer.removeListener(channel, listener);
eventSubscriptions.delete(channel);
ipcRenderer.send('cosign:unsubscribeSessionEvents', { sessionId });
};
},
},
// ===========================================================================
// Account 服务相关 (HTTP API)
// ===========================================================================
account: {
// 创建签名会话
createSignSession: (params: {
shareId: string;
password: string;
messageHash: string;
initiatorName?: string;
}) => ipcRenderer.invoke('account:createSignSession', params),
// 获取签名会话状态 (通过邀请码)
getSignSessionByInviteCode: (inviteCode: string) =>
ipcRenderer.invoke('account:getSignSessionByInviteCode', { inviteCode }),
// 健康检查
healthCheck: () => ipcRenderer.invoke('account:healthCheck'),
// 测试连接
testConnection: () => ipcRenderer.invoke('account:testConnection'),
// 更新服务 URL
updateUrl: (url: string) =>
ipcRenderer.invoke('account:updateUrl', { url }),
// 获取当前服务 URL
getUrl: () => ipcRenderer.invoke('account:getUrl'),
},
// ===========================================================================
// 存储相关 (SQLite)
// ===========================================================================
storage: {
// Share 操作
saveShare: (share: {
sessionId: string;
walletName: string;
partyId: string;
partyIndex: number;
threshold: { t: number; n: number };
publicKey: string;
rawShare: string;
participants?: Array<{ partyId: string; name: string }>;
}, password: string) =>
ipcRenderer.invoke('storage:saveShare', { share, password }),
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: {
messageRouterUrl?: string;
autoBackup?: boolean;
backupPath?: string;
}) => ipcRenderer.invoke('storage:saveSettings', { settings }),
},
// ===========================================================================
// 地址派生相关
// ===========================================================================
address: {
// 派生指定链的地址
derive: (shareId: string, chain: string, password: string) =>
ipcRenderer.invoke('address:derive', { shareId, chain, password }),
// 派生所有支持链的地址
deriveAll: (shareId: string, password: string) =>
ipcRenderer.invoke('address:deriveAll', { shareId, password }),
// 获取 share 的所有派生地址
list: (shareId: string) =>
ipcRenderer.invoke('address:list', { shareId }),
// 获取支持的链列表
getSupportedChains: () =>
ipcRenderer.invoke('address:getSupportedChains'),
},
// ===========================================================================
// 签名历史相关
// ===========================================================================
signing: {
// 获取签名历史
getHistory: (shareId: string) =>
ipcRenderer.invoke('signing:getHistory', { shareId }),
},
// ===========================================================================
// Kava 区块链相关
// ===========================================================================
kava: {
// 查询 KAVA 余额
getBalance: (address: string) =>
ipcRenderer.invoke('kava:getBalance', { address }),
// 查询所有余额
getAllBalances: (address: string) =>
ipcRenderer.invoke('kava:getAllBalances', { address }),
// 查询账户信息
getAccountInfo: (address: string) =>
ipcRenderer.invoke('kava:getAccountInfo', { address }),
// 构建转账交易 (待 TSS 签名)
buildSendTx: (params: {
fromAddress: string;
toAddress: string;
amount: string;
publicKeyHex: string;
memo?: string;
}) => ipcRenderer.invoke('kava:buildSendTx', params),
// 完成签名并广播交易
completeTxAndBroadcast: (params: {
unsignedTx: unknown;
signatureHex: string;
}) => ipcRenderer.invoke('kava:completeTxAndBroadcast', params),
// 查询交易状态
getTxStatus: (txHash: string) =>
ipcRenderer.invoke('kava:getTxStatus', { txHash }),
// 获取配置
getConfig: () => ipcRenderer.invoke('kava:getConfig'),
// 更新配置
updateConfig: (config: {
lcdEndpoint?: string;
rpcEndpoint?: string;
chainId?: string;
}) => ipcRenderer.invoke('kava:updateConfig', { config }),
// 健康检查
healthCheck: () => ipcRenderer.invoke('kava:healthCheck'),
// 切换网络 (mainnet/testnet)
switchNetwork: (network: 'mainnet' | 'testnet') =>
ipcRenderer.invoke('kava:switchNetwork', { network }),
// 获取当前网络
getNetwork: () => ipcRenderer.invoke('kava:getNetwork'),
},
// ===========================================================================
// 对话框相关
// ===========================================================================
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 }),
},
// ===========================================================================
// 调试相关
// ===========================================================================
debug: {
// 订阅主进程日志
subscribeLogs: (callback: (event: unknown, data: { level: string; source: string; message: string }) => void) => {
ipcRenderer.on('debug:log', callback);
ipcRenderer.send('debug:subscribe');
},
// 取消订阅
unsubscribeLogs: () => {
ipcRenderer.removeAllListeners('debug:log');
ipcRenderer.send('debug:unsubscribe');
},
// 发送日志到主进程
log: (level: string, source: string, message: string) => {
ipcRenderer.send('debug:log', { level, source, message });
},
},
});