From 5633aa154be2fc225b03fdce9c0e04a77e95dfcd Mon Sep 17 00:00:00 2001 From: padreug Date: Sun, 7 Sep 2025 00:19:43 +0200 Subject: [PATCH] Enhance PaymentService and useTicketPurchase composable for improved wallet handling - Introduced asynchronous methods in PaymentService for retrieving user wallets and checking wallet balances, allowing for dual authentication detection. - Updated getUserWalletsAsync, hasWalletWithBalanceAsync, and getWalletWithBalanceAsync methods to streamline wallet access and balance checks. - Refactored useTicketPurchase composable to load user wallets asynchronously on component mount, improving user experience during ticket purchases. - Enhanced error handling and logging for wallet loading and payment processes. These changes improve the reliability and responsiveness of wallet interactions within the payment flow. --- src/core/services/PaymentService.ts | 92 +++++++++++++++++-- .../components/PurchaseTicketDialog.vue | 12 ++- .../events/composables/useTicketPurchase.ts | 35 ++++++- 3 files changed, 123 insertions(+), 16 deletions(-) diff --git a/src/core/services/PaymentService.ts b/src/core/services/PaymentService.ts index 56b19ba..8cf010c 100644 --- a/src/core/services/PaymentService.ts +++ b/src/core/services/PaymentService.ts @@ -52,21 +52,81 @@ export class PaymentService extends BaseService { } /** - * Get user wallets from authenticated user + * Get global auth composable + */ + private async getGlobalAuth() { + try { + // Use async dynamic import to avoid circular dependencies + const { auth } = await import('@/composables/useAuth') + return auth + } catch (error) { + this.debug('Could not access global auth:', error) + return null + } + } + + /** + * Get user wallets from authenticated user (using dual auth detection) + */ + async getUserWalletsAsync() { + // Check both injected auth service AND global auth composable + const hasAuthService = this.authService?.user?.value?.wallets + const globalAuth = await this.getGlobalAuth() + const hasGlobalAuth = globalAuth?.currentUser?.value?.wallets + + const wallets = hasAuthService || hasGlobalAuth || [] + + this.debug('Getting user wallets:', { + hasAuthService: !!hasAuthService, + hasGlobalAuth: !!hasGlobalAuth, + walletsCount: Array.isArray(wallets) ? wallets.length : 0, + walletsSource: hasAuthService ? 'authService' : (hasGlobalAuth ? 'globalAuth' : 'none') + }) + + return wallets + } + + /** + * Get user wallets from authenticated user (synchronous fallback) */ get userWallets() { + // Fallback to just auth service for synchronous access return this.authService?.user?.value?.wallets || [] } /** - * Check if user has any wallet with balance + * Check if user has any wallet with balance (async version) + */ + async hasWalletWithBalanceAsync(): Promise { + const wallets = await this.getUserWalletsAsync() + return wallets.some((wallet: any) => wallet.balance_msat > 0) + } + + /** + * Check if user has any wallet with balance (synchronous fallback) */ get hasWalletWithBalance(): boolean { return this.userWallets.some((wallet: any) => wallet.balance_msat > 0) } /** - * Find wallet with sufficient balance for payment + * Find wallet with sufficient balance for payment (async version) + */ + async getWalletWithBalanceAsync(requiredAmountSats?: number): Promise { + const wallets = await this.getUserWalletsAsync() + if (!wallets.length) return null + + if (requiredAmountSats) { + // Convert sats to msat for comparison + const requiredMsat = requiredAmountSats * 1000 + return wallets.find((wallet: any) => wallet.balance_msat >= requiredMsat) + } + + return wallets.find((wallet: any) => wallet.balance_msat > 0) + } + + /** + * Find wallet with sufficient balance for payment (synchronous fallback) */ getWalletWithBalance(requiredAmountSats?: number): any | null { const wallets = this.userWallets @@ -137,14 +197,26 @@ export class PaymentService extends BaseService { requiredAmountSats?: number, options: PaymentOptions = {} ): Promise { - // Check authentication - if (!this.authService?.isAuthenticated?.value || !this.authService?.user?.value) { + // Check authentication using dual auth detection + const hasAuthService = this.authService?.isAuthenticated?.value && this.authService?.user?.value + const globalAuth = await this.getGlobalAuth() + const hasGlobalAuth = globalAuth?.isAuthenticated?.value && globalAuth?.currentUser?.value + + if (!hasAuthService && !hasGlobalAuth) { + this.debug('Payment failed - user not authenticated:', { + hasAuthService: !!hasAuthService, + hasGlobalAuth: !!hasGlobalAuth + }) throw new Error('User must be authenticated to pay with wallet') } - // Find suitable wallet - const wallet = this.getWalletWithBalance(requiredAmountSats) + // Find suitable wallet using async version for proper dual auth detection + const wallet = await this.getWalletWithBalanceAsync(requiredAmountSats) if (!wallet) { + this.debug('No wallet with sufficient balance found:', { + requiredAmountSats, + walletsAvailable: (await this.getUserWalletsAsync()).length + }) throw new Error('No wallet with sufficient balance found') } @@ -235,8 +307,8 @@ export class PaymentService extends BaseService { return null } - // Try wallet payment first if user has balance - if (this.hasWalletWithBalance) { + // Try wallet payment first if user has balance (use async check for proper dual auth detection) + if (await this.hasWalletWithBalanceAsync()) { try { return await this.payWithWallet( paymentRequest, @@ -247,6 +319,8 @@ export class PaymentService extends BaseService { this.debug('Wallet payment failed, offering external wallet option:', error) // Don't throw here, continue to external wallet option } + } else { + this.debug('No wallet with balance available, skipping wallet payment') } // Fallback to external wallet diff --git a/src/modules/events/components/PurchaseTicketDialog.vue b/src/modules/events/components/PurchaseTicketDialog.vue index 4255ee5..4c93ace 100644 --- a/src/modules/events/components/PurchaseTicketDialog.vue +++ b/src/modules/events/components/PurchaseTicketDialog.vue @@ -1,6 +1,6 @@