import { create } from 'zustand'; // ============================================================================= // 类型定义 // ============================================================================= export type ConnectionStatus = 'unknown' | 'checking' | 'connected' | 'disconnected' | 'error'; export type AppReadyState = 'initializing' | 'ready' | 'error'; export type OperationStatus = 'idle' | 'connecting' | 'in_progress' | 'completed' | 'failed'; export interface ServiceStatus { status: ConnectionStatus; message?: string; lastChecked?: Date; } export interface OperationProgress { status: OperationStatus; type?: 'keygen' | 'sign'; sessionId?: string; currentStep?: number; totalSteps?: number; stepDescription?: string; error?: string; } export interface EnvironmentCheck { messageRouter: ServiceStatus; kavaApi: ServiceStatus; database: ServiceStatus; } interface AppState { // 应用就绪状态 appReady: AppReadyState; appError?: string; // 环境检测结果 environment: EnvironmentCheck; // 当前操作进度 operation: OperationProgress; // Actions setAppReady: (state: AppReadyState, error?: string) => void; setMessageRouterStatus: (status: ServiceStatus) => void; setKavaApiStatus: (status: ServiceStatus) => void; setDatabaseStatus: (status: ServiceStatus) => void; setOperation: (operation: Partial) => void; resetOperation: () => void; checkAllServices: () => Promise; } // ============================================================================= // Store // ============================================================================= export const useAppStore = create((set, get) => ({ // 初始状态 appReady: 'initializing', appError: undefined, environment: { messageRouter: { status: 'unknown' }, kavaApi: { status: 'unknown' }, database: { status: 'unknown' }, }, operation: { status: 'idle', }, // Actions setAppReady: (state, error) => set({ appReady: state, appError: error }), setMessageRouterStatus: (status) => set((s) => ({ environment: { ...s.environment, messageRouter: status }, })), setKavaApiStatus: (status) => set((s) => ({ environment: { ...s.environment, kavaApi: status }, })), setDatabaseStatus: (status) => set((s) => ({ environment: { ...s.environment, database: status }, })), setOperation: (operation) => set((s) => ({ operation: { ...s.operation, ...operation }, })), resetOperation: () => set({ operation: { status: 'idle' }, }), checkAllServices: async () => { const { setMessageRouterStatus, setKavaApiStatus, setDatabaseStatus, setAppReady } = get(); // 检测 Message Router - 真实验证注册状态 setMessageRouterStatus({ status: 'checking', message: '正在检测...' }); try { if (window.electronAPI) { const settings = await window.electronAPI.storage.getSettings(); const routerUrl = settings?.messageRouterUrl || 'mpc-grpc.szaiai.com:443'; // 1. 检查是否已连接 const connResult = await window.electronAPI.grpc.isConnected(); if (!connResult.connected) { setMessageRouterStatus({ status: 'disconnected', message: '未连接到 ' + routerUrl, lastChecked: new Date(), }); } else { // 2. 已连接,检查是否已注册 const partyIdResult = await window.electronAPI.grpc.getPartyId(); if (!partyIdResult.partyId) { setMessageRouterStatus({ status: 'disconnected', message: '已连接但未注册', lastChecked: new Date(), }); } else { // 3. 已注册,从 Message Router 验证自己是否在注册列表中 const partiesResult = await window.electronAPI.grpc.getRegisteredParties(); if (partiesResult.success) { const selfRegistered = partiesResult.parties.some( (p) => p.partyId === partyIdResult.partyId ); if (selfRegistered) { const selfParty = partiesResult.parties.find( (p) => p.partyId === partyIdResult.partyId ); setMessageRouterStatus({ status: 'connected', message: `已注册 (${selfParty?.online ? '在线' : '离线'})`, lastChecked: new Date(), }); } else { setMessageRouterStatus({ status: 'error', message: '注册验证失败', lastChecked: new Date(), }); } } else { setMessageRouterStatus({ status: 'error', message: partiesResult.error || '获取注册列表失败', lastChecked: new Date(), }); } } } } else { setMessageRouterStatus({ status: 'disconnected', message: '非 Electron 环境', }); } } catch (error) { setMessageRouterStatus({ status: 'error', message: (error as Error).message, lastChecked: new Date(), }); } // 检测 Kava API setKavaApiStatus({ status: 'checking', message: '正在检测...' }); try { if (window.electronAPI) { // 使用健康检查 API (查询最新区块) const result = await window.electronAPI.kava.healthCheck(); if (result.success && result.data?.ok) { const config = await window.electronAPI.kava.getConfig(); const latencyMsg = result.data.latency ? ` (${result.data.latency}ms)` : ''; setKavaApiStatus({ status: 'connected', message: (config?.lcdEndpoint || 'Kava Mainnet') + latencyMsg, lastChecked: new Date(), }); } else { setKavaApiStatus({ status: 'error', message: result.data?.error || result.error || 'API 响应异常', lastChecked: new Date(), }); } } else { setKavaApiStatus({ status: 'disconnected', message: '非 Electron 环境', }); } } catch (error) { setKavaApiStatus({ status: 'error', message: (error as Error).message, lastChecked: new Date(), }); } // 检测数据库 setDatabaseStatus({ status: 'checking', message: '正在检测...' }); try { if (window.electronAPI) { const result = await window.electronAPI.storage.listShares(); if (result.success) { setDatabaseStatus({ status: 'connected', message: `${result.data?.length || 0} 个钱包`, lastChecked: new Date(), }); } else { setDatabaseStatus({ status: 'error', message: result.error || '数据库错误', lastChecked: new Date(), }); } } else { setDatabaseStatus({ status: 'disconnected', message: '非 Electron 环境', }); } } catch (error) { setDatabaseStatus({ status: 'error', message: (error as Error).message, lastChecked: new Date(), }); } // 判断整体就绪状态 const env = get().environment; const hasError = env.messageRouter.status === 'error' || env.kavaApi.status === 'error' || env.database.status === 'error'; if (hasError) { setAppReady('error', '部分服务连接失败,请检查设置'); } else { setAppReady('ready'); } }, })); // ============================================================================= // 辅助函数 // ============================================================================= export function getOverallStatus(env: EnvironmentCheck): ConnectionStatus { const statuses = [env.messageRouter.status, env.kavaApi.status, env.database.status]; if (statuses.includes('checking')) return 'checking'; if (statuses.includes('error')) return 'error'; if (statuses.every((s) => s === 'connected')) return 'connected'; if (statuses.includes('disconnected')) return 'disconnected'; return 'unknown'; } export function getStatusColor(status: ConnectionStatus): string { switch (status) { case 'connected': return '#22c55e'; // green case 'checking': return '#f59e0b'; // yellow case 'disconnected': return '#6b7280'; // gray case 'error': return '#ef4444'; // red default: return '#6b7280'; // gray } } export function getStatusText(status: ConnectionStatus): string { switch (status) { case 'connected': return '已连接'; case 'checking': return '检测中...'; case 'disconnected': return '未连接'; case 'error': return '连接失败'; default: return '未知'; } }