story-research-zapwall/hooks/useNostrAuth.ts
2026-01-10 09:41:57 +01:00

94 lines
2.4 KiB
TypeScript

import { useState, useEffect } from 'react'
import { nostrAuthService } from '@/lib/nostrAuth'
import type { NostrConnectState } from '@/types/nostr'
type UseNostrAuthResult = NostrConnectState & {
loading: boolean
error: string | null
connect: () => Promise<void>
disconnect: () => Promise<void>
accountExists: boolean | null
isUnlocked: boolean
}
function useAuthState(): NostrConnectState {
const [state, setState] = useState<NostrConnectState>(nostrAuthService.getState())
useEffect(() => {
const unsubscribe = nostrAuthService.subscribe(setState)
return unsubscribe
}, [])
return state
}
function useAccountExistsStatus(): boolean | null {
const [accountExists, setAccountExists] = useState<boolean | null>(null)
useEffect(() => {
const load = async (): Promise<void> => {
try {
setAccountExists(await nostrAuthService.accountExists())
} catch {
setAccountExists(false)
}
}
void load()
}, [])
return accountExists
}
function createAuthActions(params: {
setLoading: (next: boolean) => void
setError: (next: string | null) => void
}): { connect: () => Promise<void>; disconnect: () => Promise<void> } {
return {
connect: () => connectAuth(params),
disconnect: () => disconnectAuth(params),
}
}
async function connectAuth(params: {
setLoading: (next: boolean) => void
setError: (next: string | null) => void
}): Promise<void> {
params.setLoading(true)
params.setError(null)
try {
await nostrAuthService.connect()
} catch (e) {
params.setError(e instanceof Error ? e.message : 'Connection failed')
} finally {
params.setLoading(false)
}
}
async function disconnectAuth(params: {
setLoading: (next: boolean) => void
setError: (next: string | null) => void
}): Promise<void> {
params.setLoading(true)
try {
nostrAuthService.disconnect()
} catch (e) {
params.setError(e instanceof Error ? e.message : 'Disconnection failed')
} finally {
params.setLoading(false)
}
}
export function useNostrAuth(): UseNostrAuthResult {
const state = useAuthState()
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const accountExists = useAccountExistsStatus()
const { connect, disconnect } = createAuthActions({ setLoading, setError })
return {
...state,
loading,
error,
connect,
disconnect,
accountExists,
isUnlocked: nostrAuthService.isUnlocked(),
}
}