94 lines
2.4 KiB
TypeScript
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(),
|
|
}
|
|
}
|