import React, { useState } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPuzzlePiece, faShieldHalved, faCircleInfo } from '@fortawesome/free-solid-svg-icons' import { Hooks } from 'applesauce-react' import { Accounts } from 'applesauce-accounts' import { NostrConnectSigner } from 'applesauce-signers' import { getDefaultBunkerPermissions } from '../services/nostrConnect' const LoginOptions: React.FC = () => { const accountManager = Hooks.useAccountManager() const [showBunkerInput, setShowBunkerInput] = useState(false) const [bunkerUri, setBunkerUri] = useState('') const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) const handleExtensionLogin = async () => { try { setIsLoading(true) setError(null) const account = await Accounts.ExtensionAccount.fromExtension() accountManager.addAccount(account) accountManager.setActive(account) } catch (err) { console.error('Extension login failed:', err) const errorMessage = err instanceof Error ? err.message : String(err) // Check if extension is not installed if (errorMessage.includes('Signer extension missing') || errorMessage.includes('window.nostr') || errorMessage.includes('not found') || errorMessage.includes('undefined') || errorMessage.toLowerCase().includes('extension missing')) { setError( <> No browser extension found. Please install{' '} nos2x {' '}or another nostr extension. ) } else if (errorMessage.includes('denied') || errorMessage.includes('rejected') || errorMessage.includes('cancel')) { setError('Authentication was cancelled or denied.') } else { setError(`Authentication failed: ${errorMessage}`) } } finally { setIsLoading(false) } } const handleBunkerLogin = async () => { if (!bunkerUri.trim()) { setError('Please enter a bunker URI') return } if (!bunkerUri.startsWith('bunker://')) { setError( <> Invalid bunker URI. Must start with bunker://. Don't have a signer? Give{' '} Amber {' '}or{' '} Aegis {' '}a try. ) return } try { setIsLoading(true) setError(null) // Create signer from bunker URI with default permissions const permissions = getDefaultBunkerPermissions() const signer = await NostrConnectSigner.fromBunkerURI(bunkerUri, { permissions }) // Get pubkey from signer const pubkey = await signer.getPublicKey() // Create account from signer const account = new Accounts.NostrConnectAccount(pubkey, signer) // Add to account manager and set active accountManager.addAccount(account) accountManager.setActive(account) // Clear input on success setBunkerUri('') setShowBunkerInput(false) } catch (err) { console.error('[bunker] Login failed:', err) const errorMessage = err instanceof Error ? err.message : 'Failed to connect to bunker' // Check for permission-related errors if (errorMessage.toLowerCase().includes('permission') || errorMessage.toLowerCase().includes('unauthorized')) { setError('Your bunker connection is missing signing permissions. Reconnect and approve signing.') } else { // Show helpful message for bunker connection failures setError( <> Failed: {errorMessage}

Don't have a signer? Give{' '} Amber {' '}or{' '} Aegis {' '}a try. ) } } finally { setIsLoading(false) } } return (

Hi! I'm Boris.

Connect your npub to see your bookmarks, explore long-form articles, and create your own highlights.

{!showBunkerInput && ( )} {!showBunkerInput ? ( ) : (
setBunkerUri(e.target.value)} disabled={isLoading} className="bunker-input" onKeyDown={(e) => { if (e.key === 'Enter') { handleBunkerLogin() } }} />
)}
{error && (
{error}
)}

New to nostr? Start here:{' '} nstart.me

) } export default LoginOptions