diff --git a/components/KeyManagementManager.tsx b/components/KeyManagementManager.tsx index 466a02b..6fc80f5 100644 --- a/components/KeyManagementManager.tsx +++ b/components/KeyManagementManager.tsx @@ -411,4 +411,3 @@ export function KeyManagementManager() { ) } - diff --git a/features/key-management-configuration.md b/features/key-management-configuration.md index cc50f7d..49c0a2e 100644 --- a/features/key-management-configuration.md +++ b/features/key-management-configuration.md @@ -121,4 +121,3 @@ Créer une page de configuration permettant de : - Vérifier que les mots de récupération sont affichés une seule fois - Vérifier que la clé privée n'est jamais affichée - Vérifier que le système de chiffrement à deux niveaux est respecté - diff --git a/lib/nip98.ts b/lib/nip98.ts index 868c407..94536a4 100644 --- a/lib/nip98.ts +++ b/lib/nip98.ts @@ -5,8 +5,10 @@ */ import type { EventTemplate } from 'nostr-tools' -import { nostrRemoteSigner } from './nostrRemoteSigner' +import { finalizeEvent } from 'nostr-tools' +import { hexToBytes } from 'nostr-tools/utils' import { nostrService } from './nostr' +import { nostrAuthService } from './nostrAuth' /** * Generate NIP-98 authentication token for HTTP request @@ -18,7 +20,17 @@ import { nostrService } from './nostr' export async function generateNip98Token(method: string, url: string, payloadHash?: string): Promise { const pubkey = nostrService.getPublicKey() if (!pubkey) { - throw new Error('Public key required for NIP-98 authentication. Please connect with a Nostr extension.') + throw new Error('Public key required for NIP-98 authentication. Please unlock your account.') + } + + // Check if private key is available (unlocked) + if (!nostrAuthService.isUnlocked()) { + throw new Error('Private key required for NIP-98 authentication. Please unlock your account with your recovery phrase.') + } + + const privateKey = nostrAuthService.getPrivateKey() + if (!privateKey) { + throw new Error('Private key not available. Please unlock your account.') } // Parse URL to get components @@ -36,18 +48,17 @@ export async function generateNip98Token(method: string, url: string, payloadHas tags.push(['payload', payloadHash]) } - const eventTemplate: EventTemplate = { + const eventTemplate: EventTemplate & { pubkey: string } = { kind: 27235, // NIP-98 kind for HTTP auth created_at: Math.floor(Date.now() / 1000), tags: tags, content: '', + pubkey: pubkey, } - // Sign the event - const signedEvent = await nostrRemoteSigner.signEvent(eventTemplate) - if (!signedEvent) { - throw new Error('Failed to sign NIP-98 authentication event') - } + // Sign the event directly with the private key (no plugin needed) + const secretKey = hexToBytes(privateKey) + const signedEvent = finalizeEvent(eventTemplate, secretKey) // Encode event as base64 JSON const eventJson = JSON.stringify(signedEvent) @@ -59,7 +70,10 @@ export async function generateNip98Token(method: string, url: string, payloadHas /** * Check if NIP-98 authentication is available + * Requires both public key and unlocked private key */ export function isNip98Available(): boolean { - return nostrRemoteSigner.isAvailable() + const pubkey = nostrService.getPublicKey() + const isUnlocked = nostrAuthService.isUnlocked() + return !!pubkey && isUnlocked }