From df2e70f2d1d7da19f80aaac34b1595e6f1a8f969 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Jan 2026 09:11:49 +0000 Subject: [PATCH] refactor: extract canAccountSign helper to useAccount - Move canAccountSign function from relay-state-manager to useAccount.ts - Import and reuse the shared helper in relay-state-manager - Update useAccount hook to use the extracted helper internally - Follows DRY principle by centralizing account sign capability logic This keeps the account sign capability detection logic in one place, making it easier to maintain and ensuring consistency across the app. --- src/hooks/useAccount.ts | 25 ++++++++++++++----------- src/services/relay-state-manager.ts | 11 +---------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/hooks/useAccount.ts b/src/hooks/useAccount.ts index bd30c51..4e25797 100644 --- a/src/hooks/useAccount.ts +++ b/src/hooks/useAccount.ts @@ -2,6 +2,19 @@ import { useMemo } from "react"; import { use$ } from "applesauce-react/hooks"; import accounts from "@/services/accounts"; +/** + * Check if an account can sign events + * Read-only accounts cannot sign and should not be prompted for auth + * + * @param account - The account to check (can be undefined) + * @returns true if the account can sign, false otherwise + */ +export function canAccountSign(account: typeof accounts.active): boolean { + if (!account) return false; + const accountType = account.constructor.name; + return accountType !== "ReadonlyAccount"; +} + /** * Hook to access the active account with signing capability detection * @@ -45,18 +58,8 @@ export function useAccount() { // Check if the account has a functional signer // Read-only accounts have a signer that throws errors on sign operations - // We detect this by checking for the ReadonlySigner type or checking signer methods const signer = account.signer; - let canSign = false; - - if (signer) { - // ReadonlyAccount from applesauce-accounts has a ReadonlySigner - // that throws on signEvent, nip04, nip44 operations - // We can detect it by checking if it's an instance with the expected methods - // but we'll use a safer approach: check the account type name - const accountType = account.constructor.name; - canSign = accountType !== "ReadonlyAccount"; - } + const canSign = canAccountSign(account); return { account, diff --git a/src/services/relay-state-manager.ts b/src/services/relay-state-manager.ts index 3e1bfc4..9cb247d 100644 --- a/src/services/relay-state-manager.ts +++ b/src/services/relay-state-manager.ts @@ -9,6 +9,7 @@ import type { import { transitionAuthState, type AuthEvent } from "@/lib/auth-state-machine"; import { createLogger } from "@/lib/logger"; import { normalizeRelayURL } from "@/lib/relay-url"; +import { canAccountSign } from "@/hooks/useAccount"; import pool from "./relay-pool"; import accountManager from "./accounts"; import db from "./db"; @@ -19,16 +20,6 @@ const MAX_NOTICES = 20; const MAX_ERRORS = 20; const CHALLENGE_TTL = 5 * 60 * 1000; // 5 minutes in milliseconds -/** - * Check if an account can sign events - * Read-only accounts cannot sign and should not be prompted for auth - */ -function canAccountSign(account: typeof accountManager.active): boolean { - if (!account) return false; - const accountType = account.constructor.name; - return accountType !== "ReadonlyAccount"; -} - /** * Observable values emitted by relay observables * Note: Using startWith() to ensure immediate emission with current values