rwadurian/frontend/admin-web/src/hooks/useTSSClient.ts

121 lines
3.0 KiB
TypeScript

'use client';
import { useState, useEffect, useCallback, useRef } from 'react';
import { TSSClient, createTSSClient, KeygenParams, KeygenResult } from '@/lib/tss';
interface UseTSSClientOptions {
messageRouterUrl?: string;
autoInit?: boolean;
}
interface UseTSSClientReturn {
client: TSSClient | null;
isInitialized: boolean;
isInitializing: boolean;
error: string | null;
init: () => Promise<void>;
registerParty: (partyId: string, role?: string) => Promise<void>;
keygen: (
params: KeygenParams,
onProgress?: (current: number, total: number) => void
) => Promise<KeygenResult>;
stop: () => void;
disconnect: () => void;
}
const DEFAULT_MESSAGE_ROUTER_URL = 'mpc-grpc.szaiai.com:443';
/**
* React hook for TSS client operations
*/
export function useTSSClient(options: UseTSSClientOptions = {}): UseTSSClientReturn {
const {
messageRouterUrl = DEFAULT_MESSAGE_ROUTER_URL,
autoInit = true,
} = options;
const [client, setClient] = useState<TSSClient | null>(null);
const [isInitialized, setIsInitialized] = useState(false);
const [isInitializing, setIsInitializing] = useState(false);
const [error, setError] = useState<string | null>(null);
const clientRef = useRef<TSSClient | null>(null);
const init = useCallback(async () => {
if (isInitializing || isInitialized) {
return;
}
setIsInitializing(true);
setError(null);
try {
const tssClient = createTSSClient(messageRouterUrl);
await tssClient.init();
clientRef.current = tssClient;
setClient(tssClient);
setIsInitialized(true);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to initialize TSS client';
setError(errorMessage);
console.error('TSS client initialization failed:', err);
} finally {
setIsInitializing(false);
}
}, [messageRouterUrl, isInitializing, isInitialized]);
const registerParty = useCallback(async (partyId: string, role: string = 'temporary') => {
if (!clientRef.current) {
throw new Error('TSS client not initialized');
}
await clientRef.current.registerParty(partyId, role);
}, []);
const keygen = useCallback(async (
params: KeygenParams,
onProgress?: (current: number, total: number) => void
): Promise<KeygenResult> => {
if (!clientRef.current) {
throw new Error('TSS client not initialized');
}
return clientRef.current.keygen(params, onProgress, (error) => {
console.error('Keygen error:', error);
});
}, []);
const stop = useCallback(() => {
clientRef.current?.stop();
}, []);
const disconnect = useCallback(() => {
clientRef.current?.disconnect();
setClient(null);
setIsInitialized(false);
}, []);
// Auto-init on mount
useEffect(() => {
if (autoInit) {
init();
}
return () => {
clientRef.current?.disconnect();
};
}, [autoInit, init]);
return {
client,
isInitialized,
isInitializing,
error,
init,
registerParty,
keygen,
stop,
disconnect,
};
}