From 7eecec750647ad19ee1e74a496b34707bc6f1150 Mon Sep 17 00:00:00 2001 From: Chad Curtis Date: Sun, 13 Jul 2025 20:12:42 +0000 Subject: [PATCH] tidying --- src/components/ZapButton.tsx | 1 - src/components/ZapDialog.tsx | 45 ++---------------------- src/hooks/useNWC.ts | 64 ++-------------------------------- src/hooks/useWallet.ts | 2 +- src/hooks/useZaps.ts | 67 ++++++------------------------------ 5 files changed, 18 insertions(+), 161 deletions(-) diff --git a/src/components/ZapButton.tsx b/src/components/ZapButton.tsx index ddfae56..2e8d79b 100644 --- a/src/components/ZapButton.tsx +++ b/src/components/ZapButton.tsx @@ -10,7 +10,6 @@ interface ZapButtonProps { target: Event; className?: string; showCount?: boolean; - // New: option to pass pre-fetched zap data (for batch mode) zapData?: { count: number; totalSats: number; isLoading?: boolean }; } diff --git a/src/components/ZapDialog.tsx b/src/components/ZapDialog.tsx index 1e674b9..7a33eef 100644 --- a/src/components/ZapDialog.tsx +++ b/src/components/ZapDialog.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, useRef } from 'react'; -import { Zap, Copy, Sparkle, Sparkles, Star, Rocket, Wallet, Globe } from 'lucide-react'; +import { Zap, Copy, Sparkle, Sparkles, Star, Rocket } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Dialog, @@ -40,24 +40,7 @@ export function ZapDialog({ target, children, className }: ZapDialogProps) { const { user } = useCurrentUser(); const { data: author } = useAuthor(target.pubkey); const { toast } = useToast(); - const { webln, activeNWC, hasWebLN, hasNWC, detectWebLN } = useWallet(); - - // Debug logging - useEffect(() => { - console.debug('ZapDialog wallet status:', { hasWebLN, hasNWC, activeNWC: !!activeNWC }); - }, [hasWebLN, hasNWC, activeNWC]); - - // Additional debug logging when dialog opens - useEffect(() => { - if (open) { - console.debug('ZapDialog opened with wallet status:', { - hasWebLN, - hasNWC, - activeNWC: activeNWC ? { alias: activeNWC.alias, isConnected: activeNWC.isConnected } : null - }); - } - }, [open, hasWebLN, hasNWC, activeNWC]); - + const { webln, activeNWC, hasWebLN, detectWebLN } = useWallet(); const { zap, isZapping, invoice, setInvoice } = useZaps(target, webln, activeNWC, () => setOpen(false)); const [amount, setAmount] = useState(100); const [comment, setComment] = useState(''); @@ -104,7 +87,7 @@ export function ZapDialog({ target, children, className }: ZapDialogProps) { zap(finalAmount, comment); }; - if (!user || user.pubkey === target.pubkey || !author?.metadata?.lud16) { + if (!user || user.pubkey === target.pubkey || !author?.metadata?.lud06 && !author?.metadata?.lud16) { return null; } @@ -141,28 +124,6 @@ export function ZapDialog({ target, children, className }: ZapDialogProps) { ) : ( <> - {/* Payment Method Indicator */} -
-
- {hasNWC ? ( - <> - - Wallet Connected - - ) : hasWebLN ? ( - <> - - WebLN Available - - ) : ( - <> - - Manual Payment - - )} -
-
-
('nwc-active-connection', null); const [connectionInfo, setConnectionInfo] = useState>({}); - // Use connections directly - no filtering needed - // Parse and validate NWC URI const parseNWCUri = (uri: string): { connectionString: string } | null => { try { @@ -70,8 +68,6 @@ export function useNWCInternal() { } try { - console.debug('Testing NWC connection:', { uri: uri.substring(0, 50) + '...' }); - // Test the connection by creating an LN client with timeout const testPromise = new Promise((resolve, reject) => { try { @@ -81,18 +77,15 @@ export function useNWCInternal() { reject(error); } }); - const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Connection test timeout')), 10000); }); - - const _client = await Promise.race([testPromise, timeoutPromise]) as LN; + await Promise.race([testPromise, timeoutPromise]) as LN; const connection: NWCConnection = { connectionString: parsed.connectionString, alias: alias || 'NWC Wallet', isConnected: true, - // Don't store the client, create fresh ones for each payment }; // Store basic connection info @@ -107,33 +100,9 @@ export function useNWCInternal() { const newConnections = [...connections, connection]; setConnections(newConnections); - console.debug('NWC connection added:', { - alias: connection.alias, - totalConnections: newConnections.length, - connectionString: parsed.connectionString.substring(0, 50) + '...', - isConnected: connection.isConnected - }); - // Set as active if it's the first connection or no active connection is set - if (connections.length === 0 || !activeConnection) { - console.debug('Setting as active connection:', { - alias: connection.alias, - connectionString: parsed.connectionString.substring(0, 50) + '...', - previousActiveConnection: activeConnection - }); + if (connections.length === 0 || !activeConnection) setActiveConnection(parsed.connectionString); - console.debug('Active connection set to:', parsed.connectionString.substring(0, 50) + '...'); - } - - console.debug('NWC connection successful'); - - // Force a small delay to ensure state updates are processed - setTimeout(() => { - console.debug('Post-connection state check:', { - connectionsLength: connections.length + 1, // +1 because we just added one - newConnectionAlias: connection.alias - }); - }, 100); toast({ title: 'Wallet connected', @@ -159,14 +128,9 @@ export function useNWCInternal() { const filtered = connections.filter(c => c.connectionString !== connectionString); setConnections(filtered); - console.debug('NWC connection removed:', { - remainingConnections: filtered.length - }); - if (activeConnection === connectionString) { const newActive = filtered.length > 0 ? filtered[0].connectionString : null; setActiveConnection(newActive); - console.debug('Active connection changed:', { newActive }); } setConnectionInfo(prev => { @@ -183,15 +147,8 @@ export function useNWCInternal() { // Get active connection const getActiveConnection = useCallback((): NWCConnection | null => { - console.debug('getActiveConnection called:', { - activeConnection, - connectionsLength: connections.length, - connections: connections.map(c => ({ alias: c.alias, connectionString: c.connectionString.substring(0, 50) + '...' })) - }); - // If no active connection is set but we have connections, set the first one as active if (!activeConnection && connections.length > 0) { - console.debug('Setting first connection as active:', connections[0].alias); setActiveConnection(connections[0].connectionString); return connections[0]; } @@ -202,7 +159,6 @@ export function useNWCInternal() { } const found = connections.find(c => c.connectionString === activeConnection); - console.debug('Found active connection:', found ? found.alias : 'null'); return found || null; }, [activeConnection, connections, setActiveConnection]); @@ -218,7 +174,6 @@ export function useNWCInternal() { // Always create a fresh client for each payment to avoid stale connections let client: LN; try { - console.debug('Creating fresh NWC client for payment...'); client = new LN(connection.connectionString); } catch (error) { console.error('Failed to create NWC client:', error); @@ -226,20 +181,13 @@ export function useNWCInternal() { } try { - console.debug('Sending payment via NWC SDK:', { - invoice: invoice.substring(0, 50) + '...', - connectionAlias: connection.alias - }); - // Add timeout to prevent hanging const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Payment timeout after 30 seconds')), 30000); + setTimeout(() => reject(new Error('Payment timeout after 15 seconds')), 15); }); const paymentPromise = client.pay(invoice); const response = await Promise.race([paymentPromise, timeoutPromise]) as { preimage: string }; - - console.debug('Payment successful:', { preimage: response.preimage }); return response; } catch (error) { console.error('NWC payment failed:', error); @@ -279,8 +227,6 @@ export function useNWCInternal() { } try { - console.debug('Testing NWC connection...', { alias: connection.alias }); - // Create a fresh client for testing const testPromise = new Promise((resolve, reject) => { try { @@ -294,10 +240,8 @@ export function useNWCInternal() { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Connection test timeout')), 5000); }); - await Promise.race([testPromise, timeoutPromise]); - console.debug('NWC connection test successful'); return true; } catch (error) { console.error('NWC connection test failed:', error); @@ -305,8 +249,6 @@ export function useNWCInternal() { } }, []); - - return { connections, activeConnection, diff --git a/src/hooks/useWallet.ts b/src/hooks/useWallet.ts index 69316f9..14dbc45 100644 --- a/src/hooks/useWallet.ts +++ b/src/hooks/useWallet.ts @@ -44,7 +44,7 @@ export function useWallet() { } }, [webln, isDetecting]); - // Only auto-detect once on mount, don't spam detection + // Only auto-detect once on mount useEffect(() => { if (!hasAttemptedDetection) { detectWebLN(); diff --git a/src/hooks/useZaps.ts b/src/hooks/useZaps.ts index 1c6be1b..7e5e3c6 100644 --- a/src/hooks/useZaps.ts +++ b/src/hooks/useZaps.ts @@ -24,7 +24,6 @@ function parseNWCUri(uri: string): NWCConnection | null { const walletPubkey = url.pathname.replace('//', ''); const secret = url.searchParams.get('secret'); const relayParam = url.searchParams.getAll('relay'); - const _lud16 = url.searchParams.get('lud16') || undefined; if (!walletPubkey || !secret || relayParam.length === 0) { return null; @@ -194,7 +193,7 @@ export function useZaps( } try { - if (!author.data || !author.data?.metadata) { + if (!author.data || !author.data?.metadata || !author.data?.event ) { toast({ title: 'Author not found', description: 'Could not find the author of this item.', @@ -204,8 +203,8 @@ export function useZaps( return; } - const { lud16 } = author.data.metadata; - if (!lud16) { + const { lud06, lud16 } = author.data.metadata; + if (!lud06 && !lud16) { toast({ title: 'Lightning address not found', description: 'The author does not have a lightning address configured.', @@ -216,7 +215,7 @@ export function useZaps( } // Get zap endpoint using the old reliable method - const zapEndpoint = await nip57.getZapEndpoint(author.data.event as Event); + const zapEndpoint = await nip57.getZapEndpoint(author.data.event); if (!zapEndpoint) { toast({ title: 'Zap endpoint not found', @@ -227,30 +226,20 @@ export function useZaps( return; } + // Create zap request const zapAmount = amount * 1000; // convert to millisats - const relays = [config.relayUrl]; - - // Create zap request (unsigned, like the old implementation) const zapRequest = nip57.makeZapRequest({ profile: primaryTarget.pubkey, - event: primaryTarget.id, + event: primaryTarget, amount: zapAmount, - relays, - comment: comment, + relays: [config.relayUrl], + comment }); - // Handle addressable events - if (primaryTarget.kind >= 30000 && primaryTarget.kind < 40000) { - const identifier = primaryTarget.tags.find((t) => t[0] === 'd')?.[1] || ''; - zapRequest.tags.push(["a", `${primaryTarget.kind}:${primaryTarget.pubkey}:${identifier}`]); - zapRequest.tags = zapRequest.tags.filter(t => t[0] !== 'e'); - } - // Sign and publish the zap request publishEvent(zapRequest, { onSuccess: async (event) => { try { - // Use the old fetch method - more reliable than LNURL validation const res = await fetch(`${zapEndpoint}?amount=${zapAmount}&nostr=${encodeURI(JSON.stringify(event))}`); const responseData = await res.json(); @@ -266,38 +255,10 @@ export function useZaps( // Get the current active NWC connection dynamically const currentNWCConnection = getActiveConnection(); - console.debug('Zap payment - detailed state check:', { - // Raw state - connectionsLength: connections.length, - activeConnectionString: activeConnection ? activeConnection.substring(0, 50) + '...' : null, - - // Connection details - connections: connections.map(c => ({ - alias: c.alias, - isConnected: c.isConnected, - connectionString: c.connectionString.substring(0, 50) + '...' - })), - - // getActiveConnection result - currentNWCConnection: currentNWCConnection ? { - alias: currentNWCConnection.alias, - isConnected: currentNWCConnection.isConnected, - connectionString: currentNWCConnection.connectionString.substring(0, 50) + '...' - } : null - }); - // Try NWC first if available and properly connected if (currentNWCConnection && currentNWCConnection.connectionString && currentNWCConnection.isConnected) { try { - console.debug('Attempting NWC payment...', { - amount, - alias: currentNWCConnection.alias, - invoiceLength: newInvoice.length - }); - - const response = await sendPayment(currentNWCConnection, newInvoice); - - console.debug('NWC payment successful:', { preimage: response.preimage }); + await sendPayment(currentNWCConnection, newInvoice); // Clear states immediately on success setIsZapping(false); @@ -322,10 +283,7 @@ export function useZaps( variant: 'destructive', }); } - } - - // Fallback to WebLN or manual payment - if (webln) { + } else if (webln) { // Try WebLN next await webln.sendPayment(newInvoice); // Clear states immediately on success @@ -339,7 +297,7 @@ export function useZaps( // Close dialog last to ensure clean state onZapSuccess?.(); - } else { + } else { // Default - show QR code and manual Lightning URI setInvoice(newInvoice); setIsZapping(false); } @@ -376,7 +334,6 @@ export function useZaps( }; return { - // Legacy single-target API (for backward compatibility) zaps, ...query, zap, @@ -384,8 +341,6 @@ export function useZaps( invoice, setInvoice, parseNWCUri, - - // New batch API zapData, isBatchMode,