import { useState } from 'react'; import { WalletType } from 'rnwalletman'; export interface OTPBindCallbacks { onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: any) => void; onError: (error: string) => void; isDebug?: boolean; } export interface OTPBindState { mobile: string; otp: string; step: 'mobile' | 'otp' | 'processing'; loading: boolean; otpData: any; } export interface OTPBindActions { setMobile: (mobile: string) => void; setOtp: (otp: string) => void; requestOTP: () => Promise; verifyOTP: () => Promise; resetToMobile: () => void; } export function useOTPBind( walletType: WalletType, callbacks: OTPBindCallbacks, config?: { otpLength?: number; mobileLength?: number; additionalParams?: any; } ): [OTPBindState, OTPBindActions] { const [mobile, setMobile] = useState(''); const [otp, setOtp] = useState(''); const [step, setStep] = useState<'mobile' | 'otp' | 'processing'>('mobile'); const [loading, setLoading] = useState(false); const [otpData, setOtpData] = useState(null); const { onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug = false } = callbacks; const { otpLength = 6, mobileLength = 10, additionalParams = {} } = config || {}; const log = (...args: any[]) => { if (isDebug) console.log(`[${walletType}]`, ...args); }; const error = (...args: any[]) => { if (isDebug) console.error(`[${walletType}]`, ...args); }; const requestOTP = async () => { if (!mobile || mobile.length !== mobileLength) { onError('Invalid mobile number'); return; } setLoading(true); log('Requesting OTP for:', mobile); try { const response = await onRequestOTP(walletType, { mobile, ...additionalParams, }); log('OTP response:', response); if (response.success) { setOtpData(response.data); setStep('otp'); } else { error('OTP request failed:', response.message); onError(response.message || 'Failed to request OTP'); } } catch (e) { error('Request OTP error:', e); onError(e instanceof Error ? e.message : 'Failed to request OTP'); } finally { setLoading(false); } }; const verifyOTP = async () => { if (!otp || otp.length !== otpLength) { onError(`Invalid OTP (expected ${otpLength} digits)`); return; } setLoading(true); setStep('processing'); log('Verifying OTP:', otp); try { const response = await onVerifyOTP(walletType, { mobile, otp, ...additionalParams, ...(otpData || {}), }); log('Verify response:', response); if (response.success) { onSuccess(response.data); } else { error('Verify failed:', response.message); setStep('otp'); onError(response.message || 'Failed to verify OTP'); } } catch (e) { error('Verify OTP error:', e); setStep('otp'); onError(e instanceof Error ? e.message : 'Failed to verify OTP'); } finally { setLoading(false); } }; const resetToMobile = () => { setStep('mobile'); setOtp(''); }; return [ { mobile, otp, step, loading, otpData }, { setMobile, setOtp, requestOTP, verifyOTP, resetToMobile }, ]; }