2025-07-13 17:53:30 +00:00
|
|
|
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
|
|
import { useNWC } from '@/hooks/useNWCContext';
|
2025-07-13 06:47:45 +00:00
|
|
|
import type { WebLNProvider } from 'webln';
|
|
|
|
import { requestProvider } from 'webln';
|
|
|
|
|
|
|
|
export interface WalletStatus {
|
|
|
|
hasWebLN: boolean;
|
|
|
|
hasNWC: boolean;
|
|
|
|
webln: WebLNProvider | null;
|
|
|
|
activeNWC: ReturnType<typeof useNWC>['getActiveConnection'] extends () => infer T ? T : null;
|
|
|
|
isDetecting: boolean;
|
|
|
|
preferredMethod: 'nwc' | 'webln' | 'manual';
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useWallet() {
|
|
|
|
const [webln, setWebln] = useState<WebLNProvider | null>(null);
|
|
|
|
const [isDetecting, setIsDetecting] = useState(false);
|
2025-07-13 17:53:30 +00:00
|
|
|
const [hasAttemptedDetection, setHasAttemptedDetection] = useState(false);
|
|
|
|
const { connections, getActiveConnection } = useNWC();
|
|
|
|
|
|
|
|
// Get the active connection directly - no memoization to avoid stale state
|
2025-07-13 06:47:45 +00:00
|
|
|
const activeNWC = getActiveConnection();
|
|
|
|
|
|
|
|
// Detect WebLN
|
|
|
|
const detectWebLN = useCallback(async () => {
|
|
|
|
if (webln || isDetecting) return webln;
|
2025-07-13 17:53:30 +00:00
|
|
|
|
2025-07-13 06:47:45 +00:00
|
|
|
setIsDetecting(true);
|
|
|
|
try {
|
|
|
|
const provider = await requestProvider();
|
|
|
|
setWebln(provider);
|
2025-07-13 17:53:30 +00:00
|
|
|
setHasAttemptedDetection(true);
|
2025-07-13 06:47:45 +00:00
|
|
|
return provider;
|
|
|
|
} catch (error) {
|
2025-07-13 17:53:30 +00:00
|
|
|
// Only log the error if it's not the common "no provider" error
|
|
|
|
if (error instanceof Error && !error.message.includes('no WebLN provider')) {
|
|
|
|
console.warn('WebLN detection error:', error);
|
|
|
|
}
|
2025-07-13 06:47:45 +00:00
|
|
|
setWebln(null);
|
2025-07-13 17:53:30 +00:00
|
|
|
setHasAttemptedDetection(true);
|
2025-07-13 06:47:45 +00:00
|
|
|
return null;
|
|
|
|
} finally {
|
|
|
|
setIsDetecting(false);
|
|
|
|
}
|
|
|
|
}, [webln, isDetecting]);
|
|
|
|
|
2025-07-13 17:53:30 +00:00
|
|
|
// Only auto-detect once on mount, don't spam detection
|
2025-07-13 06:47:45 +00:00
|
|
|
useEffect(() => {
|
2025-07-13 17:53:30 +00:00
|
|
|
if (!hasAttemptedDetection) {
|
|
|
|
detectWebLN();
|
|
|
|
}
|
|
|
|
}, [detectWebLN, hasAttemptedDetection]);
|
2025-07-13 06:47:45 +00:00
|
|
|
|
|
|
|
// Test WebLN connection
|
|
|
|
const testWebLN = useCallback(async (): Promise<boolean> => {
|
|
|
|
if (!webln) return false;
|
2025-07-13 17:53:30 +00:00
|
|
|
|
2025-07-13 06:47:45 +00:00
|
|
|
try {
|
|
|
|
await webln.enable();
|
|
|
|
return true;
|
|
|
|
} catch (error) {
|
|
|
|
console.error('WebLN test failed:', error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}, [webln]);
|
|
|
|
|
2025-07-13 17:53:30 +00:00
|
|
|
// Calculate status values reactively
|
|
|
|
const hasNWC = useMemo(() => {
|
|
|
|
return connections.length > 0 && connections.some(c => c.isConnected);
|
|
|
|
}, [connections]);
|
|
|
|
|
2025-07-13 06:47:45 +00:00
|
|
|
// Determine preferred payment method
|
2025-07-13 17:53:30 +00:00
|
|
|
const preferredMethod: WalletStatus['preferredMethod'] = activeNWC
|
|
|
|
? 'nwc'
|
|
|
|
: webln
|
|
|
|
? 'webln'
|
2025-07-13 06:47:45 +00:00
|
|
|
: 'manual';
|
|
|
|
|
|
|
|
const status: WalletStatus = {
|
|
|
|
hasWebLN: !!webln,
|
2025-07-13 17:53:30 +00:00
|
|
|
hasNWC,
|
2025-07-13 06:47:45 +00:00
|
|
|
webln,
|
|
|
|
activeNWC,
|
|
|
|
isDetecting,
|
|
|
|
preferredMethod,
|
|
|
|
};
|
|
|
|
|
2025-07-13 17:53:30 +00:00
|
|
|
// Debug logging for wallet status changes
|
|
|
|
useEffect(() => {
|
|
|
|
console.debug('Wallet status updated:', {
|
|
|
|
hasWebLN: status.hasWebLN,
|
|
|
|
hasNWC: status.hasNWC,
|
|
|
|
connectionsCount: connections.length,
|
|
|
|
activeNWC: !!status.activeNWC,
|
|
|
|
preferredMethod: status.preferredMethod
|
|
|
|
});
|
|
|
|
}, [status.hasWebLN, status.hasNWC, connections.length, status.activeNWC, status.preferredMethod]);
|
|
|
|
|
2025-07-13 06:47:45 +00:00
|
|
|
return {
|
|
|
|
...status,
|
2025-07-13 17:53:30 +00:00
|
|
|
hasAttemptedDetection,
|
2025-07-13 06:47:45 +00:00
|
|
|
detectWebLN,
|
|
|
|
testWebLN,
|
|
|
|
};
|
|
|
|
}
|