UNPKG

cyphertap

Version:

Nostr, Lightning and Ecash on a single Button component

113 lines (112 loc) 4.6 kB
// src/lib/client/services/initialization.ts import { get } from 'svelte/store'; import { BROWSER as browser } from 'esm-env'; import { ndkInstance, currentUser, autoLogin, EXTENSION_LOGIN } from '../stores/nostr.js'; import { initWallet } from '../stores/wallet.js'; import { createDebug } from '../utils/debug.js'; import { initNavigation } from '../stores/navigation.js'; import { startUnpublishedEventsMonitor } from './unpublishedEvents.js'; // Create a debug logger const d = createDebug('init'); // Simple status enum export var InitStatus; (function (InitStatus) { InitStatus["IDLE"] = "idle"; InitStatus["INITIALIZING"] = "initializing"; InitStatus["INITIALIZED"] = "initialized"; InitStatus["ERROR"] = "error"; })(InitStatus || (InitStatus = {})); // Create a state object to track initialization status export const appState = $state({ status: InitStatus.IDLE, error: null, isInitialized: false }); /** * Main initialization function that sets up the entire app * This is the only function called from the layout * @param skipAuth Whether to skip authentication (for login pages) */ export async function initializeApp(skipAuth = false) { // Prevent multiple initialization attempts if (appState.status === InitStatus.INITIALIZING) { d.log('Initialization already in progress, skipping'); return { initialized: false }; } d.log('Starting app initialization'); appState.status = InitStatus.INITIALIZING; appState.error = null; try { // Step 1: Auto-login if needed let autoLoginSuccess = false; if (!skipAuth && browser) { d.log('Attempting auto-login'); try { autoLoginSuccess = await autoLogin() !== null; d.log(`Auto-login result: ${autoLoginSuccess ? 'success' : 'failed'}`); } catch (error) { d.error('Auto-login error:', error); // If extension marker exists but extension is not available if (localStorage.getItem(EXTENSION_LOGIN) === 'true' && !window.nostr) { appState.error = 'Nostr extension not found. Please install or enable your extension.'; } else { appState.error = error instanceof Error ? error.message : 'Auto-login failed'; } // Clear any problematic markers localStorage.removeItem(EXTENSION_LOGIN); return { initialized: false }; } } else { d.log('Skipping auto-login'); } // Step 2: Check if we have NDK instance and user after auto-login const ndk = get(ndkInstance); const user = get(currentUser); // If we don't have both NDK and user, we're not ready for full app initialization if (!ndk || !user) { d.log('No NDK instance or user available, initialization incomplete'); if (skipAuth) { // This is expected on login page d.log('Auth skipped, this is likely the login page'); appState.status = InitStatus.IDLE; return { initialized: false }; } else { // This is unexpected on non-login pages appState.status = InitStatus.ERROR; appState.error = 'Authentication required'; return { initialized: false }; } } // Step 3: Initialize all components since we have NDK and user d.log('NDK and user available, initializing components'); console.log(ndk.activeUser?.pubkey, user.pubkey); initNavigation(); // Initialize async components // await initWallet(); // Start monitoring for unpublished events // d.log('Starting unpublished events monitor'); // startUnpublishedEventsMonitor(); // Mark initialization as complete d.log('App initialization complete'); appState.status = InitStatus.INITIALIZED; appState.isInitialized = true; return { initialized: true }; } catch (error) { d.error('App initialization failed:', error); appState.status = InitStatus.ERROR; appState.error = error instanceof Error ? error.message : 'Unknown initialization error'; return { initialized: false }; } } /** * Check if user is authenticated and app is initialized * Useful for route guards */ export function isAppReady() { return !!get(currentUser) && appState.isInitialized; }