From 074de680dfa5ad9a1404c2141c0aed3a8308c431 Mon Sep 17 00:00:00 2001 From: austinkelsay Date: Tue, 13 May 2025 11:47:00 -0500 Subject: [PATCH] prevent race conditions in BitcoinConnect initialization by memoizing promise, clean up some logs --- .../bitcoinConnect/BitcoinConnect.js | 19 +++++++++++++------ .../SubscriptionPaymentButton.js | 6 ++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/components/bitcoinConnect/BitcoinConnect.js b/src/components/bitcoinConnect/BitcoinConnect.js index d2f0a01..6e60241 100644 --- a/src/components/bitcoinConnect/BitcoinConnect.js +++ b/src/components/bitcoinConnect/BitcoinConnect.js @@ -7,10 +7,15 @@ const Button = dynamic(() => import('@getalby/bitcoin-connect-react').then(mod = // Module-level state let initialized = false; +let initializationPromise = null; let bitcoinConnectClient = null; export async function initializeBitcoinConnect() { - if (!initialized) { + if (initialized) return bitcoinConnectClient; // fast path + + if (initializationPromise) return initializationPromise; // someone else is already doing the work + + initializationPromise = (async () => { try { // Import the required modules const bc = await import('@getalby/bitcoin-connect-react'); @@ -38,18 +43,20 @@ export async function initializeBitcoinConnect() { initialized = true; console.log('Bitcoin Connect initialized successfully, client:', bitcoinConnectClient); + return bitcoinConnectClient; } catch (error) { // If the error is about custom element already being defined, we can ignore it // as it means the component is already initialized if (!error.message?.includes('has already been defined as a custom element')) { console.error('Error initializing Bitcoin Connect:', error); } + throw error; // re-throw so callers see the failure + } finally { + initializationPromise = null; // allow retry after failure } - } else { - console.log('Bitcoin Connect already initialized'); - } - - return bitcoinConnectClient; + })(); + + return initializationPromise; } // Export the SDK for direct usage diff --git a/src/components/bitcoinConnect/SubscriptionPaymentButton.js b/src/components/bitcoinConnect/SubscriptionPaymentButton.js index 921d6a8..8ee2819 100644 --- a/src/components/bitcoinConnect/SubscriptionPaymentButton.js +++ b/src/components/bitcoinConnect/SubscriptionPaymentButton.js @@ -76,7 +76,6 @@ const SubscriptionPaymentButtons = ({ satoshi: amount, comment: `Subscription Purchase. User: ${session?.user?.id}`, }); - console.log("Invoice fetched successfully:", newInvoice); return newInvoice; } catch (error) { console.error('Error fetching invoice:', error); @@ -132,7 +131,6 @@ const SubscriptionPaymentButtons = ({ // Get NWC URL const newNWCUrl = newNwc.getNostrWalletConnectUrl(); - console.log("NWC URL generated:", !!newNWCUrl); if (newNWCUrl) { const nwcProvider = new sdk.webln.NostrWebLNProvider({ @@ -153,7 +151,7 @@ const SubscriptionPaymentButtons = ({ console.log("Sending payment with NWC provider"); const paymentResponse = await nwcProvider.sendPayment(invoice.paymentRequest); - console.log("Payment response:", paymentResponse); + console.log("Payment response:", paymentResponse?.preimage); if (!paymentResponse || !paymentResponse?.preimage) { showToast('error', 'NWC', 'Payment failed'); @@ -215,7 +213,7 @@ const SubscriptionPaymentButtons = ({ console.log("Sending payment with manual NWC"); const payResponse = await nwc.sendPayment(invoice.paymentRequest); - console.log("Payment response:", payResponse); + console.log("Payment response:", payResponse?.preimage); if (!payResponse || !payResponse.preimage) { showToast('error', 'NWC', 'Payment failed');