ns-auth-sdk 1.12.0 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -197,6 +197,8 @@ const PRF_EVAL_INPUT = new TextEncoder().encode("nostr-pwk");
197
197
  */
198
198
  async function isPrfSupported() {
199
199
  try {
200
+ const cryptoObj = typeof window !== "undefined" && window.crypto || globalThis.crypto;
201
+ if (!cryptoObj || !cryptoObj.subtle) return false;
200
202
  const response = await navigator.credentials.get({ publicKey: {
201
203
  challenge: crypto.getRandomValues(new Uint8Array(32)),
202
204
  allowCredentials: [],
@@ -301,6 +303,11 @@ function fromBase64(b64) {
301
303
  }
302
304
  async function checkPRFSupport() {
303
305
  try {
306
+ const cryptoObj = typeof window !== "undefined" && window.crypto || globalThis.crypto;
307
+ if (!cryptoObj || !cryptoObj.subtle) {
308
+ console.log("Web Crypto API not available, falling back to password-protected key");
309
+ return false;
310
+ }
304
311
  const supported = (typeof PublicKeyCredential !== "undefined" ? await PublicKeyCredential.getClientCapabilities() : null)?.["extension:prf"] === true;
305
312
  if (supported) console.log("PRF extension is supported.");
306
313
  else console.log("PRF extension is not supported.");
@@ -423,7 +430,9 @@ async function getPublicKeyFromPassword(password, salt = DEFAULT_SALT) {
423
430
  async function deriveSaltFromUsername(username) {
424
431
  if (!username) return "";
425
432
  const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());
426
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
433
+ const subtle = globalThis.crypto?.subtle;
434
+ if (!subtle) throw new Error("Web Crypto API not available");
435
+ const hashBuffer = await subtle.digest("SHA-256", msgBuffer);
427
436
  return bytesToHex(new Uint8Array(hashBuffer));
428
437
  }
429
438
  function parseRecoveryTag(tags) {
@@ -466,7 +475,9 @@ async function verifyRecoverySignature(kind0) {
466
475
  }
467
476
  async function sha256(message) {
468
477
  const msgBuffer = new TextEncoder().encode(message);
469
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
478
+ const subtle = globalThis.crypto?.subtle;
479
+ if (!subtle) throw new Error("Web Crypto API not available");
480
+ const hashBuffer = await subtle.digest("SHA-256", msgBuffer);
470
481
  return new Uint8Array(hashBuffer);
471
482
  }
472
483
  /**
@@ -865,6 +876,11 @@ var NosskeyManager = class {
865
876
  */
866
877
  const INFO_BYTES = new TextEncoder().encode("nostr-pwk");
867
878
  const AES_LENGTH = 256;
879
+ function getSubtle() {
880
+ const subtle = globalThis.crypto?.subtle;
881
+ if (!subtle) throw new Error("Web Crypto API not available");
882
+ return subtle;
883
+ }
868
884
  /**
869
885
  * PRF AES-GCM
870
886
  * @param secret PRF
@@ -872,8 +888,9 @@ const AES_LENGTH = 256;
872
888
  * @returns AES-GCM
873
889
  */
874
890
  async function deriveAesGcmKey(secret, salt) {
875
- const keyMaterial = await crypto.subtle.importKey("raw", secret, "HKDF", false, ["deriveKey"]);
876
- return crypto.subtle.deriveKey({
891
+ const subtle = getSubtle();
892
+ const keyMaterial = await subtle.importKey("raw", secret, "HKDF", false, ["deriveKey"]);
893
+ return subtle.deriveKey({
877
894
  name: "HKDF",
878
895
  hash: "SHA-256",
879
896
  salt,
@@ -891,7 +908,7 @@ async function deriveAesGcmKey(secret, salt) {
891
908
  * @returns
892
909
  */
893
910
  async function aesGcmEncrypt(key, iv, plaintext) {
894
- const buf = await crypto.subtle.encrypt({
911
+ const buf = await getSubtle().encrypt({
895
912
  name: "AES-GCM",
896
913
  iv
897
914
  }, key, plaintext);
@@ -910,7 +927,7 @@ async function aesGcmEncrypt(key, iv, plaintext) {
910
927
  * @returns
911
928
  */
912
929
  async function aesGcmDecrypt(key, iv, ct, tag) {
913
- const buf = await crypto.subtle.decrypt({
930
+ const buf = await getSubtle().decrypt({
914
931
  name: "AES-GCM",
915
932
  iv
916
933
  }, key, new Uint8Array([...ct, ...tag]));
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["#cacheOptions","#cachedEntry","#clearCachedEntry","#scheduleExpiry","#getCachedKeyIfValid","#clearKey","#expiryTimer","secp256k1","#keyCache","#storageOptions","#prfOptions","#loadKeyInfoFromStorage","#currentKeyInfo","#saveKeyInfoToStorage","#clearKey","#signWithKey"],"sources":["../src/utils/utils.ts","../src/utils/key-cache.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/nosskey.ts","../src/utils/crypto-utils.ts","../src/utils/test-utils.ts","../src/services/auth.service.ts","../src/utils/validation.ts","../src/services/relay.service.ts"],"sourcesContent":["/**\n * @packageDocumentation\n */\n\n/**\n * @param bytes\n * @returns\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n const key = '0123456789abcdef';\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n const firstNibble = bytes[i] >> 4;\n const secondNibble = bytes[i] & 15;\n hex += key[firstNibble] + key[secondNibble];\n }\n return hex;\n}\n\n/**\n * @param hex\n * @returns\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const key = '0123456789abcdef';\n const bytes = [];\n let currentByte = 0;\n let highNibble = true;\n\n for (let i = 0; i < hex.length; i++) {\n const charValue = key.indexOf(hex[i].toLowerCase());\n if (charValue === -1) continue;\n\n if (highNibble) {\n currentByte = charValue << 4;\n highNibble = false;\n } else {\n currentByte += charValue;\n bytes.push(currentByte);\n highNibble = true;\n }\n }\n\n return new Uint8Array(bytes);\n}\n","/**\n * Key cache management for Nosskey\n * @packageDocumentation\n */\n\nimport type { KeyCacheOptions } from './types.js';\nimport { bytesToHex } from './utils.js';\n\n/**\n * Key cache entry with expiration time\n */\ninterface CacheEntry {\n id: string;\n sk: Uint8Array;\n expireAt: number;\n}\n\n/**\n * Key cache manager for managing temporary secret keys\n */\nexport class KeyCache {\n #cachedEntry: CacheEntry | null = null;\n\n #expiryTimer: NodeJS.Timeout | null = null;\n\n #cacheOptions: KeyCacheOptions = {\n enabled: false,\n timeoutMs: 5 * 60 * 1000,\n };\n\n /**\n * KeyCache\n * @param options\n */\n constructor(options?: Partial<KeyCacheOptions>) {\n if (options) {\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n if (Object.keys(options).length > 0 && this.#cachedEntry !== null) {\n this.clearAllCachedKeys();\n }\n\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n\n getCacheOptions(): KeyCacheOptions {\n return { ...this.#cacheOptions };\n }\n\n isEnabled(): boolean {\n return this.#cacheOptions.enabled;\n }\n\n /**\n * @param credentialId\n * @param sk\n */\n setKey(credentialId: Uint8Array | string, sk: Uint8Array): void {\n if (!this.#cacheOptions.enabled) return;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n const timeout =\n this.#cacheOptions.timeoutMs !== undefined ? this.#cacheOptions.timeoutMs : 5 * 60 * 1000;\n const expireAt = Date.now() + timeout;\n\n this.#clearCachedEntry();\n\n this.#cachedEntry = {\n id,\n sk: new Uint8Array(sk),\n expireAt,\n };\n\n try {\n this.#scheduleExpiry();\n } catch (error) {\n this.#clearCachedEntry();\n throw error;\n }\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n getKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n if (!this.#cacheOptions.enabled) return undefined;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n return this.#getCachedKeyIfValid(id);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n\n if (this.#cachedEntry && this.#cachedEntry.id === id) {\n this.#clearCachedEntry();\n }\n }\n\n clearAllCachedKeys(): void {\n this.#clearCachedEntry();\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n #getCachedKeyIfValid(credentialId: string): Uint8Array | undefined {\n if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) {\n return undefined;\n }\n\n if (Date.now() < this.#cachedEntry.expireAt) {\n return this.#cachedEntry.sk;\n }\n\n this.#clearCachedEntry();\n return undefined;\n }\n\n #clearCachedEntry(): void {\n if (this.#cachedEntry) {\n this.#clearKey(this.#cachedEntry.sk);\n this.#cachedEntry = null;\n }\n\n if (this.#expiryTimer) {\n clearTimeout(this.#expiryTimer);\n this.#expiryTimer = null;\n }\n }\n\n #scheduleExpiry(): void {\n if (!this.#cachedEntry) return;\n\n const now = Date.now();\n const timeToExpiry = this.#cachedEntry.expireAt - now;\n\n if (timeToExpiry <= 0) {\n this.#clearCachedEntry();\n return;\n }\n\n this.#expiryTimer = setTimeout(() => {\n this.#clearCachedEntry();\n }, timeToExpiry + 1);\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * PRF (Pseudo-Random Function) handler for WebAuthn\n * @packageDocumentation\n */\n\nimport type { GetPrfSecretOptions, PasskeyCreationOptions } from './types.js';\n\nconst PRF_EVAL_INPUT = new TextEncoder().encode('nostr-pwk');\n\n/**\n * @returns PRF\n */\nexport async function isPrfSupported(): Promise<boolean> {\n try {\n const response = await navigator.credentials.get({\n publicKey: {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials: [],\n userVerification: 'required',\n extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } },\n } as PublicKeyCredentialRequestOptions,\n });\n\n if (!response) return false;\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const res = assertion.getClientExtensionResults()?.prf?.results?.first;\n return !!res;\n } catch {\n return false;\n }\n}\n\n/**\n * @param options\n * @returns Credential\n */\nexport async function createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n // Node\n const rpName = options.rp?.name || (typeof location !== 'undefined' ? location.host : 'Nosskey');\n const rpId = options.rp?.id;\n const userName = options.user?.name || 'user@example.com';\n const userDisplayName = options.user?.displayName || 'Nosskey user';\n\n const credentialCreationOptions: CredentialCreationOptions = {\n publicKey: {\n rp: {\n name: rpName,\n id: rpId,\n },\n user: {\n id: crypto.getRandomValues(new Uint8Array(16)),\n name: userName,\n displayName: userDisplayName,\n },\n pubKeyCredParams: options.pubKeyCredParams || [{ type: 'public-key', alg: -7 }], // ES256\n authenticatorSelection: options.authenticatorSelection || {\n residentKey: 'required',\n userVerification: 'required',\n },\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n extensions: options.extensions || { prf: {} }, // PRF拡張を要求\n } as PublicKeyCredentialCreationOptions,\n };\n const cred = (await navigator.credentials.create(\n credentialCreationOptions\n )) as PublicKeyCredential;\n\n return new Uint8Array(cred.rawId);\n}\n\n/**\n * ID\n * @param credentialId \n * @param options PRF(rpId、timeout、userVerification)\n * @returns PRF credentialID\n */\nexport async function getPrfSecret(\n credentialId?: Uint8Array,\n options?: GetPrfSecretOptions\n): Promise<{ secret: Uint8Array; id: Uint8Array }> {\n const allowCredentials = credentialId ? [{ type: 'public-key' as const, id: credentialId }] : [];\n\n const requestOptions: PublicKeyCredentialRequestOptions = {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials,\n userVerification: options?.userVerification || 'required',\n extensions: {\n prf: { eval: { first: PRF_EVAL_INPUT } },\n } as AuthenticationExtensionsClientInputs,\n };\n\n if (options?.rpId) {\n requestOptions.rpId = options.rpId;\n }\n if (options?.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await navigator.credentials.get({\n publicKey: requestOptions,\n });\n\n if (!response) {\n throw new Error('Authentication failed');\n }\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const secret = assertion.getClientExtensionResults()?.prf?.results?.first;\n if (!secret) {\n throw new Error('PRF secret not available');\n }\n\n // response credentialId\n const responseId = new Uint8Array((response as PublicKeyCredential).rawId);\n\n return {\n secret: new Uint8Array(secret),\n id: responseId,\n };\n}\n","/**\n * PRF support check with a password-protected-key fallback.\n * If the PRF WebAuthn extension is unavailable, callers can fall back to a\n * password-protected private key. The private key is wrapped with a password-\n * derived AES-GCM key and stored alongside the public key (SPKI).\n *\n * This is a minimal, browser-oriented implementation designed to provide a\n * practical alternative while keeping crypto surface area focused and safe.\n */\n\nimport { getPublicKey } from 'applesauce-core/helpers';\n\nexport type PasswordProtectedBundle = {\n publicKeySpkiBase64: string;\n wrappedPrivateKeyBase64: string;\n saltBase64: string;\n ivBase64: string;\n};\n\nfunction toBase64(bytes: ArrayBuffer): string {\n const arr = new Uint8Array(bytes);\n let binary = '';\n for (let i = 0; i < arr.byteLength; i++) binary += String.fromCharCode(arr[i]);\n if (typeof window !== 'undefined' && (window as any).btoa) {\n return (window as any).btoa(binary);\n }\n return Buffer.from(binary, 'binary').toString('base64');\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n if (typeof window !== 'undefined' && (window as any).atob) {\n const bin = (window as any).atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\nexport async function checkPRFSupport(): Promise<boolean> {\n try {\n const caps = typeof PublicKeyCredential !== 'undefined' ? await PublicKeyCredential.getClientCapabilities() : null;\n const supported = caps?.['extension:prf'] === true;\n if (supported) {\n console.log('PRF extension is supported.');\n } else {\n console.log('PRF extension is not supported.');\n }\n return !!supported;\n } catch (e) {\n console.log('Could not determine PRF support:', e);\n return false;\n }\n}\n\nexport async function generatePasswordProtectedKey(password: string): Promise<PasswordProtectedBundle> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const kp = await cryptoObj.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const publicKey = kp.publicKey;\n const privateKey = kp.privateKey;\n\n const spki = await cryptoObj.subtle.exportKey('spki', publicKey);\n const publicKeySpkiBase64 = toBase64(spki);\n\n const privateKeyJwk = await cryptoObj.subtle.exportKey('jwk', privateKey);\n const jwkStr = JSON.stringify(privateKeyJwk);\n\n const salt = cryptoObj.getRandomValues(new Uint8Array(16));\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt']\n );\n const iv = cryptoObj.getRandomValues(new Uint8Array(12));\n const enc = new TextEncoder().encode(jwkStr);\n const ct = await cryptoObj.subtle.encrypt({ name: 'AES-GCM', iv }, aesKey, enc);\n\n return {\n publicKeySpkiBase64,\n wrappedPrivateKeyBase64: toBase64(ct),\n saltBase64: toBase64(salt.buffer),\n ivBase64: toBase64(iv.buffer),\n };\n}\n\nexport async function unwrapPasswordProtectedPrivateKey(bundle: PasswordProtectedBundle, password: string): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const salt = fromBase64(bundle.saltBase64);\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n );\n const iv = fromBase64(bundle.ivBase64);\n const ct = fromBase64(bundle.wrappedPrivateKeyBase64);\n const jwkBytes = await cryptoObj.subtle.decrypt({ name: 'AES-GCM', iv: iv.slice() }, aesKey, ct.slice());\n const jwkStr = new TextDecoder().decode(jwkBytes);\n const privateKeyJwk = JSON.parse(jwkStr);\n const privateKey = await cryptoObj.subtle.importKey('jwk', privateKeyJwk, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const d = (privateKeyJwk as any).d as string;\n if (!d) throw new Error('Missing private scalar in JWK');\n const sk = base64UrlToBytes(d);\n return sk;\n}\n\nfunction base64UrlToBytes(base64url: string): Uint8Array {\n let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = base64.length % 4;\n if (pad) base64 += '='.repeat(4 - pad);\n if (typeof window !== 'undefined' && (window as any).atob) {\n const binary = (window as any).atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(base64, 'base64'));\n}\n\nexport async function importPublicKeyFromBundle(bundle: PasswordProtectedBundle) {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n const spki = fromBase64(bundle.publicKeySpkiBase64);\n const publicKey = await cryptoObj.subtle.importKey('spki', spki, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify']);\n return publicKey;\n}\n\nconst DEFAULT_SALT = 'nostr-key-derivation';\n\nexport async function deriveNostrPrivateKey(password: string, salt: string = DEFAULT_SALT): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const encoder = new TextEncoder();\n const passwordKey = await cryptoObj.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n );\n\n const derivedBits = await cryptoObj.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt: encoder.encode(salt),\n iterations: 100000,\n hash: 'SHA-256',\n },\n passwordKey,\n 256\n );\n\n return new Uint8Array(derivedBits);\n}\n\nexport async function getPublicKeyFromPassword(password: string, salt: string = DEFAULT_SALT): Promise<string> {\n const sk = await deriveNostrPrivateKey(password, salt);\n return getPublicKey(sk);\n}\n","import { finalizeEvent, getPublicKey } from 'applesauce-core/helpers';\nimport * as secp256k1 from '@noble/secp256k1';\nimport { KeyCache } from './key-cache.js';\nimport { createPasskey, getPrfSecret, isPrfSupported } from './prf-handler.js';\nimport { checkPRFSupport, deriveNostrPrivateKey, getPublicKeyFromPassword, unwrapPasswordProtectedPrivateKey } from './prf-password-fallback.js';\nimport type {\n GetPrfSecretOptions,\n KeyCacheOptions,\n KeyOptions,\n NosskeyManagerLike,\n KeyManagerOptions,\n Event,\n KeyInfo,\n NostrKeyStorageOptions,\n PasskeyCreationOptions,\n SignOptions,\n} from './types.js';\n/**\n * Nosskey class for Passkey-Derived Nostr Identity\n * @packageDocumentation\n */\nimport { bytesToHex, hexToBytes } from './utils.js';\nimport type { KeyRecovery } from './types.js';\n\nexport async function deriveSaltFromUsername(username?: string): Promise<string> {\n if (!username) {\n return '';\n }\n \n const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\nexport function parseRecoveryTag(tags: string[][]): KeyRecovery | null {\n const recoveryTag = tags.find(tag => tag[0] === 'r');\n if (!recoveryTag || recoveryTag.length < 3) return null;\n\n // Format: ['r', recoveryPubkey, recoverySalt, createdAt, signature]\n const createdAt = recoveryTag[3] ? parseInt(recoveryTag[3], 10) : undefined;\n return {\n recoveryPubkey: recoveryTag[1],\n recoverySalt: recoveryTag[2],\n createdAt: createdAt || undefined,\n signature: recoveryTag[4] || undefined,\n };\n}\n\nexport function createRecoveryTag(recovery: KeyRecovery): string[] {\n return [\n 'r',\n recovery.recoveryPubkey,\n recovery.recoverySalt,\n recovery.createdAt?.toString() || '',\n recovery.signature || '',\n ];\n}\n\nexport function getRecoverySignature(kind0: Event): string | null {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return null;\n \n const tag = kind0.tags?.find(t => t[0] === 'r');\n return tag && tag.length > 4 ? tag[4] || null : null;\n}\n\nexport async function verifyRecoverySignature(kind0: Event): Promise<boolean> {\n try {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return false;\n \n const signature = getRecoverySignature(kind0);\n if (!signature || !kind0.pubkey) return false;\n \n // Verify Schnorr signature: signature over current pubkey (as message)\n // using the recovery pubkey\n // Note: verify expects the message hash, not the message itself\n const messageHash = await sha256(kind0.pubkey);\n const signatureBytes = hexToBytes(signature);\n const pubkeyBytes = hexToBytes(kind0.pubkey);\n \n return secp256k1.verify(signatureBytes, messageHash, pubkeyBytes);\n } catch (e) {\n return false;\n }\n}\n\nasync function sha256(message: string): Promise<Uint8Array> {\n const msgBuffer = new TextEncoder().encode(message);\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Nosskey - Passkey-Derived Nostr Keys\n */\nexport class NosskeyManager implements NosskeyManagerLike {\n #keyCache: KeyCache;\n\n // KeyInfo\n #currentKeyInfo: KeyInfo | null = null;\n\n // KeyInfo\n #storageOptions: NostrKeyStorageOptions = {\n enabled: true,\n storageKey: 'nosskey_keyinfo',\n };\n\n // PRF\n #prfOptions: GetPrfSecretOptions = {};\n\n /**\n * NosskeyManager\n * @param options\n */\n constructor(options?: KeyManagerOptions) {\n // KeyCache\n this.#keyCache = new KeyCache(options?.cacheOptions);\n\n if (options?.storageOptions) {\n this.#storageOptions = { ...this.#storageOptions, ...options.storageOptions };\n }\n\n // option\n const userVerification = options?.prfOptions?.userVerification ?? 'required';\n if (options?.prfOptions) {\n this.#prfOptions = { ...options.prfOptions, userVerification };\n } else {\n this.#prfOptions = { userVerification };\n }\n\n // KeyInfo\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n }\n }\n }\n\n /**\n * KeyInfo\n * @param options\n */\n setStorageOptions(options: Partial<NostrKeyStorageOptions>): void {\n this.#storageOptions = { ...this.#storageOptions, ...options };\n\n if (options.enabled === false) {\n this.clearStoredKeyInfo();\n }\n }\n\n /**\n * KeyInfo\n */\n getStorageOptions(): NostrKeyStorageOptions {\n return { ...this.#storageOptions };\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n this.#currentKeyInfo = keyInfo;\n\n if (this.#storageOptions.enabled) {\n void this.#saveKeyInfoToStorage(keyInfo);\n }\n }\n\n /**\n * KeyInfo\n */\n getCurrentKeyInfo(): KeyInfo | null {\n // KeyInfo\n if (!this.#currentKeyInfo && this.#storageOptions.enabled) {\n this.#currentKeyInfo = this.#loadKeyInfoFromStorage();\n }\n return this.#currentKeyInfo;\n }\n\n /**\n * KeyInfo\n * @returns KeyInfo\n */\n hasKeyInfo(): boolean {\n if (this.#currentKeyInfo) {\n return true;\n }\n\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n async #saveKeyInfoToStorage(keyInfo: KeyInfo): Promise<void> {\n if (!this.#storageOptions.enabled) return;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.setItem(key, JSON.stringify(keyInfo));\n }\n\n /**\n * KeyInfo\n */\n #loadKeyInfoFromStorage(): KeyInfo | null {\n if (!this.#storageOptions.enabled) return null;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return null;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n const data = storage.getItem(key);\n\n if (!data) return null;\n\n try {\n return JSON.parse(data) as KeyInfo;\n } catch (e) {\n console.error('Failed to parse stored KeyInfo', e);\n return null;\n }\n }\n\n /**\n * KeyInfo\n */\n clearStoredKeyInfo(): void {\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.removeItem(key);\n\n // KeyInfo\n this.#currentKeyInfo = null;\n }\n\n /**\n * NIP-07\n * KeyInfo\n */\n async getPublicKey(): Promise<string> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return keyInfo.pubkey;\n }\n\n /**\n * NIP-07\n * KeyInfo\n * @param event Nostr\n */\n async signEvent(event: Event): Promise<Event> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return this.signEventWithKeyInfo(event, keyInfo);\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n this.#keyCache.setCacheOptions(options);\n }\n\n getCacheOptions(): KeyCacheOptions {\n return this.#keyCache.getCacheOptions();\n }\n\n getCachedSecretKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n return this.#keyCache.getKey(credentialId);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n this.#keyCache.clearCachedKey(credentialId);\n }\n\n clearAllCachedKeys(): void {\n this.#keyCache.clearAllCachedKeys();\n }\n\n /**\n * @param options\n * @returns Credential\n */\n async createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n return createPasskey({\n rp: {\n id: this.#prfOptions.rpId,\n name: this.#prfOptions.rpId,\n },\n authenticatorSelection: {\n userVerification: this.#prfOptions.userVerification,\n },\n ...options,\n });\n }\n\n/**\n * Check if PRF is supported\n */\n async checkPRFSupport(): Promise<boolean> {\n return checkPRFSupport();\n }\n\n /**\n * Create Nostr key - automatically uses password fallback if PRF unavailable\n * @param credentialId Passkey credential ID\n * @param password Password for encryption (required if PRF not supported)\n * @param options \n */\n async createKey(credentialId?: Uint8Array, password?: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const prfSupported = await this.checkPRFSupport();\n \n let keyInfo: KeyInfo;\n \n if (prfSupported) {\n keyInfo = await this.createPrfNostrKey(credentialId, options);\n \n // Auto-add password recovery if requested and PRF is supported\n if (options.recoveryPassword) {\n keyInfo = await this.addPasswordRecovery(options.recoveryPassword, credentialId);\n }\n } else {\n if (!password) {\n throw new Error('Password is required when PRF is not supported');\n }\n if (!options.username) {\n throw new Error('Username is required when PRF is not supported');\n }\n keyInfo = await this.createPasswordProtectedNostrKey(password, options);\n }\n \n return keyInfo;\n }\n\n /**\n * Create Nostr key using PRF (standard passkey flow)\n */\n async createPrfNostrKey(credentialId?: Uint8Array, options: KeyOptions = {}): Promise<KeyInfo> {\n const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);\n\n if (sk.every((byte) => byte === 0)) {\n throw new Error('Invalid PRF output: all zeros');\n }\n\n const skHex = bytesToHex(sk);\n const publicKey = getPublicKey(sk);\n \n const salt = await deriveSaltFromUsername(options.username);\n\n const keyInfo: KeyInfo = {\n credentialId: bytesToHex(credentialId || responseId),\n pubkey: publicKey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n if (this.#keyCache.isEnabled() && this.#keyCache.getCacheOptions().cacheOnCreation) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n\n return keyInfo;\n }\n\n /**\n * Create Nostr key using password-derived key (fallback when PRF unavailable)\n * @param password Password to derive the private key\n * @param options \n */\n async createPasswordProtectedNostrKey(password: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const salt = await deriveSaltFromUsername(options.username);\n const pubkey = await getPublicKeyFromPassword(password, salt);\n\n const credentialId = bytesToHex((typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto).getRandomValues(new Uint8Array(16)));\n\n const keyInfo: KeyInfo = {\n credentialId,\n pubkey: pubkey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n return keyInfo;\n }\n\n/**\n * @param event Nostr\n * @param keyInfo KeyInfo\n * @param options\n */\n async signEventWithKeyInfo(\n event: Event,\n keyInfo: KeyInfo,\n options: SignOptions = {}\n ): Promise<Event> {\n const { clearMemory = true, tags, password } = options;\n\n const shouldUseCache = this.#keyCache.isEnabled();\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n\n let sk: Uint8Array | undefined;\n\n if (isPasswordDerived) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await deriveNostrPrivateKey(password, keyInfo.salt);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password to sign.');\n }\n } else if (keyInfo.passwordProtectedBundle) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle!, password);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password or use createNostrKey to initialize.');\n }\n } else {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n\n if (!sk) {\n const { secret: prfSecret } = await getPrfSecret(\n hexToBytes(keyInfo.credentialId),\n this.#prfOptions\n );\n sk = prfSecret;\n\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n }\n\n const eventToSign = {\n kind: event.kind,\n content: event.content,\n created_at: event.created_at || Math.floor(Date.now() / 1000),\n tags: tags ? [...(event.tags || []), ...tags] : event.tags || [],\n };\n\n const signedEvent = finalizeEvent(eventToSign, sk);\n\n if (!shouldUseCache && clearMemory) {\n this.#clearKey(sk);\n }\n\n return signedEvent;\n }\n\n/**\n * @param keyInfo KeyInfo\n * @param credentialId KeyInfoのcredentialId\n * @param options\n * @returns \n */\n async exportNostrKey(keyInfo: KeyInfo, credentialId?: Uint8Array, options: KeyOptions = {}): Promise<string> {\n if (keyInfo.passwordProtectedBundle) {\n if (!options.password) {\n throw new Error('Password is required for password-protected keys');\n }\n const sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle, options.password);\n return bytesToHex(sk);\n }\n\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n if (isPasswordDerived) {\n if (!options.password) {\n throw new Error('Password is required for password-derived keys');\n }\n const sk = await deriveNostrPrivateKey(options.password, keyInfo.salt);\n return bytesToHex(sk);\n }\n\n let usedCredentialId = credentialId;\n\n if (!usedCredentialId && keyInfo.credentialId) {\n usedCredentialId = hexToBytes(keyInfo.credentialId);\n }\n\n const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);\n const skHex = bytesToHex(sk);\n\n return skHex;\n }\n\n /**\n * PRF\n */\n async isPrfSupported(): Promise<boolean> {\n return isPrfSupported();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n * @param currentCredentialId Current passkey credential ID\n */\n async addPasswordRecovery(password: string, currentCredentialId?: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (keyInfo.passwordProtectedBundle) {\n throw new Error('Password recovery already exists for password-derived key');\n }\n\n if (keyInfo.recovery) {\n throw new Error('Recovery already configured');\n }\n\n const usedCredentialId = currentCredentialId || (keyInfo.credentialId ? hexToBytes(keyInfo.credentialId) : undefined);\n if (!usedCredentialId) {\n throw new Error('Credential ID required');\n }\n\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n\n // Generate recovery salt\n const recoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n\n // Derive recovery pubkey from password\n const recoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n\n // Sign current pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, keyInfo.pubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n ...keyInfo,\n recovery: {\n recoveryPubkey,\n recoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n #signWithKey(sk: Uint8Array, message: string): string {\n const event = finalizeEvent({\n kind: 0,\n content: '',\n tags: [],\n created_at: Math.floor(Date.now() / 1000),\n }, sk);\n return event.sig;\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (!keyInfo.recovery) {\n throw new Error('No recovery key configured');\n }\n\n if (!newCredentialId) {\n throw new Error('New credential ID is required for recovery');\n }\n\n const { recoveryPubkey, recoverySalt } = keyInfo.recovery;\n\n // Verify password\n const derivedRecoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n if (derivedRecoveryPubkey !== recoveryPubkey) {\n throw new Error('Invalid recovery password');\n }\n\n // Derive new key from new credential\n const { secret: newSk } = await getPrfSecret(newCredentialId, this.#prfOptions);\n const newPubkey = getPublicKey(newSk);\n this.#clearKey(newSk);\n\n // Generate new recovery for the new key\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n const newRecoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n const newRecoveryPubkey = await getPublicKeyFromPassword(password, newRecoverySalt);\n\n // Sign new pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, newPubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n credentialId: bytesToHex(newCredentialId),\n pubkey: newPubkey,\n salt: keyInfo.salt,\n recovery: {\n recoveryPubkey: newRecoveryPubkey,\n recoverySalt: newRecoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n /**\n * Get the recovery data for publishing to kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number; signature?: string } | null {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo || !keyInfo.recovery) return null;\n\n return {\n recoveryPubkey: keyInfo.recovery.recoveryPubkey,\n recoverySalt: keyInfo.recovery.recoverySalt,\n createdAt: keyInfo.recovery.createdAt,\n signature: keyInfo.recovery.signature,\n };\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * Cryptographic utilities for Nosskey\n * @packageDocumentation\n */\n\nconst INFO_BYTES = new TextEncoder().encode('nostr-pwk');\nconst AES_LENGTH = 256; // bits\n\n/**\n * PRF AES-GCM\n * @param secret PRF\n * @param salt\n * @returns AES-GCM\n */\nexport async function deriveAesGcmKey(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {\n const keyMaterial = await crypto.subtle.importKey('raw', secret, 'HKDF', false, ['deriveKey']);\n\n return crypto.subtle.deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt, info: INFO_BYTES },\n keyMaterial,\n { name: 'AES-GCM', length: AES_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param plaintext\n * @returns\n */\nexport async function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array) {\n const buf = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);\n\n const bytes = new Uint8Array(buf);\n return {\n ciphertext: bytes.slice(0, -16),\n tag: bytes.slice(-16),\n };\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param ct\n * @param tag\n * @returns\n */\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n iv: Uint8Array,\n ct: Uint8Array,\n tag: Uint8Array\n): Promise<Uint8Array> {\n const buf = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n new Uint8Array([...ct, ...tag])\n );\n return new Uint8Array(buf);\n}\n","/**\n * Test utilities for sdk\n * @packageDocumentation\n */\n\n/**\n * Helper for testing/debugging\n * @param userId - User identifier\n * @returns Promise resolving to the dummy credential\n */\nexport async function registerDummyPasskey(userId: string): Promise<PublicKeyCredential> {\n // Create a dummy credential for testing\n const dummySignature = new Uint8Array(64);\n // Fill with some non-zero values for testing\n for (let i = 0; i < dummySignature.length; i++) {\n dummySignature[i] = (i + 1) % 256;\n }\n\n const dummyId = new Uint8Array(32);\n for (let i = 0; i < dummyId.length; i++) {\n dummyId[i] = (i + 1) % 256;\n }\n\n const credential = {\n id: 'dummy-credential-id',\n rawId: dummyId,\n type: 'public-key',\n response: {\n clientDataJSON: new Uint8Array(0),\n attestationObject: new Uint8Array(0),\n signature: dummySignature,\n authenticatorData: new Uint8Array(0),\n getAuthenticatorData: () => new Uint8Array(0),\n getPublicKey: () => new Uint8Array(0),\n getPublicKeyAlgorithm: () => -7,\n getTransports: () => ['internal'],\n },\n } as unknown as PublicKeyCredential;\n\n return credential;\n}\n","import { NosskeyManager, type KeyInfo, type Event, type PasskeyCreationOptions, type SignOptions, type KeyOptions } from '../utils';\nimport type { AuthServiceConfig } from '../types/auth';\n\n/**\n * Service wrapper around NosskeyManager\n * Handles WebAuthn/Passkey integration with Nostr\n */\nexport class AuthService {\n private manager: NosskeyManager | null = null;\n private config: AuthServiceConfig;\n\n constructor(config: AuthServiceConfig = {}) {\n this.config = {\n rpId: config.rpId || (typeof window !== 'undefined' ? window.location.hostname.replace(/^www\\./, '') : 'localhost'),\n rpName: config.rpName || this.getDefaultRpName(),\n storageKey: config.storageKey || 'nsauth_keyinfo',\n cacheTimeoutMs: config.cacheTimeoutMs || 30 * 60 * 1000,\n cacheOnCreation: config.cacheOnCreation !== undefined ? config.cacheOnCreation : true,\n };\n }\n\n private getDefaultRpName(): string {\n if (typeof window === 'undefined') return 'localhost';\n const hostname = window.location.hostname;\n if (hostname.includes('nosskey.app')) return 'nosskey.app';\n return hostname.replace(/^www\\./, '');\n }\n\n /**\n * Initialize the NosskeyManager instance\n */\n private getManager(): NosskeyManager {\n if (!this.manager) {\n this.manager = new NosskeyManager({\n cacheOptions: {\n enabled: true,\n timeoutMs: this.config.cacheTimeoutMs,\n cacheOnCreation: this.config.cacheOnCreation,\n },\n storageOptions: {\n enabled: true,\n storageKey: this.config.storageKey,\n },\n });\n }\n return this.manager;\n }\n\n /**\n * Create a new passkey\n * Uses platform authenticator only (Touch ID, Face ID, Windows Hello)\n */\n async createPasskey(username?: string): Promise<Uint8Array> {\n const manager = this.getManager();\n \n const rpId = this.config.rpId === 'localhost' ? 'localhost' : this.config.rpId;\n const rpName = this.config.rpName;\n \n const trimmedUsername = username?.trim();\n const uniqueUsername = trimmedUsername \n ? trimmedUsername \n : `user-${Date.now()}@example.com`;\n \n const options: PasskeyCreationOptions = {\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n name: uniqueUsername,\n displayName: trimmedUsername || 'User',\n },\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n residentKey: 'preferred',\n userVerification: 'preferred',\n },\n extensions: {\n prf: {},\n },\n };\n \n return await manager.createPasskey(options);\n }\n\n/**\n * Create a new Nostr key from a credential ID\n * Automatically uses password fallback if PRF is not supported\n * @param credentialId Passkey credential ID\n * @param password Password (required if PRF not supported)\n * @param options.username Username for the key\n * @param options.recoveryPassword Password for recovery (enables recovery on new device)\n */\n async createKey(credentialId?: Uint8Array, password?: string, options?: KeyOptions): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.createKey(credentialId, password, options);\n }\n\n /**\n * Check if PRF is supported, otherwise password fallback is needed\n */\n async checkPRFSupport(): Promise<boolean> {\n const manager = this.getManager();\n return await manager.checkPRFSupport();\n }\n\n /**\n * Get the current public key\n */\n async getPublicKey(): Promise<string> {\n const manager = this.getManager();\n return await manager.getPublicKey();\n }\n\n /**\n * Sign a Nostr event\n */\n async signEvent(event: Event, options?: SignOptions): Promise<Event> {\n const manager = this.getManager();\n return await manager.signEvent(event, options);\n }\n\n /**\n * Get current key info\n */\n getCurrentKeyInfo(): KeyInfo | null {\n const manager = this.getManager();\n return manager.getCurrentKeyInfo();\n }\n\n /**\n * Set current key info\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n const manager = this.getManager();\n manager.setCurrentKeyInfo(keyInfo);\n }\n\n /**\n * Check if key info exists\n */\n hasKeyInfo(): boolean {\n const manager = this.getManager();\n return manager.hasKeyInfo();\n }\n\n /**\n * Clear stored key info\n */\n clearStoredKeyInfo(): void {\n const manager = this.getManager();\n manager.clearStoredKeyInfo();\n }\n\n/**\n * Check if PRF is supported (legacy alias)\n */\n async isPrfSupported(): Promise<boolean> {\n return this.checkPRFSupport();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n */\n async addPasswordRecovery(password: string): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.addPasswordRecovery(password);\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.activateWithPassword(password, newCredentialId);\n }\n\n /**\n * Get recovery data for kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number } | null {\n const manager = this.getManager();\n return manager.getRecoveryForKind0();\n }\n}\n\n","export const MAX_ROLE_LENGTH = 100;\nconst ROLE_PATTERN = /^[a-zA-Z0-9\\s\\-_]+$/;\n\nexport const isValidRoleTag = (role: string): boolean => {\n const trimmed = role.trim();\n return (\n trimmed.length > 0 &&\n trimmed.length <= MAX_ROLE_LENGTH &&\n ROLE_PATTERN.test(trimmed)\n );\n};\n\nexport const isValidPubkey = (pubkey: string): boolean =>\n pubkey.length === 64 && /^[0-9a-fA-F]+$/.test(pubkey);\n\nexport const isValidHttpUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n};\n\nexport const isValidRelayUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['ws:', 'wss:'].includes(parsed.protocol) && parsed.hostname.length > 0;\n } catch {\n return false;\n }\n};\n","import type { EventStore } from 'applesauce-core';\nimport type { Event } from '../types/nostr';\nimport type { ProfileMetadata, FollowEntry } from '../types/nostr';\nimport type { RelayServiceConfig } from '../types/auth';\nimport { isValidPubkey, isValidRelayUrl, isValidRoleTag } from '../utils/validation';\n\n/**\n * Service for communicating with Nostr relays using applesauce-core\n */\nexport class RelayService {\n private eventStore: EventStore | null = null;\n private relayUrls: string[];\n private defaultRelays = ['wss://relay.damus.io'];\n private readonly maxProfileContentSize = 10000;\n private readonly minProfileQueryIntervalMs = 300;\n private readonly minPublishIntervalMs = 750;\n private readonly lastActionAt = new Map<string, number>();\n\n constructor(config: RelayServiceConfig = {}) {\n this.relayUrls = this.validateRelayUrls(config.relayUrls ?? this.defaultRelays);\n }\n\n /**\n * Initialize with applesauce EventStore\n */\n initialize(eventStore: EventStore): void {\n this.eventStore = eventStore;\n // Set default relays if EventStore has a method for it\n if (eventStore && 'setRelays' in eventStore && typeof eventStore.setRelays === 'function') {\n (eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Set relay URLs\n */\n setRelays(urls: string[]): void {\n this.relayUrls = this.validateRelayUrls(urls);\n if (this.eventStore && 'setRelays' in this.eventStore && typeof this.eventStore.setRelays === 'function') {\n (this.eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Get current relay URLs\n */\n getRelays(): string[] {\n return [...this.relayUrls];\n }\n\n /**\n * Publish an event to relays\n */\n async publishEvent(event: Event, timeoutMs = 1000): Promise<boolean> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('publish', this.minPublishIntervalMs);\n return new Promise((resolve, reject) => {\n if (this.relayUrls.length === 0) {\n reject(new Error('No relays configured'));\n return;\n }\n\n // Use EventStore's publish method\n // Note: This is a simplified implementation - actual applesauce API may differ\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.publish !== 'function') {\n reject(new Error('EventStore does not support publish method'));\n return;\n }\n const subscription = eventStore.publish(event).subscribe({\n next: (response: any) => {\n if (response?.type === 'OK') {\n subscription.unsubscribe();\n resolve(true);\n }\n },\n error: (error: Error) => {\n subscription.unsubscribe();\n reject(error);\n },\n });\n\n // Timeout fallback\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(false);\n }, timeoutMs);\n });\n }\n\n /**\n * Fetch a profile (Kind 0 event)\n */\n async fetchProfile(pubkey: string): Promise<ProfileMetadata | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-profile', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n subscription.unsubscribe();\n resolve(metadata);\n return;\n }\n console.error('Failed to parse profile metadata');\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n // Timeout\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch role tag from profile event (Kind 0)\n */\n async fetchProfileRoleTag(pubkey: string): Promise<string | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-role-tag', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const tags = packet.event.tags || [];\n for (const tag of tags) {\n if (tag[0] === 'role' && tag[1]) {\n const candidate = tag[1].trim();\n if (isValidRoleTag(candidate)) {\n subscription.unsubscribe();\n resolve(candidate);\n return;\n }\n }\n }\n subscription.unsubscribe();\n resolve(null);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile role tag:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch a follow list (Kind 3 event)\n */\n async fetchFollowList(pubkey: string): Promise<FollowEntry[]> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-follow-list', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [3],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve([]);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 3) {\n const followList: FollowEntry[] = [];\n const tags = packet.event.tags || [];\n\n for (const tag of tags) {\n if (tag[0] === 'p' && tag[1]) {\n followList.push({\n pubkey: tag[1],\n relay: tag[2] || undefined,\n petname: tag[3] || undefined,\n });\n }\n }\n\n subscription.unsubscribe();\n resolve(followList);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve([]);\n },\n error: (error: Error) => {\n console.error('Error fetching follow list:', error);\n subscription.unsubscribe();\n resolve([]);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve([]);\n }, 10000);\n });\n }\n\n /**\n * Fetch multiple profiles in batch\n */\n async fetchMultipleProfiles(pubkeys: string[]): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n if (pubkeys.length === 0) {\n return new Map();\n }\n\n await this.enforceRateLimit('fetch-multiple-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, ProfileMetadata>();\n const filter = {\n kinds: [0],\n authors: pubkeys,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n profiles.set(packet.event.pubkey, metadata);\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(profiles);\n },\n error: (error: Error) => {\n console.error('Error fetching profiles:', error);\n subscription.unsubscribe();\n resolve(profiles);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(profiles);\n }, 1000);\n });\n }\n\n /**\n * Query kind 0 events (profiles) by pubkey\n * If pubkeys array is empty, fetches recent kind 0 events\n */\n async queryProfiles(pubkeys: string[] = [], limit = 100): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('query-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, { metadata: ProfileMetadata; timestamp: number }>();\n const filter: any = {\n kinds: [0],\n limit,\n };\n\n if (pubkeys.length > 0) {\n filter.authors = pubkeys;\n }\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n const timestamp = packet.event.created_at || 0;\n const existing = profiles.get(packet.event.pubkey);\n if (!existing || timestamp > existing.timestamp) {\n profiles.set(packet.event.pubkey, { metadata, timestamp });\n }\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n error: (error: Error) => {\n console.error('Error querying profiles:', error);\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n }, 10000);\n });\n }\n\n /**\n * Publish or update a kind 3 event (follow list/contacts)\n */\n async publishFollowList(\n pubkey: string,\n followList: FollowEntry[],\n signEvent: (event: Event) => Promise<Event>\n ): Promise<boolean> {\n const tags: string[][] = followList.map((entry) => {\n if (!isValidPubkey(entry.pubkey)) {\n throw new Error('Invalid pubkey format for follow list entry.');\n }\n if (entry.relay && !isValidRelayUrl(entry.relay)) {\n throw new Error('Invalid relay URL format for follow list entry.');\n }\n const tag: string[] = ['p', entry.pubkey];\n if (entry.relay) {\n tag.push(entry.relay);\n }\n if (entry.petname) {\n tag.push(entry.petname);\n }\n return tag;\n });\n\n const event: Event = {\n kind: 3,\n content: '',\n created_at: Math.floor(Date.now() / 1000),\n tags,\n };\n\n const signedEvent = await signEvent(event);\n return await this.publishEvent(signedEvent);\n }\n\n private validateRelayUrls(urls: string[]): string[] {\n if (urls.length === 0) {\n return [];\n }\n const validUrls = urls.filter((url) => isValidRelayUrl(url));\n if (validUrls.length !== urls.length) {\n throw new Error('Invalid relay URL format');\n }\n return validUrls;\n }\n\n private parseProfileMetadata(content: string): ProfileMetadata | null {\n if (content.length > this.maxProfileContentSize) {\n return null;\n }\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n const metadata: ProfileMetadata = {};\n if (typeof (parsed as ProfileMetadata).name === 'string') {\n metadata.name = (parsed as ProfileMetadata).name;\n }\n if (typeof (parsed as ProfileMetadata).display_name === 'string') {\n metadata.display_name = (parsed as ProfileMetadata).display_name;\n }\n if (typeof (parsed as ProfileMetadata).about === 'string') {\n metadata.about = (parsed as ProfileMetadata).about;\n }\n if (typeof (parsed as ProfileMetadata).picture === 'string') {\n metadata.picture = (parsed as ProfileMetadata).picture;\n }\n if (typeof (parsed as ProfileMetadata).website === 'string') {\n metadata.website = (parsed as ProfileMetadata).website;\n }\n return metadata;\n } catch (error) {\n console.error('Failed to parse profile metadata:', error);\n return null;\n }\n }\n\n private async enforceRateLimit(action: string, minIntervalMs: number): Promise<void> {\n const lastAt = this.lastActionAt.get(action) ?? 0;\n const now = Date.now();\n const waitMs = minIntervalMs - (now - lastAt);\n if (waitMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, waitMs));\n }\n this.lastActionAt.set(action, Date.now());\n }\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["#cacheOptions","#cachedEntry","#clearCachedEntry","#scheduleExpiry","#getCachedKeyIfValid","#clearKey","#expiryTimer","secp256k1","#keyCache","#storageOptions","#prfOptions","#loadKeyInfoFromStorage","#currentKeyInfo","#saveKeyInfoToStorage","#clearKey","#signWithKey"],"sources":["../src/utils/utils.ts","../src/utils/key-cache.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/nosskey.ts","../src/utils/crypto-utils.ts","../src/utils/test-utils.ts","../src/services/auth.service.ts","../src/utils/validation.ts","../src/services/relay.service.ts"],"sourcesContent":["/**\n * @packageDocumentation\n */\n\n/**\n * @param bytes\n * @returns\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n const key = '0123456789abcdef';\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n const firstNibble = bytes[i] >> 4;\n const secondNibble = bytes[i] & 15;\n hex += key[firstNibble] + key[secondNibble];\n }\n return hex;\n}\n\n/**\n * @param hex\n * @returns\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const key = '0123456789abcdef';\n const bytes = [];\n let currentByte = 0;\n let highNibble = true;\n\n for (let i = 0; i < hex.length; i++) {\n const charValue = key.indexOf(hex[i].toLowerCase());\n if (charValue === -1) continue;\n\n if (highNibble) {\n currentByte = charValue << 4;\n highNibble = false;\n } else {\n currentByte += charValue;\n bytes.push(currentByte);\n highNibble = true;\n }\n }\n\n return new Uint8Array(bytes);\n}\n","/**\n * Key cache management for Nosskey\n * @packageDocumentation\n */\n\nimport type { KeyCacheOptions } from './types.js';\nimport { bytesToHex } from './utils.js';\n\n/**\n * Key cache entry with expiration time\n */\ninterface CacheEntry {\n id: string;\n sk: Uint8Array;\n expireAt: number;\n}\n\n/**\n * Key cache manager for managing temporary secret keys\n */\nexport class KeyCache {\n #cachedEntry: CacheEntry | null = null;\n\n #expiryTimer: NodeJS.Timeout | null = null;\n\n #cacheOptions: KeyCacheOptions = {\n enabled: false,\n timeoutMs: 5 * 60 * 1000,\n };\n\n /**\n * KeyCache\n * @param options\n */\n constructor(options?: Partial<KeyCacheOptions>) {\n if (options) {\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n if (Object.keys(options).length > 0 && this.#cachedEntry !== null) {\n this.clearAllCachedKeys();\n }\n\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n\n getCacheOptions(): KeyCacheOptions {\n return { ...this.#cacheOptions };\n }\n\n isEnabled(): boolean {\n return this.#cacheOptions.enabled;\n }\n\n /**\n * @param credentialId\n * @param sk\n */\n setKey(credentialId: Uint8Array | string, sk: Uint8Array): void {\n if (!this.#cacheOptions.enabled) return;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n const timeout =\n this.#cacheOptions.timeoutMs !== undefined ? this.#cacheOptions.timeoutMs : 5 * 60 * 1000;\n const expireAt = Date.now() + timeout;\n\n this.#clearCachedEntry();\n\n this.#cachedEntry = {\n id,\n sk: new Uint8Array(sk),\n expireAt,\n };\n\n try {\n this.#scheduleExpiry();\n } catch (error) {\n this.#clearCachedEntry();\n throw error;\n }\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n getKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n if (!this.#cacheOptions.enabled) return undefined;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n return this.#getCachedKeyIfValid(id);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n\n if (this.#cachedEntry && this.#cachedEntry.id === id) {\n this.#clearCachedEntry();\n }\n }\n\n clearAllCachedKeys(): void {\n this.#clearCachedEntry();\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n #getCachedKeyIfValid(credentialId: string): Uint8Array | undefined {\n if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) {\n return undefined;\n }\n\n if (Date.now() < this.#cachedEntry.expireAt) {\n return this.#cachedEntry.sk;\n }\n\n this.#clearCachedEntry();\n return undefined;\n }\n\n #clearCachedEntry(): void {\n if (this.#cachedEntry) {\n this.#clearKey(this.#cachedEntry.sk);\n this.#cachedEntry = null;\n }\n\n if (this.#expiryTimer) {\n clearTimeout(this.#expiryTimer);\n this.#expiryTimer = null;\n }\n }\n\n #scheduleExpiry(): void {\n if (!this.#cachedEntry) return;\n\n const now = Date.now();\n const timeToExpiry = this.#cachedEntry.expireAt - now;\n\n if (timeToExpiry <= 0) {\n this.#clearCachedEntry();\n return;\n }\n\n this.#expiryTimer = setTimeout(() => {\n this.#clearCachedEntry();\n }, timeToExpiry + 1);\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * PRF (Pseudo-Random Function) handler for WebAuthn\n * @packageDocumentation\n */\n\nimport type { GetPrfSecretOptions, PasskeyCreationOptions } from './types.js';\n\nconst PRF_EVAL_INPUT = new TextEncoder().encode('nostr-pwk');\n\n/**\n * @returns PRF\n */\nexport async function isPrfSupported(): Promise<boolean> {\n try {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) {\n return false;\n }\n\n const response = await navigator.credentials.get({\n publicKey: {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials: [],\n userVerification: 'required',\n extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } },\n } as PublicKeyCredentialRequestOptions,\n });\n\n if (!response) return false;\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const res = assertion.getClientExtensionResults()?.prf?.results?.first;\n return !!res;\n } catch {\n return false;\n }\n}\n\n/**\n * @param options\n * @returns Credential\n */\nexport async function createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n // Node\n const rpName = options.rp?.name || (typeof location !== 'undefined' ? location.host : 'Nosskey');\n const rpId = options.rp?.id;\n const userName = options.user?.name || 'user@example.com';\n const userDisplayName = options.user?.displayName || 'Nosskey user';\n\n const credentialCreationOptions: CredentialCreationOptions = {\n publicKey: {\n rp: {\n name: rpName,\n id: rpId,\n },\n user: {\n id: crypto.getRandomValues(new Uint8Array(16)),\n name: userName,\n displayName: userDisplayName,\n },\n pubKeyCredParams: options.pubKeyCredParams || [{ type: 'public-key', alg: -7 }], // ES256\n authenticatorSelection: options.authenticatorSelection || {\n residentKey: 'required',\n userVerification: 'required',\n },\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n extensions: options.extensions || { prf: {} }, // PRF拡張を要求\n } as PublicKeyCredentialCreationOptions,\n };\n const cred = (await navigator.credentials.create(\n credentialCreationOptions\n )) as PublicKeyCredential;\n\n return new Uint8Array(cred.rawId);\n}\n\n/**\n * ID\n * @param credentialId \n * @param options PRF(rpId、timeout、userVerification)\n * @returns PRF credentialID\n */\nexport async function getPrfSecret(\n credentialId?: Uint8Array,\n options?: GetPrfSecretOptions\n): Promise<{ secret: Uint8Array; id: Uint8Array }> {\n const allowCredentials = credentialId ? [{ type: 'public-key' as const, id: credentialId }] : [];\n\n const requestOptions: PublicKeyCredentialRequestOptions = {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials,\n userVerification: options?.userVerification || 'required',\n extensions: {\n prf: { eval: { first: PRF_EVAL_INPUT } },\n } as AuthenticationExtensionsClientInputs,\n };\n\n if (options?.rpId) {\n requestOptions.rpId = options.rpId;\n }\n if (options?.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await navigator.credentials.get({\n publicKey: requestOptions,\n });\n\n if (!response) {\n throw new Error('Authentication failed');\n }\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const secret = assertion.getClientExtensionResults()?.prf?.results?.first;\n if (!secret) {\n throw new Error('PRF secret not available');\n }\n\n // response credentialId\n const responseId = new Uint8Array((response as PublicKeyCredential).rawId);\n\n return {\n secret: new Uint8Array(secret),\n id: responseId,\n };\n}\n","/**\n * PRF support check with a password-protected-key fallback.\n * If the PRF WebAuthn extension is unavailable, callers can fall back to a\n * password-protected private key. The private key is wrapped with a password-\n * derived AES-GCM key and stored alongside the public key (SPKI).\n *\n * This is a minimal, browser-oriented implementation designed to provide a\n * practical alternative while keeping crypto surface area focused and safe.\n */\n\nimport { getPublicKey } from 'applesauce-core/helpers';\n\nexport type PasswordProtectedBundle = {\n publicKeySpkiBase64: string;\n wrappedPrivateKeyBase64: string;\n saltBase64: string;\n ivBase64: string;\n};\n\nfunction toBase64(bytes: ArrayBuffer): string {\n const arr = new Uint8Array(bytes);\n let binary = '';\n for (let i = 0; i < arr.byteLength; i++) binary += String.fromCharCode(arr[i]);\n if (typeof window !== 'undefined' && (window as any).btoa) {\n return (window as any).btoa(binary);\n }\n return Buffer.from(binary, 'binary').toString('base64');\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n if (typeof window !== 'undefined' && (window as any).atob) {\n const bin = (window as any).atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\nexport async function checkPRFSupport(): Promise<boolean> {\n try {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) {\n console.log('Web Crypto API not available, falling back to password-protected key');\n return false;\n }\n\n const caps = typeof PublicKeyCredential !== 'undefined' ? await PublicKeyCredential.getClientCapabilities() : null;\n const supported = caps?.['extension:prf'] === true;\n if (supported) {\n console.log('PRF extension is supported.');\n } else {\n console.log('PRF extension is not supported.');\n }\n return !!supported;\n } catch (e) {\n console.log('Could not determine PRF support:', e);\n return false;\n }\n}\n\nexport async function generatePasswordProtectedKey(password: string): Promise<PasswordProtectedBundle> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const kp = await cryptoObj.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const publicKey = kp.publicKey;\n const privateKey = kp.privateKey;\n\n const spki = await cryptoObj.subtle.exportKey('spki', publicKey);\n const publicKeySpkiBase64 = toBase64(spki);\n\n const privateKeyJwk = await cryptoObj.subtle.exportKey('jwk', privateKey);\n const jwkStr = JSON.stringify(privateKeyJwk);\n\n const salt = cryptoObj.getRandomValues(new Uint8Array(16));\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt']\n );\n const iv = cryptoObj.getRandomValues(new Uint8Array(12));\n const enc = new TextEncoder().encode(jwkStr);\n const ct = await cryptoObj.subtle.encrypt({ name: 'AES-GCM', iv }, aesKey, enc);\n\n return {\n publicKeySpkiBase64,\n wrappedPrivateKeyBase64: toBase64(ct),\n saltBase64: toBase64(salt.buffer),\n ivBase64: toBase64(iv.buffer),\n };\n}\n\nexport async function unwrapPasswordProtectedPrivateKey(bundle: PasswordProtectedBundle, password: string): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const salt = fromBase64(bundle.saltBase64);\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n );\n const iv = fromBase64(bundle.ivBase64);\n const ct = fromBase64(bundle.wrappedPrivateKeyBase64);\n const jwkBytes = await cryptoObj.subtle.decrypt({ name: 'AES-GCM', iv: iv.slice() }, aesKey, ct.slice());\n const jwkStr = new TextDecoder().decode(jwkBytes);\n const privateKeyJwk = JSON.parse(jwkStr);\n const privateKey = await cryptoObj.subtle.importKey('jwk', privateKeyJwk, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const d = (privateKeyJwk as any).d as string;\n if (!d) throw new Error('Missing private scalar in JWK');\n const sk = base64UrlToBytes(d);\n return sk;\n}\n\nfunction base64UrlToBytes(base64url: string): Uint8Array {\n let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = base64.length % 4;\n if (pad) base64 += '='.repeat(4 - pad);\n if (typeof window !== 'undefined' && (window as any).atob) {\n const binary = (window as any).atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(base64, 'base64'));\n}\n\nexport async function importPublicKeyFromBundle(bundle: PasswordProtectedBundle) {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n const spki = fromBase64(bundle.publicKeySpkiBase64);\n const publicKey = await cryptoObj.subtle.importKey('spki', spki, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify']);\n return publicKey;\n}\n\nconst DEFAULT_SALT = 'nostr-key-derivation';\n\nexport async function deriveNostrPrivateKey(password: string, salt: string = DEFAULT_SALT): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const encoder = new TextEncoder();\n const passwordKey = await cryptoObj.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n );\n\n const derivedBits = await cryptoObj.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt: encoder.encode(salt),\n iterations: 100000,\n hash: 'SHA-256',\n },\n passwordKey,\n 256\n );\n\n return new Uint8Array(derivedBits);\n}\n\nexport async function getPublicKeyFromPassword(password: string, salt: string = DEFAULT_SALT): Promise<string> {\n const sk = await deriveNostrPrivateKey(password, salt);\n return getPublicKey(sk);\n}\n","import { finalizeEvent, getPublicKey } from 'applesauce-core/helpers';\nimport * as secp256k1 from '@noble/secp256k1';\nimport { KeyCache } from './key-cache.js';\nimport { createPasskey, getPrfSecret, isPrfSupported } from './prf-handler.js';\nimport { checkPRFSupport, deriveNostrPrivateKey, getPublicKeyFromPassword, unwrapPasswordProtectedPrivateKey } from './prf-password-fallback.js';\nimport type {\n GetPrfSecretOptions,\n KeyCacheOptions,\n KeyOptions,\n NosskeyManagerLike,\n KeyManagerOptions,\n Event,\n KeyInfo,\n NostrKeyStorageOptions,\n PasskeyCreationOptions,\n SignOptions,\n} from './types.js';\n/**\n * Nosskey class for Passkey-Derived Nostr Identity\n * @packageDocumentation\n */\nimport { bytesToHex, hexToBytes } from './utils.js';\nimport type { KeyRecovery } from './types.js';\n\nexport async function deriveSaltFromUsername(username?: string): Promise<string> {\n if (!username) {\n return '';\n }\n \n const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n const hashBuffer = await subtle.digest('SHA-256', msgBuffer);\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\nexport function parseRecoveryTag(tags: string[][]): KeyRecovery | null {\n const recoveryTag = tags.find(tag => tag[0] === 'r');\n if (!recoveryTag || recoveryTag.length < 3) return null;\n\n // Format: ['r', recoveryPubkey, recoverySalt, createdAt, signature]\n const createdAt = recoveryTag[3] ? parseInt(recoveryTag[3], 10) : undefined;\n return {\n recoveryPubkey: recoveryTag[1],\n recoverySalt: recoveryTag[2],\n createdAt: createdAt || undefined,\n signature: recoveryTag[4] || undefined,\n };\n}\n\nexport function createRecoveryTag(recovery: KeyRecovery): string[] {\n return [\n 'r',\n recovery.recoveryPubkey,\n recovery.recoverySalt,\n recovery.createdAt?.toString() || '',\n recovery.signature || '',\n ];\n}\n\nexport function getRecoverySignature(kind0: Event): string | null {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return null;\n \n const tag = kind0.tags?.find(t => t[0] === 'r');\n return tag && tag.length > 4 ? tag[4] || null : null;\n}\n\nexport async function verifyRecoverySignature(kind0: Event): Promise<boolean> {\n try {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return false;\n \n const signature = getRecoverySignature(kind0);\n if (!signature || !kind0.pubkey) return false;\n \n // Verify Schnorr signature: signature over current pubkey (as message)\n // using the recovery pubkey\n // Note: verify expects the message hash, not the message itself\n const messageHash = await sha256(kind0.pubkey);\n const signatureBytes = hexToBytes(signature);\n const pubkeyBytes = hexToBytes(kind0.pubkey);\n \n return secp256k1.verify(signatureBytes, messageHash, pubkeyBytes);\n } catch (e) {\n return false;\n }\n}\n\nasync function sha256(message: string): Promise<Uint8Array> {\n const msgBuffer = new TextEncoder().encode(message);\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n const hashBuffer = await subtle.digest('SHA-256', msgBuffer);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Nosskey - Passkey-Derived Nostr Keys\n */\nexport class NosskeyManager implements NosskeyManagerLike {\n #keyCache: KeyCache;\n\n // KeyInfo\n #currentKeyInfo: KeyInfo | null = null;\n\n // KeyInfo\n #storageOptions: NostrKeyStorageOptions = {\n enabled: true,\n storageKey: 'nosskey_keyinfo',\n };\n\n // PRF\n #prfOptions: GetPrfSecretOptions = {};\n\n /**\n * NosskeyManager\n * @param options\n */\n constructor(options?: KeyManagerOptions) {\n // KeyCache\n this.#keyCache = new KeyCache(options?.cacheOptions);\n\n if (options?.storageOptions) {\n this.#storageOptions = { ...this.#storageOptions, ...options.storageOptions };\n }\n\n // option\n const userVerification = options?.prfOptions?.userVerification ?? 'required';\n if (options?.prfOptions) {\n this.#prfOptions = { ...options.prfOptions, userVerification };\n } else {\n this.#prfOptions = { userVerification };\n }\n\n // KeyInfo\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n }\n }\n }\n\n /**\n * KeyInfo\n * @param options\n */\n setStorageOptions(options: Partial<NostrKeyStorageOptions>): void {\n this.#storageOptions = { ...this.#storageOptions, ...options };\n\n if (options.enabled === false) {\n this.clearStoredKeyInfo();\n }\n }\n\n /**\n * KeyInfo\n */\n getStorageOptions(): NostrKeyStorageOptions {\n return { ...this.#storageOptions };\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n this.#currentKeyInfo = keyInfo;\n\n if (this.#storageOptions.enabled) {\n void this.#saveKeyInfoToStorage(keyInfo);\n }\n }\n\n /**\n * KeyInfo\n */\n getCurrentKeyInfo(): KeyInfo | null {\n // KeyInfo\n if (!this.#currentKeyInfo && this.#storageOptions.enabled) {\n this.#currentKeyInfo = this.#loadKeyInfoFromStorage();\n }\n return this.#currentKeyInfo;\n }\n\n /**\n * KeyInfo\n * @returns KeyInfo\n */\n hasKeyInfo(): boolean {\n if (this.#currentKeyInfo) {\n return true;\n }\n\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n async #saveKeyInfoToStorage(keyInfo: KeyInfo): Promise<void> {\n if (!this.#storageOptions.enabled) return;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.setItem(key, JSON.stringify(keyInfo));\n }\n\n /**\n * KeyInfo\n */\n #loadKeyInfoFromStorage(): KeyInfo | null {\n if (!this.#storageOptions.enabled) return null;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return null;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n const data = storage.getItem(key);\n\n if (!data) return null;\n\n try {\n return JSON.parse(data) as KeyInfo;\n } catch (e) {\n console.error('Failed to parse stored KeyInfo', e);\n return null;\n }\n }\n\n /**\n * KeyInfo\n */\n clearStoredKeyInfo(): void {\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.removeItem(key);\n\n // KeyInfo\n this.#currentKeyInfo = null;\n }\n\n /**\n * NIP-07\n * KeyInfo\n */\n async getPublicKey(): Promise<string> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return keyInfo.pubkey;\n }\n\n /**\n * NIP-07\n * KeyInfo\n * @param event Nostr\n */\n async signEvent(event: Event): Promise<Event> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return this.signEventWithKeyInfo(event, keyInfo);\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n this.#keyCache.setCacheOptions(options);\n }\n\n getCacheOptions(): KeyCacheOptions {\n return this.#keyCache.getCacheOptions();\n }\n\n getCachedSecretKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n return this.#keyCache.getKey(credentialId);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n this.#keyCache.clearCachedKey(credentialId);\n }\n\n clearAllCachedKeys(): void {\n this.#keyCache.clearAllCachedKeys();\n }\n\n /**\n * @param options\n * @returns Credential\n */\n async createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n return createPasskey({\n rp: {\n id: this.#prfOptions.rpId,\n name: this.#prfOptions.rpId,\n },\n authenticatorSelection: {\n userVerification: this.#prfOptions.userVerification,\n },\n ...options,\n });\n }\n\n/**\n * Check if PRF is supported\n */\n async checkPRFSupport(): Promise<boolean> {\n return checkPRFSupport();\n }\n\n /**\n * Create Nostr key - automatically uses password fallback if PRF unavailable\n * @param credentialId Passkey credential ID\n * @param password Password for encryption (required if PRF not supported)\n * @param options \n */\n async createKey(credentialId?: Uint8Array, password?: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const prfSupported = await this.checkPRFSupport();\n \n let keyInfo: KeyInfo;\n \n if (prfSupported) {\n keyInfo = await this.createPrfNostrKey(credentialId, options);\n \n // Auto-add password recovery if requested and PRF is supported\n if (options.recoveryPassword) {\n keyInfo = await this.addPasswordRecovery(options.recoveryPassword, credentialId);\n }\n } else {\n if (!password) {\n throw new Error('Password is required when PRF is not supported');\n }\n if (!options.username) {\n throw new Error('Username is required when PRF is not supported');\n }\n keyInfo = await this.createPasswordProtectedNostrKey(password, options);\n }\n \n return keyInfo;\n }\n\n /**\n * Create Nostr key using PRF (standard passkey flow)\n */\n async createPrfNostrKey(credentialId?: Uint8Array, options: KeyOptions = {}): Promise<KeyInfo> {\n const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);\n\n if (sk.every((byte) => byte === 0)) {\n throw new Error('Invalid PRF output: all zeros');\n }\n\n const skHex = bytesToHex(sk);\n const publicKey = getPublicKey(sk);\n \n const salt = await deriveSaltFromUsername(options.username);\n\n const keyInfo: KeyInfo = {\n credentialId: bytesToHex(credentialId || responseId),\n pubkey: publicKey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n if (this.#keyCache.isEnabled() && this.#keyCache.getCacheOptions().cacheOnCreation) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n\n return keyInfo;\n }\n\n /**\n * Create Nostr key using password-derived key (fallback when PRF unavailable)\n * @param password Password to derive the private key\n * @param options \n */\n async createPasswordProtectedNostrKey(password: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const salt = await deriveSaltFromUsername(options.username);\n const pubkey = await getPublicKeyFromPassword(password, salt);\n\n const credentialId = bytesToHex((typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto).getRandomValues(new Uint8Array(16)));\n\n const keyInfo: KeyInfo = {\n credentialId,\n pubkey: pubkey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n return keyInfo;\n }\n\n/**\n * @param event Nostr\n * @param keyInfo KeyInfo\n * @param options\n */\n async signEventWithKeyInfo(\n event: Event,\n keyInfo: KeyInfo,\n options: SignOptions = {}\n ): Promise<Event> {\n const { clearMemory = true, tags, password } = options;\n\n const shouldUseCache = this.#keyCache.isEnabled();\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n\n let sk: Uint8Array | undefined;\n\n if (isPasswordDerived) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await deriveNostrPrivateKey(password, keyInfo.salt);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password to sign.');\n }\n } else if (keyInfo.passwordProtectedBundle) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle!, password);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password or use createNostrKey to initialize.');\n }\n } else {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n\n if (!sk) {\n const { secret: prfSecret } = await getPrfSecret(\n hexToBytes(keyInfo.credentialId),\n this.#prfOptions\n );\n sk = prfSecret;\n\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n }\n\n const eventToSign = {\n kind: event.kind,\n content: event.content,\n created_at: event.created_at || Math.floor(Date.now() / 1000),\n tags: tags ? [...(event.tags || []), ...tags] : event.tags || [],\n };\n\n const signedEvent = finalizeEvent(eventToSign, sk);\n\n if (!shouldUseCache && clearMemory) {\n this.#clearKey(sk);\n }\n\n return signedEvent;\n }\n\n/**\n * @param keyInfo KeyInfo\n * @param credentialId KeyInfoのcredentialId\n * @param options\n * @returns \n */\n async exportNostrKey(keyInfo: KeyInfo, credentialId?: Uint8Array, options: KeyOptions = {}): Promise<string> {\n if (keyInfo.passwordProtectedBundle) {\n if (!options.password) {\n throw new Error('Password is required for password-protected keys');\n }\n const sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle, options.password);\n return bytesToHex(sk);\n }\n\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n if (isPasswordDerived) {\n if (!options.password) {\n throw new Error('Password is required for password-derived keys');\n }\n const sk = await deriveNostrPrivateKey(options.password, keyInfo.salt);\n return bytesToHex(sk);\n }\n\n let usedCredentialId = credentialId;\n\n if (!usedCredentialId && keyInfo.credentialId) {\n usedCredentialId = hexToBytes(keyInfo.credentialId);\n }\n\n const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);\n const skHex = bytesToHex(sk);\n\n return skHex;\n }\n\n /**\n * PRF\n */\n async isPrfSupported(): Promise<boolean> {\n return isPrfSupported();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n * @param currentCredentialId Current passkey credential ID\n */\n async addPasswordRecovery(password: string, currentCredentialId?: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (keyInfo.passwordProtectedBundle) {\n throw new Error('Password recovery already exists for password-derived key');\n }\n\n if (keyInfo.recovery) {\n throw new Error('Recovery already configured');\n }\n\n const usedCredentialId = currentCredentialId || (keyInfo.credentialId ? hexToBytes(keyInfo.credentialId) : undefined);\n if (!usedCredentialId) {\n throw new Error('Credential ID required');\n }\n\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n\n // Generate recovery salt\n const recoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n\n // Derive recovery pubkey from password\n const recoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n\n // Sign current pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, keyInfo.pubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n ...keyInfo,\n recovery: {\n recoveryPubkey,\n recoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n #signWithKey(sk: Uint8Array, message: string): string {\n const event = finalizeEvent({\n kind: 0,\n content: '',\n tags: [],\n created_at: Math.floor(Date.now() / 1000),\n }, sk);\n return event.sig;\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (!keyInfo.recovery) {\n throw new Error('No recovery key configured');\n }\n\n if (!newCredentialId) {\n throw new Error('New credential ID is required for recovery');\n }\n\n const { recoveryPubkey, recoverySalt } = keyInfo.recovery;\n\n // Verify password\n const derivedRecoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n if (derivedRecoveryPubkey !== recoveryPubkey) {\n throw new Error('Invalid recovery password');\n }\n\n // Derive new key from new credential\n const { secret: newSk } = await getPrfSecret(newCredentialId, this.#prfOptions);\n const newPubkey = getPublicKey(newSk);\n this.#clearKey(newSk);\n\n // Generate new recovery for the new key\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n const newRecoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n const newRecoveryPubkey = await getPublicKeyFromPassword(password, newRecoverySalt);\n\n // Sign new pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, newPubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n credentialId: bytesToHex(newCredentialId),\n pubkey: newPubkey,\n salt: keyInfo.salt,\n recovery: {\n recoveryPubkey: newRecoveryPubkey,\n recoverySalt: newRecoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n /**\n * Get the recovery data for publishing to kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number; signature?: string } | null {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo || !keyInfo.recovery) return null;\n\n return {\n recoveryPubkey: keyInfo.recovery.recoveryPubkey,\n recoverySalt: keyInfo.recovery.recoverySalt,\n createdAt: keyInfo.recovery.createdAt,\n signature: keyInfo.recovery.signature,\n };\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * Cryptographic utilities for Nosskey\n * @packageDocumentation\n */\n\nconst INFO_BYTES = new TextEncoder().encode('nostr-pwk');\nconst AES_LENGTH = 256; // bits\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n return subtle;\n}\n\n/**\n * PRF AES-GCM\n * @param secret PRF\n * @param salt\n * @returns AES-GCM\n */\nexport async function deriveAesGcmKey(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {\n const subtle = getSubtle();\n const keyMaterial = await subtle.importKey('raw', secret, 'HKDF', false, ['deriveKey']);\n\n return subtle.deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt, info: INFO_BYTES },\n keyMaterial,\n { name: 'AES-GCM', length: AES_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param plaintext\n * @returns\n */\nexport async function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array) {\n const subtle = getSubtle();\n const buf = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);\n\n const bytes = new Uint8Array(buf);\n return {\n ciphertext: bytes.slice(0, -16),\n tag: bytes.slice(-16),\n };\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param ct\n * @param tag\n * @returns\n */\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n iv: Uint8Array,\n ct: Uint8Array,\n tag: Uint8Array\n): Promise<Uint8Array> {\n const subtle = getSubtle();\n const buf = await subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n new Uint8Array([...ct, ...tag])\n );\n return new Uint8Array(buf);\n}\n","/**\n * Test utilities for sdk\n * @packageDocumentation\n */\n\n/**\n * Helper for testing/debugging\n * @param userId - User identifier\n * @returns Promise resolving to the dummy credential\n */\nexport async function registerDummyPasskey(userId: string): Promise<PublicKeyCredential> {\n // Create a dummy credential for testing\n const dummySignature = new Uint8Array(64);\n // Fill with some non-zero values for testing\n for (let i = 0; i < dummySignature.length; i++) {\n dummySignature[i] = (i + 1) % 256;\n }\n\n const dummyId = new Uint8Array(32);\n for (let i = 0; i < dummyId.length; i++) {\n dummyId[i] = (i + 1) % 256;\n }\n\n const credential = {\n id: 'dummy-credential-id',\n rawId: dummyId,\n type: 'public-key',\n response: {\n clientDataJSON: new Uint8Array(0),\n attestationObject: new Uint8Array(0),\n signature: dummySignature,\n authenticatorData: new Uint8Array(0),\n getAuthenticatorData: () => new Uint8Array(0),\n getPublicKey: () => new Uint8Array(0),\n getPublicKeyAlgorithm: () => -7,\n getTransports: () => ['internal'],\n },\n } as unknown as PublicKeyCredential;\n\n return credential;\n}\n","import { NosskeyManager, type KeyInfo, type Event, type PasskeyCreationOptions, type SignOptions, type KeyOptions } from '../utils';\nimport type { AuthServiceConfig } from '../types/auth';\n\n/**\n * Service wrapper around NosskeyManager\n * Handles WebAuthn/Passkey integration with Nostr\n */\nexport class AuthService {\n private manager: NosskeyManager | null = null;\n private config: AuthServiceConfig;\n\n constructor(config: AuthServiceConfig = {}) {\n this.config = {\n rpId: config.rpId || (typeof window !== 'undefined' ? window.location.hostname.replace(/^www\\./, '') : 'localhost'),\n rpName: config.rpName || this.getDefaultRpName(),\n storageKey: config.storageKey || 'nsauth_keyinfo',\n cacheTimeoutMs: config.cacheTimeoutMs || 30 * 60 * 1000,\n cacheOnCreation: config.cacheOnCreation !== undefined ? config.cacheOnCreation : true,\n };\n }\n\n private getDefaultRpName(): string {\n if (typeof window === 'undefined') return 'localhost';\n const hostname = window.location.hostname;\n if (hostname.includes('nosskey.app')) return 'nosskey.app';\n return hostname.replace(/^www\\./, '');\n }\n\n /**\n * Initialize the NosskeyManager instance\n */\n private getManager(): NosskeyManager {\n if (!this.manager) {\n this.manager = new NosskeyManager({\n cacheOptions: {\n enabled: true,\n timeoutMs: this.config.cacheTimeoutMs,\n cacheOnCreation: this.config.cacheOnCreation,\n },\n storageOptions: {\n enabled: true,\n storageKey: this.config.storageKey,\n },\n });\n }\n return this.manager;\n }\n\n /**\n * Create a new passkey\n * Uses platform authenticator only (Touch ID, Face ID, Windows Hello)\n */\n async createPasskey(username?: string): Promise<Uint8Array> {\n const manager = this.getManager();\n \n const rpId = this.config.rpId === 'localhost' ? 'localhost' : this.config.rpId;\n const rpName = this.config.rpName;\n \n const trimmedUsername = username?.trim();\n const uniqueUsername = trimmedUsername \n ? trimmedUsername \n : `user-${Date.now()}@example.com`;\n \n const options: PasskeyCreationOptions = {\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n name: uniqueUsername,\n displayName: trimmedUsername || 'User',\n },\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n residentKey: 'preferred',\n userVerification: 'preferred',\n },\n extensions: {\n prf: {},\n },\n };\n \n return await manager.createPasskey(options);\n }\n\n/**\n * Create a new Nostr key from a credential ID\n * Automatically uses password fallback if PRF is not supported\n * @param credentialId Passkey credential ID\n * @param password Password (required if PRF not supported)\n * @param options.username Username for the key\n * @param options.recoveryPassword Password for recovery (enables recovery on new device)\n */\n async createKey(credentialId?: Uint8Array, password?: string, options?: KeyOptions): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.createKey(credentialId, password, options);\n }\n\n /**\n * Check if PRF is supported, otherwise password fallback is needed\n */\n async checkPRFSupport(): Promise<boolean> {\n const manager = this.getManager();\n return await manager.checkPRFSupport();\n }\n\n /**\n * Get the current public key\n */\n async getPublicKey(): Promise<string> {\n const manager = this.getManager();\n return await manager.getPublicKey();\n }\n\n /**\n * Sign a Nostr event\n */\n async signEvent(event: Event, options?: SignOptions): Promise<Event> {\n const manager = this.getManager();\n return await manager.signEvent(event, options);\n }\n\n /**\n * Get current key info\n */\n getCurrentKeyInfo(): KeyInfo | null {\n const manager = this.getManager();\n return manager.getCurrentKeyInfo();\n }\n\n /**\n * Set current key info\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n const manager = this.getManager();\n manager.setCurrentKeyInfo(keyInfo);\n }\n\n /**\n * Check if key info exists\n */\n hasKeyInfo(): boolean {\n const manager = this.getManager();\n return manager.hasKeyInfo();\n }\n\n /**\n * Clear stored key info\n */\n clearStoredKeyInfo(): void {\n const manager = this.getManager();\n manager.clearStoredKeyInfo();\n }\n\n/**\n * Check if PRF is supported (legacy alias)\n */\n async isPrfSupported(): Promise<boolean> {\n return this.checkPRFSupport();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n */\n async addPasswordRecovery(password: string): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.addPasswordRecovery(password);\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.activateWithPassword(password, newCredentialId);\n }\n\n /**\n * Get recovery data for kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number } | null {\n const manager = this.getManager();\n return manager.getRecoveryForKind0();\n }\n}\n\n","export const MAX_ROLE_LENGTH = 100;\nconst ROLE_PATTERN = /^[a-zA-Z0-9\\s\\-_]+$/;\n\nexport const isValidRoleTag = (role: string): boolean => {\n const trimmed = role.trim();\n return (\n trimmed.length > 0 &&\n trimmed.length <= MAX_ROLE_LENGTH &&\n ROLE_PATTERN.test(trimmed)\n );\n};\n\nexport const isValidPubkey = (pubkey: string): boolean =>\n pubkey.length === 64 && /^[0-9a-fA-F]+$/.test(pubkey);\n\nexport const isValidHttpUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n};\n\nexport const isValidRelayUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['ws:', 'wss:'].includes(parsed.protocol) && parsed.hostname.length > 0;\n } catch {\n return false;\n }\n};\n","import type { EventStore } from 'applesauce-core';\nimport type { Event } from '../types/nostr';\nimport type { ProfileMetadata, FollowEntry } from '../types/nostr';\nimport type { RelayServiceConfig } from '../types/auth';\nimport { isValidPubkey, isValidRelayUrl, isValidRoleTag } from '../utils/validation';\n\n/**\n * Service for communicating with Nostr relays using applesauce-core\n */\nexport class RelayService {\n private eventStore: EventStore | null = null;\n private relayUrls: string[];\n private defaultRelays = ['wss://relay.damus.io'];\n private readonly maxProfileContentSize = 10000;\n private readonly minProfileQueryIntervalMs = 300;\n private readonly minPublishIntervalMs = 750;\n private readonly lastActionAt = new Map<string, number>();\n\n constructor(config: RelayServiceConfig = {}) {\n this.relayUrls = this.validateRelayUrls(config.relayUrls ?? this.defaultRelays);\n }\n\n /**\n * Initialize with applesauce EventStore\n */\n initialize(eventStore: EventStore): void {\n this.eventStore = eventStore;\n // Set default relays if EventStore has a method for it\n if (eventStore && 'setRelays' in eventStore && typeof eventStore.setRelays === 'function') {\n (eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Set relay URLs\n */\n setRelays(urls: string[]): void {\n this.relayUrls = this.validateRelayUrls(urls);\n if (this.eventStore && 'setRelays' in this.eventStore && typeof this.eventStore.setRelays === 'function') {\n (this.eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Get current relay URLs\n */\n getRelays(): string[] {\n return [...this.relayUrls];\n }\n\n /**\n * Publish an event to relays\n */\n async publishEvent(event: Event, timeoutMs = 1000): Promise<boolean> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('publish', this.minPublishIntervalMs);\n return new Promise((resolve, reject) => {\n if (this.relayUrls.length === 0) {\n reject(new Error('No relays configured'));\n return;\n }\n\n // Use EventStore's publish method\n // Note: This is a simplified implementation - actual applesauce API may differ\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.publish !== 'function') {\n reject(new Error('EventStore does not support publish method'));\n return;\n }\n const subscription = eventStore.publish(event).subscribe({\n next: (response: any) => {\n if (response?.type === 'OK') {\n subscription.unsubscribe();\n resolve(true);\n }\n },\n error: (error: Error) => {\n subscription.unsubscribe();\n reject(error);\n },\n });\n\n // Timeout fallback\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(false);\n }, timeoutMs);\n });\n }\n\n /**\n * Fetch a profile (Kind 0 event)\n */\n async fetchProfile(pubkey: string): Promise<ProfileMetadata | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-profile', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n subscription.unsubscribe();\n resolve(metadata);\n return;\n }\n console.error('Failed to parse profile metadata');\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n // Timeout\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch role tag from profile event (Kind 0)\n */\n async fetchProfileRoleTag(pubkey: string): Promise<string | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-role-tag', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const tags = packet.event.tags || [];\n for (const tag of tags) {\n if (tag[0] === 'role' && tag[1]) {\n const candidate = tag[1].trim();\n if (isValidRoleTag(candidate)) {\n subscription.unsubscribe();\n resolve(candidate);\n return;\n }\n }\n }\n subscription.unsubscribe();\n resolve(null);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile role tag:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch a follow list (Kind 3 event)\n */\n async fetchFollowList(pubkey: string): Promise<FollowEntry[]> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-follow-list', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [3],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve([]);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 3) {\n const followList: FollowEntry[] = [];\n const tags = packet.event.tags || [];\n\n for (const tag of tags) {\n if (tag[0] === 'p' && tag[1]) {\n followList.push({\n pubkey: tag[1],\n relay: tag[2] || undefined,\n petname: tag[3] || undefined,\n });\n }\n }\n\n subscription.unsubscribe();\n resolve(followList);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve([]);\n },\n error: (error: Error) => {\n console.error('Error fetching follow list:', error);\n subscription.unsubscribe();\n resolve([]);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve([]);\n }, 10000);\n });\n }\n\n /**\n * Fetch multiple profiles in batch\n */\n async fetchMultipleProfiles(pubkeys: string[]): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n if (pubkeys.length === 0) {\n return new Map();\n }\n\n await this.enforceRateLimit('fetch-multiple-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, ProfileMetadata>();\n const filter = {\n kinds: [0],\n authors: pubkeys,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n profiles.set(packet.event.pubkey, metadata);\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(profiles);\n },\n error: (error: Error) => {\n console.error('Error fetching profiles:', error);\n subscription.unsubscribe();\n resolve(profiles);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(profiles);\n }, 1000);\n });\n }\n\n /**\n * Query kind 0 events (profiles) by pubkey\n * If pubkeys array is empty, fetches recent kind 0 events\n */\n async queryProfiles(pubkeys: string[] = [], limit = 100): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('query-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, { metadata: ProfileMetadata; timestamp: number }>();\n const filter: any = {\n kinds: [0],\n limit,\n };\n\n if (pubkeys.length > 0) {\n filter.authors = pubkeys;\n }\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n const timestamp = packet.event.created_at || 0;\n const existing = profiles.get(packet.event.pubkey);\n if (!existing || timestamp > existing.timestamp) {\n profiles.set(packet.event.pubkey, { metadata, timestamp });\n }\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n error: (error: Error) => {\n console.error('Error querying profiles:', error);\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n }, 10000);\n });\n }\n\n /**\n * Publish or update a kind 3 event (follow list/contacts)\n */\n async publishFollowList(\n pubkey: string,\n followList: FollowEntry[],\n signEvent: (event: Event) => Promise<Event>\n ): Promise<boolean> {\n const tags: string[][] = followList.map((entry) => {\n if (!isValidPubkey(entry.pubkey)) {\n throw new Error('Invalid pubkey format for follow list entry.');\n }\n if (entry.relay && !isValidRelayUrl(entry.relay)) {\n throw new Error('Invalid relay URL format for follow list entry.');\n }\n const tag: string[] = ['p', entry.pubkey];\n if (entry.relay) {\n tag.push(entry.relay);\n }\n if (entry.petname) {\n tag.push(entry.petname);\n }\n return tag;\n });\n\n const event: Event = {\n kind: 3,\n content: '',\n created_at: Math.floor(Date.now() / 1000),\n tags,\n };\n\n const signedEvent = await signEvent(event);\n return await this.publishEvent(signedEvent);\n }\n\n private validateRelayUrls(urls: string[]): string[] {\n if (urls.length === 0) {\n return [];\n }\n const validUrls = urls.filter((url) => isValidRelayUrl(url));\n if (validUrls.length !== urls.length) {\n throw new Error('Invalid relay URL format');\n }\n return validUrls;\n }\n\n private parseProfileMetadata(content: string): ProfileMetadata | null {\n if (content.length > this.maxProfileContentSize) {\n return null;\n }\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n const metadata: ProfileMetadata = {};\n if (typeof (parsed as ProfileMetadata).name === 'string') {\n metadata.name = (parsed as ProfileMetadata).name;\n }\n if (typeof (parsed as ProfileMetadata).display_name === 'string') {\n metadata.display_name = (parsed as ProfileMetadata).display_name;\n }\n if (typeof (parsed as ProfileMetadata).about === 'string') {\n metadata.about = (parsed as ProfileMetadata).about;\n }\n if (typeof (parsed as ProfileMetadata).picture === 'string') {\n metadata.picture = (parsed as ProfileMetadata).picture;\n }\n if (typeof (parsed as ProfileMetadata).website === 'string') {\n metadata.website = (parsed as ProfileMetadata).website;\n }\n return metadata;\n } catch (error) {\n console.error('Failed to parse profile metadata:', error);\n return null;\n }\n }\n\n private async enforceRateLimit(action: string, minIntervalMs: number): Promise<void> {\n const lastAt = this.lastActionAt.get(action) ?? 0;\n const now = Date.now();\n const waitMs = minIntervalMs - (now - lastAt);\n if (waitMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, waitMs));\n }\n this.lastActionAt.set(action, Date.now());\n }\n}\n\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/utils/types.ts","../src/utils/nosskey.ts","../src/utils/utils.ts","../src/utils/crypto-utils.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/test-utils.ts","../src/types/auth.ts","../src/services/auth.service.ts","../src/types/nostr.ts","../src/services/relay.service.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/utils/types.ts","../src/utils/nosskey.ts","../src/utils/utils.ts","../src/utils/crypto-utils.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/test-utils.ts","../src/types/auth.ts","../src/services/auth.service.ts","../src/types/nostr.ts","../src/services/relay.service.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils/types.ts","../src/utils/nosskey.ts","../src/utils/utils.ts","../src/utils/crypto-utils.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/test-utils.ts","../src/types/auth.ts","../src/services/auth.service.ts","../src/types/nostr.ts","../src/services/relay.service.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils/types.ts","../src/utils/nosskey.ts","../src/utils/utils.ts","../src/utils/crypto-utils.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/test-utils.ts","../src/types/auth.ts","../src/services/auth.service.ts","../src/types/nostr.ts","../src/services/relay.service.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -171,6 +171,8 @@ const PRF_EVAL_INPUT = new TextEncoder().encode("nostr-pwk");
171
171
  */
172
172
  async function isPrfSupported() {
173
173
  try {
174
+ const cryptoObj = typeof window !== "undefined" && window.crypto || globalThis.crypto;
175
+ if (!cryptoObj || !cryptoObj.subtle) return false;
174
176
  const response = await navigator.credentials.get({ publicKey: {
175
177
  challenge: crypto.getRandomValues(new Uint8Array(32)),
176
178
  allowCredentials: [],
@@ -275,6 +277,11 @@ function fromBase64(b64) {
275
277
  }
276
278
  async function checkPRFSupport() {
277
279
  try {
280
+ const cryptoObj = typeof window !== "undefined" && window.crypto || globalThis.crypto;
281
+ if (!cryptoObj || !cryptoObj.subtle) {
282
+ console.log("Web Crypto API not available, falling back to password-protected key");
283
+ return false;
284
+ }
278
285
  const supported = (typeof PublicKeyCredential !== "undefined" ? await PublicKeyCredential.getClientCapabilities() : null)?.["extension:prf"] === true;
279
286
  if (supported) console.log("PRF extension is supported.");
280
287
  else console.log("PRF extension is not supported.");
@@ -397,7 +404,9 @@ async function getPublicKeyFromPassword(password, salt = DEFAULT_SALT) {
397
404
  async function deriveSaltFromUsername(username) {
398
405
  if (!username) return "";
399
406
  const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());
400
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
407
+ const subtle = globalThis.crypto?.subtle;
408
+ if (!subtle) throw new Error("Web Crypto API not available");
409
+ const hashBuffer = await subtle.digest("SHA-256", msgBuffer);
401
410
  return bytesToHex(new Uint8Array(hashBuffer));
402
411
  }
403
412
  function parseRecoveryTag(tags) {
@@ -440,7 +449,9 @@ async function verifyRecoverySignature(kind0) {
440
449
  }
441
450
  async function sha256(message) {
442
451
  const msgBuffer = new TextEncoder().encode(message);
443
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
452
+ const subtle = globalThis.crypto?.subtle;
453
+ if (!subtle) throw new Error("Web Crypto API not available");
454
+ const hashBuffer = await subtle.digest("SHA-256", msgBuffer);
444
455
  return new Uint8Array(hashBuffer);
445
456
  }
446
457
  /**
@@ -839,6 +850,11 @@ var NosskeyManager = class {
839
850
  */
840
851
  const INFO_BYTES = new TextEncoder().encode("nostr-pwk");
841
852
  const AES_LENGTH = 256;
853
+ function getSubtle() {
854
+ const subtle = globalThis.crypto?.subtle;
855
+ if (!subtle) throw new Error("Web Crypto API not available");
856
+ return subtle;
857
+ }
842
858
  /**
843
859
  * PRF AES-GCM
844
860
  * @param secret PRF
@@ -846,8 +862,9 @@ const AES_LENGTH = 256;
846
862
  * @returns AES-GCM
847
863
  */
848
864
  async function deriveAesGcmKey(secret, salt) {
849
- const keyMaterial = await crypto.subtle.importKey("raw", secret, "HKDF", false, ["deriveKey"]);
850
- return crypto.subtle.deriveKey({
865
+ const subtle = getSubtle();
866
+ const keyMaterial = await subtle.importKey("raw", secret, "HKDF", false, ["deriveKey"]);
867
+ return subtle.deriveKey({
851
868
  name: "HKDF",
852
869
  hash: "SHA-256",
853
870
  salt,
@@ -865,7 +882,7 @@ async function deriveAesGcmKey(secret, salt) {
865
882
  * @returns
866
883
  */
867
884
  async function aesGcmEncrypt(key, iv, plaintext) {
868
- const buf = await crypto.subtle.encrypt({
885
+ const buf = await getSubtle().encrypt({
869
886
  name: "AES-GCM",
870
887
  iv
871
888
  }, key, plaintext);
@@ -884,7 +901,7 @@ async function aesGcmEncrypt(key, iv, plaintext) {
884
901
  * @returns
885
902
  */
886
903
  async function aesGcmDecrypt(key, iv, ct, tag) {
887
- const buf = await crypto.subtle.decrypt({
904
+ const buf = await getSubtle().decrypt({
888
905
  name: "AES-GCM",
889
906
  iv
890
907
  }, key, new Uint8Array([...ct, ...tag]));
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["#cacheOptions","#cachedEntry","#clearCachedEntry","#scheduleExpiry","#getCachedKeyIfValid","#clearKey","#expiryTimer","#keyCache","#storageOptions","#prfOptions","#loadKeyInfoFromStorage","#currentKeyInfo","#saveKeyInfoToStorage","#clearKey","#signWithKey"],"sources":["../src/utils/utils.ts","../src/utils/key-cache.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/nosskey.ts","../src/utils/crypto-utils.ts","../src/utils/test-utils.ts","../src/services/auth.service.ts","../src/utils/validation.ts","../src/services/relay.service.ts"],"sourcesContent":["/**\n * @packageDocumentation\n */\n\n/**\n * @param bytes\n * @returns\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n const key = '0123456789abcdef';\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n const firstNibble = bytes[i] >> 4;\n const secondNibble = bytes[i] & 15;\n hex += key[firstNibble] + key[secondNibble];\n }\n return hex;\n}\n\n/**\n * @param hex\n * @returns\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const key = '0123456789abcdef';\n const bytes = [];\n let currentByte = 0;\n let highNibble = true;\n\n for (let i = 0; i < hex.length; i++) {\n const charValue = key.indexOf(hex[i].toLowerCase());\n if (charValue === -1) continue;\n\n if (highNibble) {\n currentByte = charValue << 4;\n highNibble = false;\n } else {\n currentByte += charValue;\n bytes.push(currentByte);\n highNibble = true;\n }\n }\n\n return new Uint8Array(bytes);\n}\n","/**\n * Key cache management for Nosskey\n * @packageDocumentation\n */\n\nimport type { KeyCacheOptions } from './types.js';\nimport { bytesToHex } from './utils.js';\n\n/**\n * Key cache entry with expiration time\n */\ninterface CacheEntry {\n id: string;\n sk: Uint8Array;\n expireAt: number;\n}\n\n/**\n * Key cache manager for managing temporary secret keys\n */\nexport class KeyCache {\n #cachedEntry: CacheEntry | null = null;\n\n #expiryTimer: NodeJS.Timeout | null = null;\n\n #cacheOptions: KeyCacheOptions = {\n enabled: false,\n timeoutMs: 5 * 60 * 1000,\n };\n\n /**\n * KeyCache\n * @param options\n */\n constructor(options?: Partial<KeyCacheOptions>) {\n if (options) {\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n if (Object.keys(options).length > 0 && this.#cachedEntry !== null) {\n this.clearAllCachedKeys();\n }\n\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n\n getCacheOptions(): KeyCacheOptions {\n return { ...this.#cacheOptions };\n }\n\n isEnabled(): boolean {\n return this.#cacheOptions.enabled;\n }\n\n /**\n * @param credentialId\n * @param sk\n */\n setKey(credentialId: Uint8Array | string, sk: Uint8Array): void {\n if (!this.#cacheOptions.enabled) return;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n const timeout =\n this.#cacheOptions.timeoutMs !== undefined ? this.#cacheOptions.timeoutMs : 5 * 60 * 1000;\n const expireAt = Date.now() + timeout;\n\n this.#clearCachedEntry();\n\n this.#cachedEntry = {\n id,\n sk: new Uint8Array(sk),\n expireAt,\n };\n\n try {\n this.#scheduleExpiry();\n } catch (error) {\n this.#clearCachedEntry();\n throw error;\n }\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n getKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n if (!this.#cacheOptions.enabled) return undefined;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n return this.#getCachedKeyIfValid(id);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n\n if (this.#cachedEntry && this.#cachedEntry.id === id) {\n this.#clearCachedEntry();\n }\n }\n\n clearAllCachedKeys(): void {\n this.#clearCachedEntry();\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n #getCachedKeyIfValid(credentialId: string): Uint8Array | undefined {\n if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) {\n return undefined;\n }\n\n if (Date.now() < this.#cachedEntry.expireAt) {\n return this.#cachedEntry.sk;\n }\n\n this.#clearCachedEntry();\n return undefined;\n }\n\n #clearCachedEntry(): void {\n if (this.#cachedEntry) {\n this.#clearKey(this.#cachedEntry.sk);\n this.#cachedEntry = null;\n }\n\n if (this.#expiryTimer) {\n clearTimeout(this.#expiryTimer);\n this.#expiryTimer = null;\n }\n }\n\n #scheduleExpiry(): void {\n if (!this.#cachedEntry) return;\n\n const now = Date.now();\n const timeToExpiry = this.#cachedEntry.expireAt - now;\n\n if (timeToExpiry <= 0) {\n this.#clearCachedEntry();\n return;\n }\n\n this.#expiryTimer = setTimeout(() => {\n this.#clearCachedEntry();\n }, timeToExpiry + 1);\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * PRF (Pseudo-Random Function) handler for WebAuthn\n * @packageDocumentation\n */\n\nimport type { GetPrfSecretOptions, PasskeyCreationOptions } from './types.js';\n\nconst PRF_EVAL_INPUT = new TextEncoder().encode('nostr-pwk');\n\n/**\n * @returns PRF\n */\nexport async function isPrfSupported(): Promise<boolean> {\n try {\n const response = await navigator.credentials.get({\n publicKey: {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials: [],\n userVerification: 'required',\n extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } },\n } as PublicKeyCredentialRequestOptions,\n });\n\n if (!response) return false;\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const res = assertion.getClientExtensionResults()?.prf?.results?.first;\n return !!res;\n } catch {\n return false;\n }\n}\n\n/**\n * @param options\n * @returns Credential\n */\nexport async function createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n // Node\n const rpName = options.rp?.name || (typeof location !== 'undefined' ? location.host : 'Nosskey');\n const rpId = options.rp?.id;\n const userName = options.user?.name || 'user@example.com';\n const userDisplayName = options.user?.displayName || 'Nosskey user';\n\n const credentialCreationOptions: CredentialCreationOptions = {\n publicKey: {\n rp: {\n name: rpName,\n id: rpId,\n },\n user: {\n id: crypto.getRandomValues(new Uint8Array(16)),\n name: userName,\n displayName: userDisplayName,\n },\n pubKeyCredParams: options.pubKeyCredParams || [{ type: 'public-key', alg: -7 }], // ES256\n authenticatorSelection: options.authenticatorSelection || {\n residentKey: 'required',\n userVerification: 'required',\n },\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n extensions: options.extensions || { prf: {} }, // PRF拡張を要求\n } as PublicKeyCredentialCreationOptions,\n };\n const cred = (await navigator.credentials.create(\n credentialCreationOptions\n )) as PublicKeyCredential;\n\n return new Uint8Array(cred.rawId);\n}\n\n/**\n * ID\n * @param credentialId \n * @param options PRF(rpId、timeout、userVerification)\n * @returns PRF credentialID\n */\nexport async function getPrfSecret(\n credentialId?: Uint8Array,\n options?: GetPrfSecretOptions\n): Promise<{ secret: Uint8Array; id: Uint8Array }> {\n const allowCredentials = credentialId ? [{ type: 'public-key' as const, id: credentialId }] : [];\n\n const requestOptions: PublicKeyCredentialRequestOptions = {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials,\n userVerification: options?.userVerification || 'required',\n extensions: {\n prf: { eval: { first: PRF_EVAL_INPUT } },\n } as AuthenticationExtensionsClientInputs,\n };\n\n if (options?.rpId) {\n requestOptions.rpId = options.rpId;\n }\n if (options?.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await navigator.credentials.get({\n publicKey: requestOptions,\n });\n\n if (!response) {\n throw new Error('Authentication failed');\n }\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const secret = assertion.getClientExtensionResults()?.prf?.results?.first;\n if (!secret) {\n throw new Error('PRF secret not available');\n }\n\n // response credentialId\n const responseId = new Uint8Array((response as PublicKeyCredential).rawId);\n\n return {\n secret: new Uint8Array(secret),\n id: responseId,\n };\n}\n","/**\n * PRF support check with a password-protected-key fallback.\n * If the PRF WebAuthn extension is unavailable, callers can fall back to a\n * password-protected private key. The private key is wrapped with a password-\n * derived AES-GCM key and stored alongside the public key (SPKI).\n *\n * This is a minimal, browser-oriented implementation designed to provide a\n * practical alternative while keeping crypto surface area focused and safe.\n */\n\nimport { getPublicKey } from 'applesauce-core/helpers';\n\nexport type PasswordProtectedBundle = {\n publicKeySpkiBase64: string;\n wrappedPrivateKeyBase64: string;\n saltBase64: string;\n ivBase64: string;\n};\n\nfunction toBase64(bytes: ArrayBuffer): string {\n const arr = new Uint8Array(bytes);\n let binary = '';\n for (let i = 0; i < arr.byteLength; i++) binary += String.fromCharCode(arr[i]);\n if (typeof window !== 'undefined' && (window as any).btoa) {\n return (window as any).btoa(binary);\n }\n return Buffer.from(binary, 'binary').toString('base64');\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n if (typeof window !== 'undefined' && (window as any).atob) {\n const bin = (window as any).atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\nexport async function checkPRFSupport(): Promise<boolean> {\n try {\n const caps = typeof PublicKeyCredential !== 'undefined' ? await PublicKeyCredential.getClientCapabilities() : null;\n const supported = caps?.['extension:prf'] === true;\n if (supported) {\n console.log('PRF extension is supported.');\n } else {\n console.log('PRF extension is not supported.');\n }\n return !!supported;\n } catch (e) {\n console.log('Could not determine PRF support:', e);\n return false;\n }\n}\n\nexport async function generatePasswordProtectedKey(password: string): Promise<PasswordProtectedBundle> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const kp = await cryptoObj.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const publicKey = kp.publicKey;\n const privateKey = kp.privateKey;\n\n const spki = await cryptoObj.subtle.exportKey('spki', publicKey);\n const publicKeySpkiBase64 = toBase64(spki);\n\n const privateKeyJwk = await cryptoObj.subtle.exportKey('jwk', privateKey);\n const jwkStr = JSON.stringify(privateKeyJwk);\n\n const salt = cryptoObj.getRandomValues(new Uint8Array(16));\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt']\n );\n const iv = cryptoObj.getRandomValues(new Uint8Array(12));\n const enc = new TextEncoder().encode(jwkStr);\n const ct = await cryptoObj.subtle.encrypt({ name: 'AES-GCM', iv }, aesKey, enc);\n\n return {\n publicKeySpkiBase64,\n wrappedPrivateKeyBase64: toBase64(ct),\n saltBase64: toBase64(salt.buffer),\n ivBase64: toBase64(iv.buffer),\n };\n}\n\nexport async function unwrapPasswordProtectedPrivateKey(bundle: PasswordProtectedBundle, password: string): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const salt = fromBase64(bundle.saltBase64);\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n );\n const iv = fromBase64(bundle.ivBase64);\n const ct = fromBase64(bundle.wrappedPrivateKeyBase64);\n const jwkBytes = await cryptoObj.subtle.decrypt({ name: 'AES-GCM', iv: iv.slice() }, aesKey, ct.slice());\n const jwkStr = new TextDecoder().decode(jwkBytes);\n const privateKeyJwk = JSON.parse(jwkStr);\n const privateKey = await cryptoObj.subtle.importKey('jwk', privateKeyJwk, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const d = (privateKeyJwk as any).d as string;\n if (!d) throw new Error('Missing private scalar in JWK');\n const sk = base64UrlToBytes(d);\n return sk;\n}\n\nfunction base64UrlToBytes(base64url: string): Uint8Array {\n let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = base64.length % 4;\n if (pad) base64 += '='.repeat(4 - pad);\n if (typeof window !== 'undefined' && (window as any).atob) {\n const binary = (window as any).atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(base64, 'base64'));\n}\n\nexport async function importPublicKeyFromBundle(bundle: PasswordProtectedBundle) {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n const spki = fromBase64(bundle.publicKeySpkiBase64);\n const publicKey = await cryptoObj.subtle.importKey('spki', spki, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify']);\n return publicKey;\n}\n\nconst DEFAULT_SALT = 'nostr-key-derivation';\n\nexport async function deriveNostrPrivateKey(password: string, salt: string = DEFAULT_SALT): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const encoder = new TextEncoder();\n const passwordKey = await cryptoObj.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n );\n\n const derivedBits = await cryptoObj.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt: encoder.encode(salt),\n iterations: 100000,\n hash: 'SHA-256',\n },\n passwordKey,\n 256\n );\n\n return new Uint8Array(derivedBits);\n}\n\nexport async function getPublicKeyFromPassword(password: string, salt: string = DEFAULT_SALT): Promise<string> {\n const sk = await deriveNostrPrivateKey(password, salt);\n return getPublicKey(sk);\n}\n","import { finalizeEvent, getPublicKey } from 'applesauce-core/helpers';\nimport * as secp256k1 from '@noble/secp256k1';\nimport { KeyCache } from './key-cache.js';\nimport { createPasskey, getPrfSecret, isPrfSupported } from './prf-handler.js';\nimport { checkPRFSupport, deriveNostrPrivateKey, getPublicKeyFromPassword, unwrapPasswordProtectedPrivateKey } from './prf-password-fallback.js';\nimport type {\n GetPrfSecretOptions,\n KeyCacheOptions,\n KeyOptions,\n NosskeyManagerLike,\n KeyManagerOptions,\n Event,\n KeyInfo,\n NostrKeyStorageOptions,\n PasskeyCreationOptions,\n SignOptions,\n} from './types.js';\n/**\n * Nosskey class for Passkey-Derived Nostr Identity\n * @packageDocumentation\n */\nimport { bytesToHex, hexToBytes } from './utils.js';\nimport type { KeyRecovery } from './types.js';\n\nexport async function deriveSaltFromUsername(username?: string): Promise<string> {\n if (!username) {\n return '';\n }\n \n const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\nexport function parseRecoveryTag(tags: string[][]): KeyRecovery | null {\n const recoveryTag = tags.find(tag => tag[0] === 'r');\n if (!recoveryTag || recoveryTag.length < 3) return null;\n\n // Format: ['r', recoveryPubkey, recoverySalt, createdAt, signature]\n const createdAt = recoveryTag[3] ? parseInt(recoveryTag[3], 10) : undefined;\n return {\n recoveryPubkey: recoveryTag[1],\n recoverySalt: recoveryTag[2],\n createdAt: createdAt || undefined,\n signature: recoveryTag[4] || undefined,\n };\n}\n\nexport function createRecoveryTag(recovery: KeyRecovery): string[] {\n return [\n 'r',\n recovery.recoveryPubkey,\n recovery.recoverySalt,\n recovery.createdAt?.toString() || '',\n recovery.signature || '',\n ];\n}\n\nexport function getRecoverySignature(kind0: Event): string | null {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return null;\n \n const tag = kind0.tags?.find(t => t[0] === 'r');\n return tag && tag.length > 4 ? tag[4] || null : null;\n}\n\nexport async function verifyRecoverySignature(kind0: Event): Promise<boolean> {\n try {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return false;\n \n const signature = getRecoverySignature(kind0);\n if (!signature || !kind0.pubkey) return false;\n \n // Verify Schnorr signature: signature over current pubkey (as message)\n // using the recovery pubkey\n // Note: verify expects the message hash, not the message itself\n const messageHash = await sha256(kind0.pubkey);\n const signatureBytes = hexToBytes(signature);\n const pubkeyBytes = hexToBytes(kind0.pubkey);\n \n return secp256k1.verify(signatureBytes, messageHash, pubkeyBytes);\n } catch (e) {\n return false;\n }\n}\n\nasync function sha256(message: string): Promise<Uint8Array> {\n const msgBuffer = new TextEncoder().encode(message);\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Nosskey - Passkey-Derived Nostr Keys\n */\nexport class NosskeyManager implements NosskeyManagerLike {\n #keyCache: KeyCache;\n\n // KeyInfo\n #currentKeyInfo: KeyInfo | null = null;\n\n // KeyInfo\n #storageOptions: NostrKeyStorageOptions = {\n enabled: true,\n storageKey: 'nosskey_keyinfo',\n };\n\n // PRF\n #prfOptions: GetPrfSecretOptions = {};\n\n /**\n * NosskeyManager\n * @param options\n */\n constructor(options?: KeyManagerOptions) {\n // KeyCache\n this.#keyCache = new KeyCache(options?.cacheOptions);\n\n if (options?.storageOptions) {\n this.#storageOptions = { ...this.#storageOptions, ...options.storageOptions };\n }\n\n // option\n const userVerification = options?.prfOptions?.userVerification ?? 'required';\n if (options?.prfOptions) {\n this.#prfOptions = { ...options.prfOptions, userVerification };\n } else {\n this.#prfOptions = { userVerification };\n }\n\n // KeyInfo\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n }\n }\n }\n\n /**\n * KeyInfo\n * @param options\n */\n setStorageOptions(options: Partial<NostrKeyStorageOptions>): void {\n this.#storageOptions = { ...this.#storageOptions, ...options };\n\n if (options.enabled === false) {\n this.clearStoredKeyInfo();\n }\n }\n\n /**\n * KeyInfo\n */\n getStorageOptions(): NostrKeyStorageOptions {\n return { ...this.#storageOptions };\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n this.#currentKeyInfo = keyInfo;\n\n if (this.#storageOptions.enabled) {\n void this.#saveKeyInfoToStorage(keyInfo);\n }\n }\n\n /**\n * KeyInfo\n */\n getCurrentKeyInfo(): KeyInfo | null {\n // KeyInfo\n if (!this.#currentKeyInfo && this.#storageOptions.enabled) {\n this.#currentKeyInfo = this.#loadKeyInfoFromStorage();\n }\n return this.#currentKeyInfo;\n }\n\n /**\n * KeyInfo\n * @returns KeyInfo\n */\n hasKeyInfo(): boolean {\n if (this.#currentKeyInfo) {\n return true;\n }\n\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n async #saveKeyInfoToStorage(keyInfo: KeyInfo): Promise<void> {\n if (!this.#storageOptions.enabled) return;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.setItem(key, JSON.stringify(keyInfo));\n }\n\n /**\n * KeyInfo\n */\n #loadKeyInfoFromStorage(): KeyInfo | null {\n if (!this.#storageOptions.enabled) return null;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return null;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n const data = storage.getItem(key);\n\n if (!data) return null;\n\n try {\n return JSON.parse(data) as KeyInfo;\n } catch (e) {\n console.error('Failed to parse stored KeyInfo', e);\n return null;\n }\n }\n\n /**\n * KeyInfo\n */\n clearStoredKeyInfo(): void {\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.removeItem(key);\n\n // KeyInfo\n this.#currentKeyInfo = null;\n }\n\n /**\n * NIP-07\n * KeyInfo\n */\n async getPublicKey(): Promise<string> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return keyInfo.pubkey;\n }\n\n /**\n * NIP-07\n * KeyInfo\n * @param event Nostr\n */\n async signEvent(event: Event): Promise<Event> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return this.signEventWithKeyInfo(event, keyInfo);\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n this.#keyCache.setCacheOptions(options);\n }\n\n getCacheOptions(): KeyCacheOptions {\n return this.#keyCache.getCacheOptions();\n }\n\n getCachedSecretKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n return this.#keyCache.getKey(credentialId);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n this.#keyCache.clearCachedKey(credentialId);\n }\n\n clearAllCachedKeys(): void {\n this.#keyCache.clearAllCachedKeys();\n }\n\n /**\n * @param options\n * @returns Credential\n */\n async createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n return createPasskey({\n rp: {\n id: this.#prfOptions.rpId,\n name: this.#prfOptions.rpId,\n },\n authenticatorSelection: {\n userVerification: this.#prfOptions.userVerification,\n },\n ...options,\n });\n }\n\n/**\n * Check if PRF is supported\n */\n async checkPRFSupport(): Promise<boolean> {\n return checkPRFSupport();\n }\n\n /**\n * Create Nostr key - automatically uses password fallback if PRF unavailable\n * @param credentialId Passkey credential ID\n * @param password Password for encryption (required if PRF not supported)\n * @param options \n */\n async createKey(credentialId?: Uint8Array, password?: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const prfSupported = await this.checkPRFSupport();\n \n let keyInfo: KeyInfo;\n \n if (prfSupported) {\n keyInfo = await this.createPrfNostrKey(credentialId, options);\n \n // Auto-add password recovery if requested and PRF is supported\n if (options.recoveryPassword) {\n keyInfo = await this.addPasswordRecovery(options.recoveryPassword, credentialId);\n }\n } else {\n if (!password) {\n throw new Error('Password is required when PRF is not supported');\n }\n if (!options.username) {\n throw new Error('Username is required when PRF is not supported');\n }\n keyInfo = await this.createPasswordProtectedNostrKey(password, options);\n }\n \n return keyInfo;\n }\n\n /**\n * Create Nostr key using PRF (standard passkey flow)\n */\n async createPrfNostrKey(credentialId?: Uint8Array, options: KeyOptions = {}): Promise<KeyInfo> {\n const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);\n\n if (sk.every((byte) => byte === 0)) {\n throw new Error('Invalid PRF output: all zeros');\n }\n\n const skHex = bytesToHex(sk);\n const publicKey = getPublicKey(sk);\n \n const salt = await deriveSaltFromUsername(options.username);\n\n const keyInfo: KeyInfo = {\n credentialId: bytesToHex(credentialId || responseId),\n pubkey: publicKey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n if (this.#keyCache.isEnabled() && this.#keyCache.getCacheOptions().cacheOnCreation) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n\n return keyInfo;\n }\n\n /**\n * Create Nostr key using password-derived key (fallback when PRF unavailable)\n * @param password Password to derive the private key\n * @param options \n */\n async createPasswordProtectedNostrKey(password: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const salt = await deriveSaltFromUsername(options.username);\n const pubkey = await getPublicKeyFromPassword(password, salt);\n\n const credentialId = bytesToHex((typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto).getRandomValues(new Uint8Array(16)));\n\n const keyInfo: KeyInfo = {\n credentialId,\n pubkey: pubkey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n return keyInfo;\n }\n\n/**\n * @param event Nostr\n * @param keyInfo KeyInfo\n * @param options\n */\n async signEventWithKeyInfo(\n event: Event,\n keyInfo: KeyInfo,\n options: SignOptions = {}\n ): Promise<Event> {\n const { clearMemory = true, tags, password } = options;\n\n const shouldUseCache = this.#keyCache.isEnabled();\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n\n let sk: Uint8Array | undefined;\n\n if (isPasswordDerived) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await deriveNostrPrivateKey(password, keyInfo.salt);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password to sign.');\n }\n } else if (keyInfo.passwordProtectedBundle) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle!, password);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password or use createNostrKey to initialize.');\n }\n } else {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n\n if (!sk) {\n const { secret: prfSecret } = await getPrfSecret(\n hexToBytes(keyInfo.credentialId),\n this.#prfOptions\n );\n sk = prfSecret;\n\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n }\n\n const eventToSign = {\n kind: event.kind,\n content: event.content,\n created_at: event.created_at || Math.floor(Date.now() / 1000),\n tags: tags ? [...(event.tags || []), ...tags] : event.tags || [],\n };\n\n const signedEvent = finalizeEvent(eventToSign, sk);\n\n if (!shouldUseCache && clearMemory) {\n this.#clearKey(sk);\n }\n\n return signedEvent;\n }\n\n/**\n * @param keyInfo KeyInfo\n * @param credentialId KeyInfoのcredentialId\n * @param options\n * @returns \n */\n async exportNostrKey(keyInfo: KeyInfo, credentialId?: Uint8Array, options: KeyOptions = {}): Promise<string> {\n if (keyInfo.passwordProtectedBundle) {\n if (!options.password) {\n throw new Error('Password is required for password-protected keys');\n }\n const sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle, options.password);\n return bytesToHex(sk);\n }\n\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n if (isPasswordDerived) {\n if (!options.password) {\n throw new Error('Password is required for password-derived keys');\n }\n const sk = await deriveNostrPrivateKey(options.password, keyInfo.salt);\n return bytesToHex(sk);\n }\n\n let usedCredentialId = credentialId;\n\n if (!usedCredentialId && keyInfo.credentialId) {\n usedCredentialId = hexToBytes(keyInfo.credentialId);\n }\n\n const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);\n const skHex = bytesToHex(sk);\n\n return skHex;\n }\n\n /**\n * PRF\n */\n async isPrfSupported(): Promise<boolean> {\n return isPrfSupported();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n * @param currentCredentialId Current passkey credential ID\n */\n async addPasswordRecovery(password: string, currentCredentialId?: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (keyInfo.passwordProtectedBundle) {\n throw new Error('Password recovery already exists for password-derived key');\n }\n\n if (keyInfo.recovery) {\n throw new Error('Recovery already configured');\n }\n\n const usedCredentialId = currentCredentialId || (keyInfo.credentialId ? hexToBytes(keyInfo.credentialId) : undefined);\n if (!usedCredentialId) {\n throw new Error('Credential ID required');\n }\n\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n\n // Generate recovery salt\n const recoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n\n // Derive recovery pubkey from password\n const recoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n\n // Sign current pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, keyInfo.pubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n ...keyInfo,\n recovery: {\n recoveryPubkey,\n recoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n #signWithKey(sk: Uint8Array, message: string): string {\n const event = finalizeEvent({\n kind: 0,\n content: '',\n tags: [],\n created_at: Math.floor(Date.now() / 1000),\n }, sk);\n return event.sig;\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (!keyInfo.recovery) {\n throw new Error('No recovery key configured');\n }\n\n if (!newCredentialId) {\n throw new Error('New credential ID is required for recovery');\n }\n\n const { recoveryPubkey, recoverySalt } = keyInfo.recovery;\n\n // Verify password\n const derivedRecoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n if (derivedRecoveryPubkey !== recoveryPubkey) {\n throw new Error('Invalid recovery password');\n }\n\n // Derive new key from new credential\n const { secret: newSk } = await getPrfSecret(newCredentialId, this.#prfOptions);\n const newPubkey = getPublicKey(newSk);\n this.#clearKey(newSk);\n\n // Generate new recovery for the new key\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n const newRecoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n const newRecoveryPubkey = await getPublicKeyFromPassword(password, newRecoverySalt);\n\n // Sign new pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, newPubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n credentialId: bytesToHex(newCredentialId),\n pubkey: newPubkey,\n salt: keyInfo.salt,\n recovery: {\n recoveryPubkey: newRecoveryPubkey,\n recoverySalt: newRecoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n /**\n * Get the recovery data for publishing to kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number; signature?: string } | null {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo || !keyInfo.recovery) return null;\n\n return {\n recoveryPubkey: keyInfo.recovery.recoveryPubkey,\n recoverySalt: keyInfo.recovery.recoverySalt,\n createdAt: keyInfo.recovery.createdAt,\n signature: keyInfo.recovery.signature,\n };\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * Cryptographic utilities for Nosskey\n * @packageDocumentation\n */\n\nconst INFO_BYTES = new TextEncoder().encode('nostr-pwk');\nconst AES_LENGTH = 256; // bits\n\n/**\n * PRF AES-GCM\n * @param secret PRF\n * @param salt\n * @returns AES-GCM\n */\nexport async function deriveAesGcmKey(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {\n const keyMaterial = await crypto.subtle.importKey('raw', secret, 'HKDF', false, ['deriveKey']);\n\n return crypto.subtle.deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt, info: INFO_BYTES },\n keyMaterial,\n { name: 'AES-GCM', length: AES_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param plaintext\n * @returns\n */\nexport async function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array) {\n const buf = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);\n\n const bytes = new Uint8Array(buf);\n return {\n ciphertext: bytes.slice(0, -16),\n tag: bytes.slice(-16),\n };\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param ct\n * @param tag\n * @returns\n */\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n iv: Uint8Array,\n ct: Uint8Array,\n tag: Uint8Array\n): Promise<Uint8Array> {\n const buf = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n new Uint8Array([...ct, ...tag])\n );\n return new Uint8Array(buf);\n}\n","/**\n * Test utilities for sdk\n * @packageDocumentation\n */\n\n/**\n * Helper for testing/debugging\n * @param userId - User identifier\n * @returns Promise resolving to the dummy credential\n */\nexport async function registerDummyPasskey(userId: string): Promise<PublicKeyCredential> {\n // Create a dummy credential for testing\n const dummySignature = new Uint8Array(64);\n // Fill with some non-zero values for testing\n for (let i = 0; i < dummySignature.length; i++) {\n dummySignature[i] = (i + 1) % 256;\n }\n\n const dummyId = new Uint8Array(32);\n for (let i = 0; i < dummyId.length; i++) {\n dummyId[i] = (i + 1) % 256;\n }\n\n const credential = {\n id: 'dummy-credential-id',\n rawId: dummyId,\n type: 'public-key',\n response: {\n clientDataJSON: new Uint8Array(0),\n attestationObject: new Uint8Array(0),\n signature: dummySignature,\n authenticatorData: new Uint8Array(0),\n getAuthenticatorData: () => new Uint8Array(0),\n getPublicKey: () => new Uint8Array(0),\n getPublicKeyAlgorithm: () => -7,\n getTransports: () => ['internal'],\n },\n } as unknown as PublicKeyCredential;\n\n return credential;\n}\n","import { NosskeyManager, type KeyInfo, type Event, type PasskeyCreationOptions, type SignOptions, type KeyOptions } from '../utils';\nimport type { AuthServiceConfig } from '../types/auth';\n\n/**\n * Service wrapper around NosskeyManager\n * Handles WebAuthn/Passkey integration with Nostr\n */\nexport class AuthService {\n private manager: NosskeyManager | null = null;\n private config: AuthServiceConfig;\n\n constructor(config: AuthServiceConfig = {}) {\n this.config = {\n rpId: config.rpId || (typeof window !== 'undefined' ? window.location.hostname.replace(/^www\\./, '') : 'localhost'),\n rpName: config.rpName || this.getDefaultRpName(),\n storageKey: config.storageKey || 'nsauth_keyinfo',\n cacheTimeoutMs: config.cacheTimeoutMs || 30 * 60 * 1000,\n cacheOnCreation: config.cacheOnCreation !== undefined ? config.cacheOnCreation : true,\n };\n }\n\n private getDefaultRpName(): string {\n if (typeof window === 'undefined') return 'localhost';\n const hostname = window.location.hostname;\n if (hostname.includes('nosskey.app')) return 'nosskey.app';\n return hostname.replace(/^www\\./, '');\n }\n\n /**\n * Initialize the NosskeyManager instance\n */\n private getManager(): NosskeyManager {\n if (!this.manager) {\n this.manager = new NosskeyManager({\n cacheOptions: {\n enabled: true,\n timeoutMs: this.config.cacheTimeoutMs,\n cacheOnCreation: this.config.cacheOnCreation,\n },\n storageOptions: {\n enabled: true,\n storageKey: this.config.storageKey,\n },\n });\n }\n return this.manager;\n }\n\n /**\n * Create a new passkey\n * Uses platform authenticator only (Touch ID, Face ID, Windows Hello)\n */\n async createPasskey(username?: string): Promise<Uint8Array> {\n const manager = this.getManager();\n \n const rpId = this.config.rpId === 'localhost' ? 'localhost' : this.config.rpId;\n const rpName = this.config.rpName;\n \n const trimmedUsername = username?.trim();\n const uniqueUsername = trimmedUsername \n ? trimmedUsername \n : `user-${Date.now()}@example.com`;\n \n const options: PasskeyCreationOptions = {\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n name: uniqueUsername,\n displayName: trimmedUsername || 'User',\n },\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n residentKey: 'preferred',\n userVerification: 'preferred',\n },\n extensions: {\n prf: {},\n },\n };\n \n return await manager.createPasskey(options);\n }\n\n/**\n * Create a new Nostr key from a credential ID\n * Automatically uses password fallback if PRF is not supported\n * @param credentialId Passkey credential ID\n * @param password Password (required if PRF not supported)\n * @param options.username Username for the key\n * @param options.recoveryPassword Password for recovery (enables recovery on new device)\n */\n async createKey(credentialId?: Uint8Array, password?: string, options?: KeyOptions): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.createKey(credentialId, password, options);\n }\n\n /**\n * Check if PRF is supported, otherwise password fallback is needed\n */\n async checkPRFSupport(): Promise<boolean> {\n const manager = this.getManager();\n return await manager.checkPRFSupport();\n }\n\n /**\n * Get the current public key\n */\n async getPublicKey(): Promise<string> {\n const manager = this.getManager();\n return await manager.getPublicKey();\n }\n\n /**\n * Sign a Nostr event\n */\n async signEvent(event: Event, options?: SignOptions): Promise<Event> {\n const manager = this.getManager();\n return await manager.signEvent(event, options);\n }\n\n /**\n * Get current key info\n */\n getCurrentKeyInfo(): KeyInfo | null {\n const manager = this.getManager();\n return manager.getCurrentKeyInfo();\n }\n\n /**\n * Set current key info\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n const manager = this.getManager();\n manager.setCurrentKeyInfo(keyInfo);\n }\n\n /**\n * Check if key info exists\n */\n hasKeyInfo(): boolean {\n const manager = this.getManager();\n return manager.hasKeyInfo();\n }\n\n /**\n * Clear stored key info\n */\n clearStoredKeyInfo(): void {\n const manager = this.getManager();\n manager.clearStoredKeyInfo();\n }\n\n/**\n * Check if PRF is supported (legacy alias)\n */\n async isPrfSupported(): Promise<boolean> {\n return this.checkPRFSupport();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n */\n async addPasswordRecovery(password: string): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.addPasswordRecovery(password);\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.activateWithPassword(password, newCredentialId);\n }\n\n /**\n * Get recovery data for kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number } | null {\n const manager = this.getManager();\n return manager.getRecoveryForKind0();\n }\n}\n\n","export const MAX_ROLE_LENGTH = 100;\nconst ROLE_PATTERN = /^[a-zA-Z0-9\\s\\-_]+$/;\n\nexport const isValidRoleTag = (role: string): boolean => {\n const trimmed = role.trim();\n return (\n trimmed.length > 0 &&\n trimmed.length <= MAX_ROLE_LENGTH &&\n ROLE_PATTERN.test(trimmed)\n );\n};\n\nexport const isValidPubkey = (pubkey: string): boolean =>\n pubkey.length === 64 && /^[0-9a-fA-F]+$/.test(pubkey);\n\nexport const isValidHttpUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n};\n\nexport const isValidRelayUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['ws:', 'wss:'].includes(parsed.protocol) && parsed.hostname.length > 0;\n } catch {\n return false;\n }\n};\n","import type { EventStore } from 'applesauce-core';\nimport type { Event } from '../types/nostr';\nimport type { ProfileMetadata, FollowEntry } from '../types/nostr';\nimport type { RelayServiceConfig } from '../types/auth';\nimport { isValidPubkey, isValidRelayUrl, isValidRoleTag } from '../utils/validation';\n\n/**\n * Service for communicating with Nostr relays using applesauce-core\n */\nexport class RelayService {\n private eventStore: EventStore | null = null;\n private relayUrls: string[];\n private defaultRelays = ['wss://relay.damus.io'];\n private readonly maxProfileContentSize = 10000;\n private readonly minProfileQueryIntervalMs = 300;\n private readonly minPublishIntervalMs = 750;\n private readonly lastActionAt = new Map<string, number>();\n\n constructor(config: RelayServiceConfig = {}) {\n this.relayUrls = this.validateRelayUrls(config.relayUrls ?? this.defaultRelays);\n }\n\n /**\n * Initialize with applesauce EventStore\n */\n initialize(eventStore: EventStore): void {\n this.eventStore = eventStore;\n // Set default relays if EventStore has a method for it\n if (eventStore && 'setRelays' in eventStore && typeof eventStore.setRelays === 'function') {\n (eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Set relay URLs\n */\n setRelays(urls: string[]): void {\n this.relayUrls = this.validateRelayUrls(urls);\n if (this.eventStore && 'setRelays' in this.eventStore && typeof this.eventStore.setRelays === 'function') {\n (this.eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Get current relay URLs\n */\n getRelays(): string[] {\n return [...this.relayUrls];\n }\n\n /**\n * Publish an event to relays\n */\n async publishEvent(event: Event, timeoutMs = 1000): Promise<boolean> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('publish', this.minPublishIntervalMs);\n return new Promise((resolve, reject) => {\n if (this.relayUrls.length === 0) {\n reject(new Error('No relays configured'));\n return;\n }\n\n // Use EventStore's publish method\n // Note: This is a simplified implementation - actual applesauce API may differ\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.publish !== 'function') {\n reject(new Error('EventStore does not support publish method'));\n return;\n }\n const subscription = eventStore.publish(event).subscribe({\n next: (response: any) => {\n if (response?.type === 'OK') {\n subscription.unsubscribe();\n resolve(true);\n }\n },\n error: (error: Error) => {\n subscription.unsubscribe();\n reject(error);\n },\n });\n\n // Timeout fallback\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(false);\n }, timeoutMs);\n });\n }\n\n /**\n * Fetch a profile (Kind 0 event)\n */\n async fetchProfile(pubkey: string): Promise<ProfileMetadata | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-profile', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n subscription.unsubscribe();\n resolve(metadata);\n return;\n }\n console.error('Failed to parse profile metadata');\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n // Timeout\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch role tag from profile event (Kind 0)\n */\n async fetchProfileRoleTag(pubkey: string): Promise<string | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-role-tag', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const tags = packet.event.tags || [];\n for (const tag of tags) {\n if (tag[0] === 'role' && tag[1]) {\n const candidate = tag[1].trim();\n if (isValidRoleTag(candidate)) {\n subscription.unsubscribe();\n resolve(candidate);\n return;\n }\n }\n }\n subscription.unsubscribe();\n resolve(null);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile role tag:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch a follow list (Kind 3 event)\n */\n async fetchFollowList(pubkey: string): Promise<FollowEntry[]> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-follow-list', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [3],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve([]);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 3) {\n const followList: FollowEntry[] = [];\n const tags = packet.event.tags || [];\n\n for (const tag of tags) {\n if (tag[0] === 'p' && tag[1]) {\n followList.push({\n pubkey: tag[1],\n relay: tag[2] || undefined,\n petname: tag[3] || undefined,\n });\n }\n }\n\n subscription.unsubscribe();\n resolve(followList);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve([]);\n },\n error: (error: Error) => {\n console.error('Error fetching follow list:', error);\n subscription.unsubscribe();\n resolve([]);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve([]);\n }, 10000);\n });\n }\n\n /**\n * Fetch multiple profiles in batch\n */\n async fetchMultipleProfiles(pubkeys: string[]): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n if (pubkeys.length === 0) {\n return new Map();\n }\n\n await this.enforceRateLimit('fetch-multiple-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, ProfileMetadata>();\n const filter = {\n kinds: [0],\n authors: pubkeys,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n profiles.set(packet.event.pubkey, metadata);\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(profiles);\n },\n error: (error: Error) => {\n console.error('Error fetching profiles:', error);\n subscription.unsubscribe();\n resolve(profiles);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(profiles);\n }, 1000);\n });\n }\n\n /**\n * Query kind 0 events (profiles) by pubkey\n * If pubkeys array is empty, fetches recent kind 0 events\n */\n async queryProfiles(pubkeys: string[] = [], limit = 100): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('query-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, { metadata: ProfileMetadata; timestamp: number }>();\n const filter: any = {\n kinds: [0],\n limit,\n };\n\n if (pubkeys.length > 0) {\n filter.authors = pubkeys;\n }\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n const timestamp = packet.event.created_at || 0;\n const existing = profiles.get(packet.event.pubkey);\n if (!existing || timestamp > existing.timestamp) {\n profiles.set(packet.event.pubkey, { metadata, timestamp });\n }\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n error: (error: Error) => {\n console.error('Error querying profiles:', error);\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n }, 10000);\n });\n }\n\n /**\n * Publish or update a kind 3 event (follow list/contacts)\n */\n async publishFollowList(\n pubkey: string,\n followList: FollowEntry[],\n signEvent: (event: Event) => Promise<Event>\n ): Promise<boolean> {\n const tags: string[][] = followList.map((entry) => {\n if (!isValidPubkey(entry.pubkey)) {\n throw new Error('Invalid pubkey format for follow list entry.');\n }\n if (entry.relay && !isValidRelayUrl(entry.relay)) {\n throw new Error('Invalid relay URL format for follow list entry.');\n }\n const tag: string[] = ['p', entry.pubkey];\n if (entry.relay) {\n tag.push(entry.relay);\n }\n if (entry.petname) {\n tag.push(entry.petname);\n }\n return tag;\n });\n\n const event: Event = {\n kind: 3,\n content: '',\n created_at: Math.floor(Date.now() / 1000),\n tags,\n };\n\n const signedEvent = await signEvent(event);\n return await this.publishEvent(signedEvent);\n }\n\n private validateRelayUrls(urls: string[]): string[] {\n if (urls.length === 0) {\n return [];\n }\n const validUrls = urls.filter((url) => isValidRelayUrl(url));\n if (validUrls.length !== urls.length) {\n throw new Error('Invalid relay URL format');\n }\n return validUrls;\n }\n\n private parseProfileMetadata(content: string): ProfileMetadata | null {\n if (content.length > this.maxProfileContentSize) {\n return null;\n }\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n const metadata: ProfileMetadata = {};\n if (typeof (parsed as ProfileMetadata).name === 'string') {\n metadata.name = (parsed as ProfileMetadata).name;\n }\n if (typeof (parsed as ProfileMetadata).display_name === 'string') {\n metadata.display_name = (parsed as ProfileMetadata).display_name;\n }\n if (typeof (parsed as ProfileMetadata).about === 'string') {\n metadata.about = (parsed as ProfileMetadata).about;\n }\n if (typeof (parsed as ProfileMetadata).picture === 'string') {\n metadata.picture = (parsed as ProfileMetadata).picture;\n }\n if (typeof (parsed as ProfileMetadata).website === 'string') {\n metadata.website = (parsed as ProfileMetadata).website;\n }\n return metadata;\n } catch (error) {\n console.error('Failed to parse profile metadata:', error);\n return null;\n }\n }\n\n private async enforceRateLimit(action: string, minIntervalMs: number): Promise<void> {\n const lastAt = this.lastActionAt.get(action) ?? 0;\n const now = Date.now();\n const waitMs = minIntervalMs - (now - lastAt);\n if (waitMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, waitMs));\n }\n this.lastActionAt.set(action, Date.now());\n }\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#cacheOptions","#cachedEntry","#clearCachedEntry","#scheduleExpiry","#getCachedKeyIfValid","#clearKey","#expiryTimer","#keyCache","#storageOptions","#prfOptions","#loadKeyInfoFromStorage","#currentKeyInfo","#saveKeyInfoToStorage","#clearKey","#signWithKey"],"sources":["../src/utils/utils.ts","../src/utils/key-cache.ts","../src/utils/prf-handler.ts","../src/utils/prf-password-fallback.ts","../src/utils/nosskey.ts","../src/utils/crypto-utils.ts","../src/utils/test-utils.ts","../src/services/auth.service.ts","../src/utils/validation.ts","../src/services/relay.service.ts"],"sourcesContent":["/**\n * @packageDocumentation\n */\n\n/**\n * @param bytes\n * @returns\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n const key = '0123456789abcdef';\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n const firstNibble = bytes[i] >> 4;\n const secondNibble = bytes[i] & 15;\n hex += key[firstNibble] + key[secondNibble];\n }\n return hex;\n}\n\n/**\n * @param hex\n * @returns\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const key = '0123456789abcdef';\n const bytes = [];\n let currentByte = 0;\n let highNibble = true;\n\n for (let i = 0; i < hex.length; i++) {\n const charValue = key.indexOf(hex[i].toLowerCase());\n if (charValue === -1) continue;\n\n if (highNibble) {\n currentByte = charValue << 4;\n highNibble = false;\n } else {\n currentByte += charValue;\n bytes.push(currentByte);\n highNibble = true;\n }\n }\n\n return new Uint8Array(bytes);\n}\n","/**\n * Key cache management for Nosskey\n * @packageDocumentation\n */\n\nimport type { KeyCacheOptions } from './types.js';\nimport { bytesToHex } from './utils.js';\n\n/**\n * Key cache entry with expiration time\n */\ninterface CacheEntry {\n id: string;\n sk: Uint8Array;\n expireAt: number;\n}\n\n/**\n * Key cache manager for managing temporary secret keys\n */\nexport class KeyCache {\n #cachedEntry: CacheEntry | null = null;\n\n #expiryTimer: NodeJS.Timeout | null = null;\n\n #cacheOptions: KeyCacheOptions = {\n enabled: false,\n timeoutMs: 5 * 60 * 1000,\n };\n\n /**\n * KeyCache\n * @param options\n */\n constructor(options?: Partial<KeyCacheOptions>) {\n if (options) {\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n if (Object.keys(options).length > 0 && this.#cachedEntry !== null) {\n this.clearAllCachedKeys();\n }\n\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n\n getCacheOptions(): KeyCacheOptions {\n return { ...this.#cacheOptions };\n }\n\n isEnabled(): boolean {\n return this.#cacheOptions.enabled;\n }\n\n /**\n * @param credentialId\n * @param sk\n */\n setKey(credentialId: Uint8Array | string, sk: Uint8Array): void {\n if (!this.#cacheOptions.enabled) return;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n const timeout =\n this.#cacheOptions.timeoutMs !== undefined ? this.#cacheOptions.timeoutMs : 5 * 60 * 1000;\n const expireAt = Date.now() + timeout;\n\n this.#clearCachedEntry();\n\n this.#cachedEntry = {\n id,\n sk: new Uint8Array(sk),\n expireAt,\n };\n\n try {\n this.#scheduleExpiry();\n } catch (error) {\n this.#clearCachedEntry();\n throw error;\n }\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n getKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n if (!this.#cacheOptions.enabled) return undefined;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n return this.#getCachedKeyIfValid(id);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n\n if (this.#cachedEntry && this.#cachedEntry.id === id) {\n this.#clearCachedEntry();\n }\n }\n\n clearAllCachedKeys(): void {\n this.#clearCachedEntry();\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n #getCachedKeyIfValid(credentialId: string): Uint8Array | undefined {\n if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) {\n return undefined;\n }\n\n if (Date.now() < this.#cachedEntry.expireAt) {\n return this.#cachedEntry.sk;\n }\n\n this.#clearCachedEntry();\n return undefined;\n }\n\n #clearCachedEntry(): void {\n if (this.#cachedEntry) {\n this.#clearKey(this.#cachedEntry.sk);\n this.#cachedEntry = null;\n }\n\n if (this.#expiryTimer) {\n clearTimeout(this.#expiryTimer);\n this.#expiryTimer = null;\n }\n }\n\n #scheduleExpiry(): void {\n if (!this.#cachedEntry) return;\n\n const now = Date.now();\n const timeToExpiry = this.#cachedEntry.expireAt - now;\n\n if (timeToExpiry <= 0) {\n this.#clearCachedEntry();\n return;\n }\n\n this.#expiryTimer = setTimeout(() => {\n this.#clearCachedEntry();\n }, timeToExpiry + 1);\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * PRF (Pseudo-Random Function) handler for WebAuthn\n * @packageDocumentation\n */\n\nimport type { GetPrfSecretOptions, PasskeyCreationOptions } from './types.js';\n\nconst PRF_EVAL_INPUT = new TextEncoder().encode('nostr-pwk');\n\n/**\n * @returns PRF\n */\nexport async function isPrfSupported(): Promise<boolean> {\n try {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) {\n return false;\n }\n\n const response = await navigator.credentials.get({\n publicKey: {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials: [],\n userVerification: 'required',\n extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } },\n } as PublicKeyCredentialRequestOptions,\n });\n\n if (!response) return false;\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const res = assertion.getClientExtensionResults()?.prf?.results?.first;\n return !!res;\n } catch {\n return false;\n }\n}\n\n/**\n * @param options\n * @returns Credential\n */\nexport async function createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n // Node\n const rpName = options.rp?.name || (typeof location !== 'undefined' ? location.host : 'Nosskey');\n const rpId = options.rp?.id;\n const userName = options.user?.name || 'user@example.com';\n const userDisplayName = options.user?.displayName || 'Nosskey user';\n\n const credentialCreationOptions: CredentialCreationOptions = {\n publicKey: {\n rp: {\n name: rpName,\n id: rpId,\n },\n user: {\n id: crypto.getRandomValues(new Uint8Array(16)),\n name: userName,\n displayName: userDisplayName,\n },\n pubKeyCredParams: options.pubKeyCredParams || [{ type: 'public-key', alg: -7 }], // ES256\n authenticatorSelection: options.authenticatorSelection || {\n residentKey: 'required',\n userVerification: 'required',\n },\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n extensions: options.extensions || { prf: {} }, // PRF拡張を要求\n } as PublicKeyCredentialCreationOptions,\n };\n const cred = (await navigator.credentials.create(\n credentialCreationOptions\n )) as PublicKeyCredential;\n\n return new Uint8Array(cred.rawId);\n}\n\n/**\n * ID\n * @param credentialId \n * @param options PRF(rpId、timeout、userVerification)\n * @returns PRF credentialID\n */\nexport async function getPrfSecret(\n credentialId?: Uint8Array,\n options?: GetPrfSecretOptions\n): Promise<{ secret: Uint8Array; id: Uint8Array }> {\n const allowCredentials = credentialId ? [{ type: 'public-key' as const, id: credentialId }] : [];\n\n const requestOptions: PublicKeyCredentialRequestOptions = {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials,\n userVerification: options?.userVerification || 'required',\n extensions: {\n prf: { eval: { first: PRF_EVAL_INPUT } },\n } as AuthenticationExtensionsClientInputs,\n };\n\n if (options?.rpId) {\n requestOptions.rpId = options.rpId;\n }\n if (options?.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await navigator.credentials.get({\n publicKey: requestOptions,\n });\n\n if (!response) {\n throw new Error('Authentication failed');\n }\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const secret = assertion.getClientExtensionResults()?.prf?.results?.first;\n if (!secret) {\n throw new Error('PRF secret not available');\n }\n\n // response credentialId\n const responseId = new Uint8Array((response as PublicKeyCredential).rawId);\n\n return {\n secret: new Uint8Array(secret),\n id: responseId,\n };\n}\n","/**\n * PRF support check with a password-protected-key fallback.\n * If the PRF WebAuthn extension is unavailable, callers can fall back to a\n * password-protected private key. The private key is wrapped with a password-\n * derived AES-GCM key and stored alongside the public key (SPKI).\n *\n * This is a minimal, browser-oriented implementation designed to provide a\n * practical alternative while keeping crypto surface area focused and safe.\n */\n\nimport { getPublicKey } from 'applesauce-core/helpers';\n\nexport type PasswordProtectedBundle = {\n publicKeySpkiBase64: string;\n wrappedPrivateKeyBase64: string;\n saltBase64: string;\n ivBase64: string;\n};\n\nfunction toBase64(bytes: ArrayBuffer): string {\n const arr = new Uint8Array(bytes);\n let binary = '';\n for (let i = 0; i < arr.byteLength; i++) binary += String.fromCharCode(arr[i]);\n if (typeof window !== 'undefined' && (window as any).btoa) {\n return (window as any).btoa(binary);\n }\n return Buffer.from(binary, 'binary').toString('base64');\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n if (typeof window !== 'undefined' && (window as any).atob) {\n const bin = (window as any).atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\nexport async function checkPRFSupport(): Promise<boolean> {\n try {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) {\n console.log('Web Crypto API not available, falling back to password-protected key');\n return false;\n }\n\n const caps = typeof PublicKeyCredential !== 'undefined' ? await PublicKeyCredential.getClientCapabilities() : null;\n const supported = caps?.['extension:prf'] === true;\n if (supported) {\n console.log('PRF extension is supported.');\n } else {\n console.log('PRF extension is not supported.');\n }\n return !!supported;\n } catch (e) {\n console.log('Could not determine PRF support:', e);\n return false;\n }\n}\n\nexport async function generatePasswordProtectedKey(password: string): Promise<PasswordProtectedBundle> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const kp = await cryptoObj.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const publicKey = kp.publicKey;\n const privateKey = kp.privateKey;\n\n const spki = await cryptoObj.subtle.exportKey('spki', publicKey);\n const publicKeySpkiBase64 = toBase64(spki);\n\n const privateKeyJwk = await cryptoObj.subtle.exportKey('jwk', privateKey);\n const jwkStr = JSON.stringify(privateKeyJwk);\n\n const salt = cryptoObj.getRandomValues(new Uint8Array(16));\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt']\n );\n const iv = cryptoObj.getRandomValues(new Uint8Array(12));\n const enc = new TextEncoder().encode(jwkStr);\n const ct = await cryptoObj.subtle.encrypt({ name: 'AES-GCM', iv }, aesKey, enc);\n\n return {\n publicKeySpkiBase64,\n wrappedPrivateKeyBase64: toBase64(ct),\n saltBase64: toBase64(salt.buffer),\n ivBase64: toBase64(iv.buffer),\n };\n}\n\nexport async function unwrapPasswordProtectedPrivateKey(bundle: PasswordProtectedBundle, password: string): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const salt = fromBase64(bundle.saltBase64);\n const pbKey = await cryptoObj.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveKey']);\n const aesKey = await cryptoObj.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt.slice().buffer, iterations: 100000, hash: 'SHA-256' },\n pbKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n );\n const iv = fromBase64(bundle.ivBase64);\n const ct = fromBase64(bundle.wrappedPrivateKeyBase64);\n const jwkBytes = await cryptoObj.subtle.decrypt({ name: 'AES-GCM', iv: iv.slice() }, aesKey, ct.slice());\n const jwkStr = new TextDecoder().decode(jwkBytes);\n const privateKeyJwk = JSON.parse(jwkStr);\n const privateKey = await cryptoObj.subtle.importKey('jwk', privateKeyJwk, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign']);\n const d = (privateKeyJwk as any).d as string;\n if (!d) throw new Error('Missing private scalar in JWK');\n const sk = base64UrlToBytes(d);\n return sk;\n}\n\nfunction base64UrlToBytes(base64url: string): Uint8Array {\n let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = base64.length % 4;\n if (pad) base64 += '='.repeat(4 - pad);\n if (typeof window !== 'undefined' && (window as any).atob) {\n const binary = (window as any).atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n }\n return new Uint8Array(Buffer.from(base64, 'base64'));\n}\n\nexport async function importPublicKeyFromBundle(bundle: PasswordProtectedBundle) {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n const spki = fromBase64(bundle.publicKeySpkiBase64);\n const publicKey = await cryptoObj.subtle.importKey('spki', spki, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify']);\n return publicKey;\n}\n\nconst DEFAULT_SALT = 'nostr-key-derivation';\n\nexport async function deriveNostrPrivateKey(password: string, salt: string = DEFAULT_SALT): Promise<Uint8Array> {\n const cryptoObj: Crypto = (typeof window !== 'undefined' && (window as any).crypto) || (globalThis as any).crypto;\n if (!cryptoObj || !cryptoObj.subtle) throw new Error('Web Crypto API not available');\n\n const encoder = new TextEncoder();\n const passwordKey = await cryptoObj.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n );\n\n const derivedBits = await cryptoObj.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt: encoder.encode(salt),\n iterations: 100000,\n hash: 'SHA-256',\n },\n passwordKey,\n 256\n );\n\n return new Uint8Array(derivedBits);\n}\n\nexport async function getPublicKeyFromPassword(password: string, salt: string = DEFAULT_SALT): Promise<string> {\n const sk = await deriveNostrPrivateKey(password, salt);\n return getPublicKey(sk);\n}\n","import { finalizeEvent, getPublicKey } from 'applesauce-core/helpers';\nimport * as secp256k1 from '@noble/secp256k1';\nimport { KeyCache } from './key-cache.js';\nimport { createPasskey, getPrfSecret, isPrfSupported } from './prf-handler.js';\nimport { checkPRFSupport, deriveNostrPrivateKey, getPublicKeyFromPassword, unwrapPasswordProtectedPrivateKey } from './prf-password-fallback.js';\nimport type {\n GetPrfSecretOptions,\n KeyCacheOptions,\n KeyOptions,\n NosskeyManagerLike,\n KeyManagerOptions,\n Event,\n KeyInfo,\n NostrKeyStorageOptions,\n PasskeyCreationOptions,\n SignOptions,\n} from './types.js';\n/**\n * Nosskey class for Passkey-Derived Nostr Identity\n * @packageDocumentation\n */\nimport { bytesToHex, hexToBytes } from './utils.js';\nimport type { KeyRecovery } from './types.js';\n\nexport async function deriveSaltFromUsername(username?: string): Promise<string> {\n if (!username) {\n return '';\n }\n \n const msgBuffer = new TextEncoder().encode(username.toLowerCase().trim());\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n const hashBuffer = await subtle.digest('SHA-256', msgBuffer);\n return bytesToHex(new Uint8Array(hashBuffer));\n}\n\nexport function parseRecoveryTag(tags: string[][]): KeyRecovery | null {\n const recoveryTag = tags.find(tag => tag[0] === 'r');\n if (!recoveryTag || recoveryTag.length < 3) return null;\n\n // Format: ['r', recoveryPubkey, recoverySalt, createdAt, signature]\n const createdAt = recoveryTag[3] ? parseInt(recoveryTag[3], 10) : undefined;\n return {\n recoveryPubkey: recoveryTag[1],\n recoverySalt: recoveryTag[2],\n createdAt: createdAt || undefined,\n signature: recoveryTag[4] || undefined,\n };\n}\n\nexport function createRecoveryTag(recovery: KeyRecovery): string[] {\n return [\n 'r',\n recovery.recoveryPubkey,\n recovery.recoverySalt,\n recovery.createdAt?.toString() || '',\n recovery.signature || '',\n ];\n}\n\nexport function getRecoverySignature(kind0: Event): string | null {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return null;\n \n const tag = kind0.tags?.find(t => t[0] === 'r');\n return tag && tag.length > 4 ? tag[4] || null : null;\n}\n\nexport async function verifyRecoverySignature(kind0: Event): Promise<boolean> {\n try {\n const recovery = parseRecoveryTag(kind0.tags || []);\n if (!recovery) return false;\n \n const signature = getRecoverySignature(kind0);\n if (!signature || !kind0.pubkey) return false;\n \n // Verify Schnorr signature: signature over current pubkey (as message)\n // using the recovery pubkey\n // Note: verify expects the message hash, not the message itself\n const messageHash = await sha256(kind0.pubkey);\n const signatureBytes = hexToBytes(signature);\n const pubkeyBytes = hexToBytes(kind0.pubkey);\n \n return secp256k1.verify(signatureBytes, messageHash, pubkeyBytes);\n } catch (e) {\n return false;\n }\n}\n\nasync function sha256(message: string): Promise<Uint8Array> {\n const msgBuffer = new TextEncoder().encode(message);\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n const hashBuffer = await subtle.digest('SHA-256', msgBuffer);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Nosskey - Passkey-Derived Nostr Keys\n */\nexport class NosskeyManager implements NosskeyManagerLike {\n #keyCache: KeyCache;\n\n // KeyInfo\n #currentKeyInfo: KeyInfo | null = null;\n\n // KeyInfo\n #storageOptions: NostrKeyStorageOptions = {\n enabled: true,\n storageKey: 'nosskey_keyinfo',\n };\n\n // PRF\n #prfOptions: GetPrfSecretOptions = {};\n\n /**\n * NosskeyManager\n * @param options\n */\n constructor(options?: KeyManagerOptions) {\n // KeyCache\n this.#keyCache = new KeyCache(options?.cacheOptions);\n\n if (options?.storageOptions) {\n this.#storageOptions = { ...this.#storageOptions, ...options.storageOptions };\n }\n\n // option\n const userVerification = options?.prfOptions?.userVerification ?? 'required';\n if (options?.prfOptions) {\n this.#prfOptions = { ...options.prfOptions, userVerification };\n } else {\n this.#prfOptions = { userVerification };\n }\n\n // KeyInfo\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n }\n }\n }\n\n /**\n * KeyInfo\n * @param options\n */\n setStorageOptions(options: Partial<NostrKeyStorageOptions>): void {\n this.#storageOptions = { ...this.#storageOptions, ...options };\n\n if (options.enabled === false) {\n this.clearStoredKeyInfo();\n }\n }\n\n /**\n * KeyInfo\n */\n getStorageOptions(): NostrKeyStorageOptions {\n return { ...this.#storageOptions };\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n this.#currentKeyInfo = keyInfo;\n\n if (this.#storageOptions.enabled) {\n void this.#saveKeyInfoToStorage(keyInfo);\n }\n }\n\n /**\n * KeyInfo\n */\n getCurrentKeyInfo(): KeyInfo | null {\n // KeyInfo\n if (!this.#currentKeyInfo && this.#storageOptions.enabled) {\n this.#currentKeyInfo = this.#loadKeyInfoFromStorage();\n }\n return this.#currentKeyInfo;\n }\n\n /**\n * KeyInfo\n * @returns KeyInfo\n */\n hasKeyInfo(): boolean {\n if (this.#currentKeyInfo) {\n return true;\n }\n\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * KeyInfo\n * @param keyInfo KeyInfo\n */\n async #saveKeyInfoToStorage(keyInfo: KeyInfo): Promise<void> {\n if (!this.#storageOptions.enabled) return;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.setItem(key, JSON.stringify(keyInfo));\n }\n\n /**\n * KeyInfo\n */\n #loadKeyInfoFromStorage(): KeyInfo | null {\n if (!this.#storageOptions.enabled) return null;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return null;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n const data = storage.getItem(key);\n\n if (!data) return null;\n\n try {\n return JSON.parse(data) as KeyInfo;\n } catch (e) {\n console.error('Failed to parse stored KeyInfo', e);\n return null;\n }\n }\n\n /**\n * KeyInfo\n */\n clearStoredKeyInfo(): void {\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.removeItem(key);\n\n // KeyInfo\n this.#currentKeyInfo = null;\n }\n\n /**\n * NIP-07\n * KeyInfo\n */\n async getPublicKey(): Promise<string> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return keyInfo.pubkey;\n }\n\n /**\n * NIP-07\n * KeyInfo\n * @param event Nostr\n */\n async signEvent(event: Event): Promise<Event> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n return this.signEventWithKeyInfo(event, keyInfo);\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n this.#keyCache.setCacheOptions(options);\n }\n\n getCacheOptions(): KeyCacheOptions {\n return this.#keyCache.getCacheOptions();\n }\n\n getCachedSecretKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n return this.#keyCache.getKey(credentialId);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n this.#keyCache.clearCachedKey(credentialId);\n }\n\n clearAllCachedKeys(): void {\n this.#keyCache.clearAllCachedKeys();\n }\n\n /**\n * @param options\n * @returns Credential\n */\n async createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n return createPasskey({\n rp: {\n id: this.#prfOptions.rpId,\n name: this.#prfOptions.rpId,\n },\n authenticatorSelection: {\n userVerification: this.#prfOptions.userVerification,\n },\n ...options,\n });\n }\n\n/**\n * Check if PRF is supported\n */\n async checkPRFSupport(): Promise<boolean> {\n return checkPRFSupport();\n }\n\n /**\n * Create Nostr key - automatically uses password fallback if PRF unavailable\n * @param credentialId Passkey credential ID\n * @param password Password for encryption (required if PRF not supported)\n * @param options \n */\n async createKey(credentialId?: Uint8Array, password?: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const prfSupported = await this.checkPRFSupport();\n \n let keyInfo: KeyInfo;\n \n if (prfSupported) {\n keyInfo = await this.createPrfNostrKey(credentialId, options);\n \n // Auto-add password recovery if requested and PRF is supported\n if (options.recoveryPassword) {\n keyInfo = await this.addPasswordRecovery(options.recoveryPassword, credentialId);\n }\n } else {\n if (!password) {\n throw new Error('Password is required when PRF is not supported');\n }\n if (!options.username) {\n throw new Error('Username is required when PRF is not supported');\n }\n keyInfo = await this.createPasswordProtectedNostrKey(password, options);\n }\n \n return keyInfo;\n }\n\n /**\n * Create Nostr key using PRF (standard passkey flow)\n */\n async createPrfNostrKey(credentialId?: Uint8Array, options: KeyOptions = {}): Promise<KeyInfo> {\n const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);\n\n if (sk.every((byte) => byte === 0)) {\n throw new Error('Invalid PRF output: all zeros');\n }\n\n const skHex = bytesToHex(sk);\n const publicKey = getPublicKey(sk);\n \n const salt = await deriveSaltFromUsername(options.username);\n\n const keyInfo: KeyInfo = {\n credentialId: bytesToHex(credentialId || responseId),\n pubkey: publicKey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n if (this.#keyCache.isEnabled() && this.#keyCache.getCacheOptions().cacheOnCreation) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n\n return keyInfo;\n }\n\n /**\n * Create Nostr key using password-derived key (fallback when PRF unavailable)\n * @param password Password to derive the private key\n * @param options \n */\n async createPasswordProtectedNostrKey(password: string, options: KeyOptions = {}): Promise<KeyInfo> {\n const salt = await deriveSaltFromUsername(options.username);\n const pubkey = await getPublicKeyFromPassword(password, salt);\n\n const credentialId = bytesToHex((typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto).getRandomValues(new Uint8Array(16)));\n\n const keyInfo: KeyInfo = {\n credentialId,\n pubkey: pubkey,\n salt: salt,\n ...(options.username && { username: options.username }),\n };\n\n return keyInfo;\n }\n\n/**\n * @param event Nostr\n * @param keyInfo KeyInfo\n * @param options\n */\n async signEventWithKeyInfo(\n event: Event,\n keyInfo: KeyInfo,\n options: SignOptions = {}\n ): Promise<Event> {\n const { clearMemory = true, tags, password } = options;\n\n const shouldUseCache = this.#keyCache.isEnabled();\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n\n let sk: Uint8Array | undefined;\n\n if (isPasswordDerived) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await deriveNostrPrivateKey(password, keyInfo.salt);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password to sign.');\n }\n } else if (keyInfo.passwordProtectedBundle) {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n if (!sk && password) {\n sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle!, password);\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n if (!sk) {\n throw new Error('Password required - key not in cache. Provide password or use createNostrKey to initialize.');\n }\n } else {\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n\n if (!sk) {\n const { secret: prfSecret } = await getPrfSecret(\n hexToBytes(keyInfo.credentialId),\n this.#prfOptions\n );\n sk = prfSecret;\n\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n }\n\n const eventToSign = {\n kind: event.kind,\n content: event.content,\n created_at: event.created_at || Math.floor(Date.now() / 1000),\n tags: tags ? [...(event.tags || []), ...tags] : event.tags || [],\n };\n\n const signedEvent = finalizeEvent(eventToSign, sk);\n\n if (!shouldUseCache && clearMemory) {\n this.#clearKey(sk);\n }\n\n return signedEvent;\n }\n\n/**\n * @param keyInfo KeyInfo\n * @param credentialId KeyInfoのcredentialId\n * @param options\n * @returns \n */\n async exportNostrKey(keyInfo: KeyInfo, credentialId?: Uint8Array, options: KeyOptions = {}): Promise<string> {\n if (keyInfo.passwordProtectedBundle) {\n if (!options.password) {\n throw new Error('Password is required for password-protected keys');\n }\n const sk = await unwrapPasswordProtectedPrivateKey(keyInfo.passwordProtectedBundle, options.password);\n return bytesToHex(sk);\n }\n\n const isPasswordDerived = !keyInfo.passwordProtectedBundle && keyInfo.salt;\n if (isPasswordDerived) {\n if (!options.password) {\n throw new Error('Password is required for password-derived keys');\n }\n const sk = await deriveNostrPrivateKey(options.password, keyInfo.salt);\n return bytesToHex(sk);\n }\n\n let usedCredentialId = credentialId;\n\n if (!usedCredentialId && keyInfo.credentialId) {\n usedCredentialId = hexToBytes(keyInfo.credentialId);\n }\n\n const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);\n const skHex = bytesToHex(sk);\n\n return skHex;\n }\n\n /**\n * PRF\n */\n async isPrfSupported(): Promise<boolean> {\n return isPrfSupported();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n * @param currentCredentialId Current passkey credential ID\n */\n async addPasswordRecovery(password: string, currentCredentialId?: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (keyInfo.passwordProtectedBundle) {\n throw new Error('Password recovery already exists for password-derived key');\n }\n\n if (keyInfo.recovery) {\n throw new Error('Recovery already configured');\n }\n\n const usedCredentialId = currentCredentialId || (keyInfo.credentialId ? hexToBytes(keyInfo.credentialId) : undefined);\n if (!usedCredentialId) {\n throw new Error('Credential ID required');\n }\n\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n\n // Generate recovery salt\n const recoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n\n // Derive recovery pubkey from password\n const recoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n\n // Sign current pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, keyInfo.pubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n ...keyInfo,\n recovery: {\n recoveryPubkey,\n recoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n #signWithKey(sk: Uint8Array, message: string): string {\n const event = finalizeEvent({\n kind: 0,\n content: '',\n tags: [],\n created_at: Math.floor(Date.now() / 1000),\n }, sk);\n return event.sig;\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current KeyInfo set');\n }\n\n if (!keyInfo.recovery) {\n throw new Error('No recovery key configured');\n }\n\n if (!newCredentialId) {\n throw new Error('New credential ID is required for recovery');\n }\n\n const { recoveryPubkey, recoverySalt } = keyInfo.recovery;\n\n // Verify password\n const derivedRecoveryPubkey = await getPublicKeyFromPassword(password, recoverySalt);\n if (derivedRecoveryPubkey !== recoveryPubkey) {\n throw new Error('Invalid recovery password');\n }\n\n // Derive new key from new credential\n const { secret: newSk } = await getPrfSecret(newCredentialId, this.#prfOptions);\n const newPubkey = getPublicKey(newSk);\n this.#clearKey(newSk);\n\n // Generate new recovery for the new key\n const cryptoObj = typeof window !== 'undefined' ? window.crypto : (globalThis as any).crypto;\n const newRecoverySalt = bytesToHex(cryptoObj.getRandomValues(new Uint8Array(16)));\n const newRecoveryPubkey = await getPublicKeyFromPassword(password, newRecoverySalt);\n\n // Sign new pubkey with recovery key\n const recoverySk = await deriveNostrPrivateKey(password, recoverySalt);\n const signature = this.#signWithKey(recoverySk, newPubkey);\n this.#clearKey(recoverySk);\n\n const updatedKeyInfo: KeyInfo = {\n credentialId: bytesToHex(newCredentialId),\n pubkey: newPubkey,\n salt: keyInfo.salt,\n recovery: {\n recoveryPubkey: newRecoveryPubkey,\n recoverySalt: newRecoverySalt,\n createdAt: Date.now(),\n signature,\n },\n };\n\n this.setCurrentKeyInfo(updatedKeyInfo);\n return updatedKeyInfo;\n }\n\n /**\n * Get the recovery data for publishing to kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number; signature?: string } | null {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo || !keyInfo.recovery) return null;\n\n return {\n recoveryPubkey: keyInfo.recovery.recoveryPubkey,\n recoverySalt: keyInfo.recovery.recoverySalt,\n createdAt: keyInfo.recovery.createdAt,\n signature: keyInfo.recovery.signature,\n };\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * Cryptographic utilities for Nosskey\n * @packageDocumentation\n */\n\nconst INFO_BYTES = new TextEncoder().encode('nostr-pwk');\nconst AES_LENGTH = 256; // bits\n\nfunction getSubtle(): SubtleCrypto {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new Error('Web Crypto API not available');\n return subtle;\n}\n\n/**\n * PRF AES-GCM\n * @param secret PRF\n * @param salt\n * @returns AES-GCM\n */\nexport async function deriveAesGcmKey(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {\n const subtle = getSubtle();\n const keyMaterial = await subtle.importKey('raw', secret, 'HKDF', false, ['deriveKey']);\n\n return subtle.deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt, info: INFO_BYTES },\n keyMaterial,\n { name: 'AES-GCM', length: AES_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param plaintext\n * @returns\n */\nexport async function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array) {\n const subtle = getSubtle();\n const buf = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);\n\n const bytes = new Uint8Array(buf);\n return {\n ciphertext: bytes.slice(0, -16),\n tag: bytes.slice(-16),\n };\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param ct\n * @param tag\n * @returns\n */\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n iv: Uint8Array,\n ct: Uint8Array,\n tag: Uint8Array\n): Promise<Uint8Array> {\n const subtle = getSubtle();\n const buf = await subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n new Uint8Array([...ct, ...tag])\n );\n return new Uint8Array(buf);\n}\n","/**\n * Test utilities for sdk\n * @packageDocumentation\n */\n\n/**\n * Helper for testing/debugging\n * @param userId - User identifier\n * @returns Promise resolving to the dummy credential\n */\nexport async function registerDummyPasskey(userId: string): Promise<PublicKeyCredential> {\n // Create a dummy credential for testing\n const dummySignature = new Uint8Array(64);\n // Fill with some non-zero values for testing\n for (let i = 0; i < dummySignature.length; i++) {\n dummySignature[i] = (i + 1) % 256;\n }\n\n const dummyId = new Uint8Array(32);\n for (let i = 0; i < dummyId.length; i++) {\n dummyId[i] = (i + 1) % 256;\n }\n\n const credential = {\n id: 'dummy-credential-id',\n rawId: dummyId,\n type: 'public-key',\n response: {\n clientDataJSON: new Uint8Array(0),\n attestationObject: new Uint8Array(0),\n signature: dummySignature,\n authenticatorData: new Uint8Array(0),\n getAuthenticatorData: () => new Uint8Array(0),\n getPublicKey: () => new Uint8Array(0),\n getPublicKeyAlgorithm: () => -7,\n getTransports: () => ['internal'],\n },\n } as unknown as PublicKeyCredential;\n\n return credential;\n}\n","import { NosskeyManager, type KeyInfo, type Event, type PasskeyCreationOptions, type SignOptions, type KeyOptions } from '../utils';\nimport type { AuthServiceConfig } from '../types/auth';\n\n/**\n * Service wrapper around NosskeyManager\n * Handles WebAuthn/Passkey integration with Nostr\n */\nexport class AuthService {\n private manager: NosskeyManager | null = null;\n private config: AuthServiceConfig;\n\n constructor(config: AuthServiceConfig = {}) {\n this.config = {\n rpId: config.rpId || (typeof window !== 'undefined' ? window.location.hostname.replace(/^www\\./, '') : 'localhost'),\n rpName: config.rpName || this.getDefaultRpName(),\n storageKey: config.storageKey || 'nsauth_keyinfo',\n cacheTimeoutMs: config.cacheTimeoutMs || 30 * 60 * 1000,\n cacheOnCreation: config.cacheOnCreation !== undefined ? config.cacheOnCreation : true,\n };\n }\n\n private getDefaultRpName(): string {\n if (typeof window === 'undefined') return 'localhost';\n const hostname = window.location.hostname;\n if (hostname.includes('nosskey.app')) return 'nosskey.app';\n return hostname.replace(/^www\\./, '');\n }\n\n /**\n * Initialize the NosskeyManager instance\n */\n private getManager(): NosskeyManager {\n if (!this.manager) {\n this.manager = new NosskeyManager({\n cacheOptions: {\n enabled: true,\n timeoutMs: this.config.cacheTimeoutMs,\n cacheOnCreation: this.config.cacheOnCreation,\n },\n storageOptions: {\n enabled: true,\n storageKey: this.config.storageKey,\n },\n });\n }\n return this.manager;\n }\n\n /**\n * Create a new passkey\n * Uses platform authenticator only (Touch ID, Face ID, Windows Hello)\n */\n async createPasskey(username?: string): Promise<Uint8Array> {\n const manager = this.getManager();\n \n const rpId = this.config.rpId === 'localhost' ? 'localhost' : this.config.rpId;\n const rpName = this.config.rpName;\n \n const trimmedUsername = username?.trim();\n const uniqueUsername = trimmedUsername \n ? trimmedUsername \n : `user-${Date.now()}@example.com`;\n \n const options: PasskeyCreationOptions = {\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n name: uniqueUsername,\n displayName: trimmedUsername || 'User',\n },\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n residentKey: 'preferred',\n userVerification: 'preferred',\n },\n extensions: {\n prf: {},\n },\n };\n \n return await manager.createPasskey(options);\n }\n\n/**\n * Create a new Nostr key from a credential ID\n * Automatically uses password fallback if PRF is not supported\n * @param credentialId Passkey credential ID\n * @param password Password (required if PRF not supported)\n * @param options.username Username for the key\n * @param options.recoveryPassword Password for recovery (enables recovery on new device)\n */\n async createKey(credentialId?: Uint8Array, password?: string, options?: KeyOptions): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.createKey(credentialId, password, options);\n }\n\n /**\n * Check if PRF is supported, otherwise password fallback is needed\n */\n async checkPRFSupport(): Promise<boolean> {\n const manager = this.getManager();\n return await manager.checkPRFSupport();\n }\n\n /**\n * Get the current public key\n */\n async getPublicKey(): Promise<string> {\n const manager = this.getManager();\n return await manager.getPublicKey();\n }\n\n /**\n * Sign a Nostr event\n */\n async signEvent(event: Event, options?: SignOptions): Promise<Event> {\n const manager = this.getManager();\n return await manager.signEvent(event, options);\n }\n\n /**\n * Get current key info\n */\n getCurrentKeyInfo(): KeyInfo | null {\n const manager = this.getManager();\n return manager.getCurrentKeyInfo();\n }\n\n /**\n * Set current key info\n */\n setCurrentKeyInfo(keyInfo: KeyInfo): void {\n const manager = this.getManager();\n manager.setCurrentKeyInfo(keyInfo);\n }\n\n /**\n * Check if key info exists\n */\n hasKeyInfo(): boolean {\n const manager = this.getManager();\n return manager.hasKeyInfo();\n }\n\n /**\n * Clear stored key info\n */\n clearStoredKeyInfo(): void {\n const manager = this.getManager();\n manager.clearStoredKeyInfo();\n }\n\n/**\n * Check if PRF is supported (legacy alias)\n */\n async isPrfSupported(): Promise<boolean> {\n return this.checkPRFSupport();\n }\n\n /**\n * Add password recovery to an existing PRF key\n * @param password Password for recovery key\n */\n async addPasswordRecovery(password: string): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.addPasswordRecovery(password);\n }\n\n /**\n * Activate recovery using password\n * Requires new credential ID from new device\n * @param password Password for recovery key\n * @param newCredentialId New passkey credential ID (required)\n */\n async activateWithPassword(password: string, newCredentialId: Uint8Array): Promise<KeyInfo> {\n const manager = this.getManager();\n return await manager.activateWithPassword(password, newCredentialId);\n }\n\n /**\n * Get recovery data for kind-0\n */\n getRecoveryForKind0(): { recoveryPubkey: string; recoverySalt: string; createdAt?: number } | null {\n const manager = this.getManager();\n return manager.getRecoveryForKind0();\n }\n}\n\n","export const MAX_ROLE_LENGTH = 100;\nconst ROLE_PATTERN = /^[a-zA-Z0-9\\s\\-_]+$/;\n\nexport const isValidRoleTag = (role: string): boolean => {\n const trimmed = role.trim();\n return (\n trimmed.length > 0 &&\n trimmed.length <= MAX_ROLE_LENGTH &&\n ROLE_PATTERN.test(trimmed)\n );\n};\n\nexport const isValidPubkey = (pubkey: string): boolean =>\n pubkey.length === 64 && /^[0-9a-fA-F]+$/.test(pubkey);\n\nexport const isValidHttpUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n};\n\nexport const isValidRelayUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return ['ws:', 'wss:'].includes(parsed.protocol) && parsed.hostname.length > 0;\n } catch {\n return false;\n }\n};\n","import type { EventStore } from 'applesauce-core';\nimport type { Event } from '../types/nostr';\nimport type { ProfileMetadata, FollowEntry } from '../types/nostr';\nimport type { RelayServiceConfig } from '../types/auth';\nimport { isValidPubkey, isValidRelayUrl, isValidRoleTag } from '../utils/validation';\n\n/**\n * Service for communicating with Nostr relays using applesauce-core\n */\nexport class RelayService {\n private eventStore: EventStore | null = null;\n private relayUrls: string[];\n private defaultRelays = ['wss://relay.damus.io'];\n private readonly maxProfileContentSize = 10000;\n private readonly minProfileQueryIntervalMs = 300;\n private readonly minPublishIntervalMs = 750;\n private readonly lastActionAt = new Map<string, number>();\n\n constructor(config: RelayServiceConfig = {}) {\n this.relayUrls = this.validateRelayUrls(config.relayUrls ?? this.defaultRelays);\n }\n\n /**\n * Initialize with applesauce EventStore\n */\n initialize(eventStore: EventStore): void {\n this.eventStore = eventStore;\n // Set default relays if EventStore has a method for it\n if (eventStore && 'setRelays' in eventStore && typeof eventStore.setRelays === 'function') {\n (eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Set relay URLs\n */\n setRelays(urls: string[]): void {\n this.relayUrls = this.validateRelayUrls(urls);\n if (this.eventStore && 'setRelays' in this.eventStore && typeof this.eventStore.setRelays === 'function') {\n (this.eventStore as any).setRelays(this.relayUrls);\n }\n }\n\n /**\n * Get current relay URLs\n */\n getRelays(): string[] {\n return [...this.relayUrls];\n }\n\n /**\n * Publish an event to relays\n */\n async publishEvent(event: Event, timeoutMs = 1000): Promise<boolean> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('publish', this.minPublishIntervalMs);\n return new Promise((resolve, reject) => {\n if (this.relayUrls.length === 0) {\n reject(new Error('No relays configured'));\n return;\n }\n\n // Use EventStore's publish method\n // Note: This is a simplified implementation - actual applesauce API may differ\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.publish !== 'function') {\n reject(new Error('EventStore does not support publish method'));\n return;\n }\n const subscription = eventStore.publish(event).subscribe({\n next: (response: any) => {\n if (response?.type === 'OK') {\n subscription.unsubscribe();\n resolve(true);\n }\n },\n error: (error: Error) => {\n subscription.unsubscribe();\n reject(error);\n },\n });\n\n // Timeout fallback\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(false);\n }, timeoutMs);\n });\n }\n\n /**\n * Fetch a profile (Kind 0 event)\n */\n async fetchProfile(pubkey: string): Promise<ProfileMetadata | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-profile', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n subscription.unsubscribe();\n resolve(metadata);\n return;\n }\n console.error('Failed to parse profile metadata');\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n // Timeout\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch role tag from profile event (Kind 0)\n */\n async fetchProfileRoleTag(pubkey: string): Promise<string | null> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-role-tag', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [0],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(null);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0) {\n const tags = packet.event.tags || [];\n for (const tag of tags) {\n if (tag[0] === 'role' && tag[1]) {\n const candidate = tag[1].trim();\n if (isValidRoleTag(candidate)) {\n subscription.unsubscribe();\n resolve(candidate);\n return;\n }\n }\n }\n subscription.unsubscribe();\n resolve(null);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(null);\n },\n error: (error: Error) => {\n console.error('Error fetching profile role tag:', error);\n subscription.unsubscribe();\n resolve(null);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(null);\n }, 5000);\n });\n }\n\n /**\n * Fetch a follow list (Kind 3 event)\n */\n async fetchFollowList(pubkey: string): Promise<FollowEntry[]> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('fetch-follow-list', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const filter = {\n kinds: [3],\n authors: [pubkey],\n limit: 1,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve([]);\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 3) {\n const followList: FollowEntry[] = [];\n const tags = packet.event.tags || [];\n\n for (const tag of tags) {\n if (tag[0] === 'p' && tag[1]) {\n followList.push({\n pubkey: tag[1],\n relay: tag[2] || undefined,\n petname: tag[3] || undefined,\n });\n }\n }\n\n subscription.unsubscribe();\n resolve(followList);\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve([]);\n },\n error: (error: Error) => {\n console.error('Error fetching follow list:', error);\n subscription.unsubscribe();\n resolve([]);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve([]);\n }, 10000);\n });\n }\n\n /**\n * Fetch multiple profiles in batch\n */\n async fetchMultipleProfiles(pubkeys: string[]): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n if (pubkeys.length === 0) {\n return new Map();\n }\n\n await this.enforceRateLimit('fetch-multiple-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, ProfileMetadata>();\n const filter = {\n kinds: [0],\n authors: pubkeys,\n };\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n profiles.set(packet.event.pubkey, metadata);\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n resolve(profiles);\n },\n error: (error: Error) => {\n console.error('Error fetching profiles:', error);\n subscription.unsubscribe();\n resolve(profiles);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n resolve(profiles);\n }, 1000);\n });\n }\n\n /**\n * Query kind 0 events (profiles) by pubkey\n * If pubkeys array is empty, fetches recent kind 0 events\n */\n async queryProfiles(pubkeys: string[] = [], limit = 100): Promise<Map<string, ProfileMetadata>> {\n if (!this.eventStore) {\n throw new Error('RelayService not initialized. Call initialize() with an EventStore instance.');\n }\n\n await this.enforceRateLimit('query-profiles', this.minProfileQueryIntervalMs);\n return new Promise((resolve) => {\n const profiles = new Map<string, { metadata: ProfileMetadata; timestamp: number }>();\n const filter: any = {\n kinds: [0],\n limit,\n };\n\n if (pubkeys.length > 0) {\n filter.authors = pubkeys;\n }\n\n const eventStore = this.eventStore as any;\n if (!eventStore || typeof eventStore.query !== 'function') {\n resolve(new Map());\n return;\n }\n const subscription = eventStore.query(filter).subscribe({\n next: (packet: any) => {\n if (packet?.event && packet.event.kind === 0 && packet.event.pubkey) {\n const metadata = this.parseProfileMetadata(packet.event.content);\n if (metadata) {\n const timestamp = packet.event.created_at || 0;\n const existing = profiles.get(packet.event.pubkey);\n if (!existing || timestamp > existing.timestamp) {\n profiles.set(packet.event.pubkey, { metadata, timestamp });\n }\n } else {\n console.error('Failed to parse profile metadata');\n }\n }\n },\n complete: () => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n error: (error: Error) => {\n console.error('Error querying profiles:', error);\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n },\n });\n\n setTimeout(() => {\n subscription.unsubscribe();\n const result = new Map<string, ProfileMetadata>();\n profiles.forEach((value, pubkey) => {\n result.set(pubkey, value.metadata);\n });\n resolve(result);\n }, 10000);\n });\n }\n\n /**\n * Publish or update a kind 3 event (follow list/contacts)\n */\n async publishFollowList(\n pubkey: string,\n followList: FollowEntry[],\n signEvent: (event: Event) => Promise<Event>\n ): Promise<boolean> {\n const tags: string[][] = followList.map((entry) => {\n if (!isValidPubkey(entry.pubkey)) {\n throw new Error('Invalid pubkey format for follow list entry.');\n }\n if (entry.relay && !isValidRelayUrl(entry.relay)) {\n throw new Error('Invalid relay URL format for follow list entry.');\n }\n const tag: string[] = ['p', entry.pubkey];\n if (entry.relay) {\n tag.push(entry.relay);\n }\n if (entry.petname) {\n tag.push(entry.petname);\n }\n return tag;\n });\n\n const event: Event = {\n kind: 3,\n content: '',\n created_at: Math.floor(Date.now() / 1000),\n tags,\n };\n\n const signedEvent = await signEvent(event);\n return await this.publishEvent(signedEvent);\n }\n\n private validateRelayUrls(urls: string[]): string[] {\n if (urls.length === 0) {\n return [];\n }\n const validUrls = urls.filter((url) => isValidRelayUrl(url));\n if (validUrls.length !== urls.length) {\n throw new Error('Invalid relay URL format');\n }\n return validUrls;\n }\n\n private parseProfileMetadata(content: string): ProfileMetadata | null {\n if (content.length > this.maxProfileContentSize) {\n return null;\n }\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n const metadata: ProfileMetadata = {};\n if (typeof (parsed as ProfileMetadata).name === 'string') {\n metadata.name = (parsed as ProfileMetadata).name;\n }\n if (typeof (parsed as ProfileMetadata).display_name === 'string') {\n metadata.display_name = (parsed as ProfileMetadata).display_name;\n }\n if (typeof (parsed as ProfileMetadata).about === 'string') {\n metadata.about = (parsed as ProfileMetadata).about;\n }\n if (typeof (parsed as ProfileMetadata).picture === 'string') {\n metadata.picture = (parsed as ProfileMetadata).picture;\n }\n if (typeof (parsed as ProfileMetadata).website === 'string') {\n metadata.website = (parsed as ProfileMetadata).website;\n }\n return metadata;\n } catch (error) {\n console.error('Failed to parse profile metadata:', error);\n return null;\n }\n }\n\n private async enforceRateLimit(action: string, minIntervalMs: number): Promise<void> {\n const lastAt = this.lastActionAt.get(action) ?? 0;\n const now = Date.now();\n const waitMs = minIntervalMs - (now - lastAt);\n if (waitMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, waitMs));\n }\n this.lastActionAt.set(action, Date.now());\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;AAQA,SAAgB,WAAW,OAA2B;CACpD,MAAM,MAAM;CACZ,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,cAAc,MAAM,MAAM;EAChC,MAAM,eAAe,MAAM,KAAK;AAChC,SAAO,IAAI,eAAe,IAAI;;AAEhC,QAAO;;;;;;AAOT,SAAgB,WAAW,KAAyB;CAClD,MAAM,MAAM;CACZ,MAAM,QAAQ,EAAE;CAChB,IAAI,cAAc;CAClB,IAAI,aAAa;AAEjB,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;EACnC,MAAM,YAAY,IAAI,QAAQ,IAAI,GAAG,aAAa,CAAC;AACnD,MAAI,cAAc,GAAI;AAEtB,MAAI,YAAY;AACd,iBAAc,aAAa;AAC3B,gBAAa;SACR;AACL,kBAAe;AACf,SAAM,KAAK,YAAY;AACvB,gBAAa;;;AAIjB,QAAO,IAAI,WAAW,MAAM;;;;;;;;ACvB9B,IAAa,WAAb,MAAsB;CACpB,eAAkC;CAElC,eAAsC;CAEtC,gBAAiC;EAC/B,SAAS;EACT,WAAW,MAAS;EACrB;;;;;CAMD,YAAY,SAAoC;AAC9C,MAAI,QACF,OAAKA,eAAgB;GAAE,GAAG,MAAKA;GAAe,GAAG;GAAS;;;;;CAO9D,gBAAgB,SAAyC;AACvD,MAAI,OAAO,KAAK,QAAQ,CAAC,SAAS,KAAK,MAAKC,gBAAiB,KAC3D,MAAK,oBAAoB;AAG3B,QAAKD,eAAgB;GAAE,GAAG,MAAKA;GAAe,GAAG;GAAS;;CAG5D,kBAAmC;AACjC,SAAO,EAAE,GAAG,MAAKA,cAAe;;CAGlC,YAAqB;AACnB,SAAO,MAAKA,aAAc;;;;;;CAO5B,OAAO,cAAmC,IAAsB;AAC9D,MAAI,CAAC,MAAKA,aAAc,QAAS;EAEjC,MAAM,KAAK,OAAO,iBAAiB,WAAW,eAAe,WAAW,aAAa;EACrF,MAAM,UACJ,MAAKA,aAAc,cAAc,SAAY,MAAKA,aAAc,YAAY,MAAS;EACvF,MAAM,WAAW,KAAK,KAAK,GAAG;AAE9B,QAAKE,kBAAmB;AAExB,QAAKD,cAAe;GAClB;GACA,IAAI,IAAI,WAAW,GAAG;GACtB;GACD;AAED,MAAI;AACF,SAAKE,gBAAiB;WACf,OAAO;AACd,SAAKD,kBAAmB;AACxB,SAAM;;;;;;;CAQV,OAAO,cAA2D;AAChE,MAAI,CAAC,MAAKF,aAAc,QAAS,QAAO;EAExC,MAAM,KAAK,OAAO,iBAAiB,WAAW,eAAe,WAAW,aAAa;AACrF,SAAO,MAAKI,oBAAqB,GAAG;;;;;CAMtC,eAAe,cAAyC;EACtD,MAAM,KAAK,OAAO,iBAAiB,WAAW,eAAe,WAAW,aAAa;AAErF,MAAI,MAAKH,eAAgB,MAAKA,YAAa,OAAO,GAChD,OAAKC,kBAAmB;;CAI5B,qBAA2B;AACzB,QAAKA,kBAAmB;;;;;;CAO1B,qBAAqB,cAA8C;AACjE,MAAI,CAAC,MAAKD,eAAgB,MAAKA,YAAa,OAAO,aACjD;AAGF,MAAI,KAAK,KAAK,GAAG,MAAKA,YAAa,SACjC,QAAO,MAAKA,YAAa;AAG3B,QAAKC,kBAAmB;;CAI1B,oBAA0B;AACxB,MAAI,MAAKD,aAAc;AACrB,SAAKI,SAAU,MAAKJ,YAAa,GAAG;AACpC,SAAKA,cAAe;;AAGtB,MAAI,MAAKK,aAAc;AACrB,gBAAa,MAAKA,YAAa;AAC/B,SAAKA,cAAe;;;CAIxB,kBAAwB;AACtB,MAAI,CAAC,MAAKL,YAAc;EAExB,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,eAAe,MAAKA,YAAa,WAAW;AAElD,MAAI,gBAAgB,GAAG;AACrB,SAAKC,kBAAmB;AACxB;;AAGF,QAAKI,cAAe,iBAAiB;AACnC,SAAKJ,kBAAmB;KACvB,eAAe,EAAE;;;;;CAMtB,UAAU,KAAuB;AAC/B,OAAK,OAAO,EAAE;;;;;;AC3JlB,MAAM,iBAAiB,IAAI,aAAa,CAAC,OAAO,YAAY;;;;AAK5D,eAAsB,iBAAmC;AACvD,KAAI;EACF,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,MAAI,CAAC,aAAa,CAAC,UAAU,OAC3B,QAAO;EAGT,MAAM,WAAW,MAAM,UAAU,YAAY,IAAI,EAC/C,WAAW;GACT,WAAW,OAAO,gBAAgB,IAAI,WAAW,GAAG,CAAC;GACrD,kBAAkB,EAAE;GACpB,kBAAkB;GAClB,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,gBAAgB,EAAE,EAAE;GACzD,EACF,CAAC;AAEF,MAAI,CAAC,SAAU,QAAO;AAatB,SAAO,CAAC,CAXU,SAUI,2BAA2B,EAAE,KAAK,SAAS;SAE3D;AACN,SAAO;;;;;;;AAQX,eAAsB,cAAc,UAAkC,EAAE,EAAuB;CAE7F,MAAM,SAAS,QAAQ,IAAI,SAAS,OAAO,aAAa,cAAc,SAAS,OAAO;CACtF,MAAM,OAAO,QAAQ,IAAI;CACzB,MAAM,WAAW,QAAQ,MAAM,QAAQ;CACvC,MAAM,kBAAkB,QAAQ,MAAM,eAAe;CAErD,MAAM,4BAAuD,EAC3D,WAAW;EACT,IAAI;GACF,MAAM;GACN,IAAI;GACL;EACD,MAAM;GACJ,IAAI,OAAO,gBAAgB,IAAI,WAAW,GAAG,CAAC;GAC9C,MAAM;GACN,aAAa;GACd;EACD,kBAAkB,QAAQ,oBAAoB,CAAC;GAAE,MAAM;GAAc,KAAK;GAAI,CAAC;EAC/E,wBAAwB,QAAQ,0BAA0B;GACxD,aAAa;GACb,kBAAkB;GACnB;EACD,WAAW,OAAO,gBAAgB,IAAI,WAAW,GAAG,CAAC;EACrD,YAAY,QAAQ,cAAc,EAAE,KAAK,EAAE,EAAE;EAC9C,EACF;CACD,MAAM,OAAQ,MAAM,UAAU,YAAY,OACxC,0BACD;AAED,QAAO,IAAI,WAAW,KAAK,MAAM;;;;;;;;AASnC,eAAsB,aACpB,cACA,SACiD;CACjD,MAAM,mBAAmB,eAAe,CAAC;EAAE,MAAM;EAAuB,IAAI;EAAc,CAAC,GAAG,EAAE;CAEhG,MAAM,iBAAoD;EACxD,WAAW,OAAO,gBAAgB,IAAI,WAAW,GAAG,CAAC;EACrD;EACA,kBAAkB,SAAS,oBAAoB;EAC/C,YAAY,EACV,KAAK,EAAE,MAAM,EAAE,OAAO,gBAAgB,EAAE,EACzC;EACF;AAED,KAAI,SAAS,KACX,gBAAe,OAAO,QAAQ;AAEhC,KAAI,SAAS,QACX,gBAAe,UAAU,QAAQ;CAGnC,MAAM,WAAW,MAAM,UAAU,YAAY,IAAI,EAC/C,WAAW,gBACZ,CAAC;AAEF,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,wBAAwB;CAa1C,MAAM,SAVY,SAUO,2BAA2B,EAAE,KAAK,SAAS;AACpE,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,2BAA2B;CAI7C,MAAM,aAAa,IAAI,WAAY,SAAiC,MAAM;AAE1E,QAAO;EACL,QAAQ,IAAI,WAAW,OAAO;EAC9B,IAAI;EACL;;;;;;;;;;;;;;AC3HH,SAAS,SAAS,OAA4B;CAC5C,MAAM,MAAM,IAAI,WAAW,MAAM;CACjC,IAAI,SAAS;AACb,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,YAAY,IAAK,WAAU,OAAO,aAAa,IAAI,GAAG;AAC9E,KAAI,OAAO,WAAW,eAAgB,OAAe,KACnD,QAAQ,OAAe,KAAK,OAAO;AAErC,QAAO,OAAO,KAAK,QAAQ,SAAS,CAAC,SAAS,SAAS;;AAGzD,SAAS,WAAW,KAAyB;AAC3C,KAAI,OAAO,WAAW,eAAgB,OAAe,MAAM;EACzD,MAAM,MAAO,OAAe,KAAK,IAAI;EACrC,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAO;AACxC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,OAAM,KAAK,IAAI,WAAW,EAAE;AACjE,SAAO;;AAET,QAAO,IAAI,WAAW,OAAO,KAAK,KAAK,SAAS,CAAC;;AAGnD,eAAsB,kBAAoC;AACxD,KAAI;EACF,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,MAAI,CAAC,aAAa,CAAC,UAAU,QAAQ;AACnC,WAAQ,IAAI,uEAAuE;AACnF,UAAO;;EAIT,MAAM,aADO,OAAO,wBAAwB,cAAc,MAAM,oBAAoB,uBAAuB,GAAG,QACrF,qBAAqB;AAC9C,MAAI,UACF,SAAQ,IAAI,8BAA8B;MAE1C,SAAQ,IAAI,kCAAkC;AAEhD,SAAO,CAAC,CAAC;UACF,GAAG;AACV,UAAQ,IAAI,oCAAoC,EAAE;AAClD,SAAO;;;AAIX,eAAsB,6BAA6B,UAAoD;CACrG,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,KAAI,CAAC,aAAa,CAAC,UAAU,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CAEpF,MAAM,KAAK,MAAM,UAAU,OAAO,YAAY;EAAE,MAAM;EAAS,YAAY;EAAS,EAAE,MAAM,CAAC,OAAO,CAAC;CACrG,MAAM,YAAY,GAAG;CACrB,MAAM,aAAa,GAAG;CAGtB,MAAM,sBAAsB,SADf,MAAM,UAAU,OAAO,UAAU,QAAQ,UAAU,CACtB;CAE1C,MAAM,gBAAgB,MAAM,UAAU,OAAO,UAAU,OAAO,WAAW;CACzE,MAAM,SAAS,KAAK,UAAU,cAAc;CAE5C,MAAM,OAAO,UAAU,gBAAgB,IAAI,WAAW,GAAG,CAAC;CAC1D,MAAM,QAAQ,MAAM,UAAU,OAAO,UAAU,OAAO,IAAI,aAAa,CAAC,OAAO,SAAS,EAAE,UAAU,OAAO,CAAC,YAAY,CAAC;CACzH,MAAM,SAAS,MAAM,UAAU,OAAO,UACpC;EAAE,MAAM;EAAU,MAAM,KAAK,OAAO,CAAC;EAAQ,YAAY;EAAQ,MAAM;EAAW,EAClF,OACA;EAAE,MAAM;EAAW,QAAQ;EAAK,EAChC,OACA,CAAC,UAAU,CACZ;CACD,MAAM,KAAK,UAAU,gBAAgB,IAAI,WAAW,GAAG,CAAC;CACxD,MAAM,MAAM,IAAI,aAAa,CAAC,OAAO,OAAO;AAG5C,QAAO;EACL;EACA,yBAAyB,SAJhB,MAAM,UAAU,OAAO,QAAQ;GAAE,MAAM;GAAW;GAAI,EAAE,QAAQ,IAAI,CAIxC;EACrC,YAAY,SAAS,KAAK,OAAO;EACjC,UAAU,SAAS,GAAG,OAAO;EAC9B;;AAGH,eAAsB,kCAAkC,QAAiC,UAAuC;CAC9H,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,KAAI,CAAC,aAAa,CAAC,UAAU,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CAEpF,MAAM,OAAO,WAAW,OAAO,WAAW;CAC1C,MAAM,QAAQ,MAAM,UAAU,OAAO,UAAU,OAAO,IAAI,aAAa,CAAC,OAAO,SAAS,EAAE,UAAU,OAAO,CAAC,YAAY,CAAC;CACzH,MAAM,SAAS,MAAM,UAAU,OAAO,UACpC;EAAE,MAAM;EAAU,MAAM,KAAK,OAAO,CAAC;EAAQ,YAAY;EAAQ,MAAM;EAAW,EAClF,OACA;EAAE,MAAM;EAAW,QAAQ;EAAK,EAChC,OACA,CAAC,UAAU,CACZ;CACD,MAAM,KAAK,WAAW,OAAO,SAAS;CACtC,MAAM,KAAK,WAAW,OAAO,wBAAwB;CACrD,MAAM,WAAW,MAAM,UAAU,OAAO,QAAQ;EAAE,MAAM;EAAW,IAAI,GAAG,OAAO;EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC;CACxG,MAAM,SAAS,IAAI,aAAa,CAAC,OAAO,SAAS;CACjD,MAAM,gBAAgB,KAAK,MAAM,OAAO;AACrB,OAAM,UAAU,OAAO,UAAU,OAAO,eAAe;EAAE,MAAM;EAAS,YAAY;EAAS,EAAE,MAAM,CAAC,OAAO,CAAC;CACjI,MAAM,IAAK,cAAsB;AACjC,KAAI,CAAC,EAAG,OAAM,IAAI,MAAM,gCAAgC;AAExD,QADW,iBAAiB,EAAE;;AAIhC,SAAS,iBAAiB,WAA+B;CACvD,IAAI,SAAS,UAAU,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;CAC5D,MAAM,MAAM,OAAO,SAAS;AAC5B,KAAI,IAAK,WAAU,IAAI,OAAO,IAAI,IAAI;AACtC,KAAI,OAAO,WAAW,eAAgB,OAAe,MAAM;EACzD,MAAM,SAAU,OAAe,KAAK,OAAO;EAC3C,MAAM,QAAQ,IAAI,WAAW,OAAO,OAAO;AAC3C,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,KAAK,OAAO,WAAW,EAAE;AACvE,SAAO;;AAET,QAAO,IAAI,WAAW,OAAO,KAAK,QAAQ,SAAS,CAAC;;AAGtD,eAAsB,0BAA0B,QAAiC;CAC/E,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,KAAI,CAAC,aAAa,CAAC,UAAU,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CACpF,MAAM,OAAO,WAAW,OAAO,oBAAoB;AAEnD,QADkB,MAAM,UAAU,OAAO,UAAU,QAAQ,MAAM;EAAE,MAAM;EAAS,YAAY;EAAS,EAAE,MAAM,CAAC,SAAS,CAAC;;AAI5H,MAAM,eAAe;AAErB,eAAsB,sBAAsB,UAAkB,OAAe,cAAmC;CAC9G,MAAM,YAAqB,OAAO,WAAW,eAAgB,OAAe,UAAY,WAAmB;AAC3G,KAAI,CAAC,aAAa,CAAC,UAAU,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CAEpF,MAAM,UAAU,IAAI,aAAa;CACjC,MAAM,cAAc,MAAM,UAAU,OAAO,UACzC,OACA,QAAQ,OAAO,SAAS,EACxB,UACA,OACA,CAAC,aAAa,CACf;CAED,MAAM,cAAc,MAAM,UAAU,OAAO,WACzC;EACE,MAAM;EACN,MAAM,QAAQ,OAAO,KAAK;EAC1B,YAAY;EACZ,MAAM;EACP,EACD,aACA,IACD;AAED,QAAO,IAAI,WAAW,YAAY;;AAGpC,eAAsB,yBAAyB,UAAkB,OAAe,cAA+B;AAE7G,QAAO,aADI,MAAM,sBAAsB,UAAU,KAAK,CAC/B;;;;;;;;;ACrJzB,eAAsB,uBAAuB,UAAoC;AAC/E,KAAI,CAAC,SACH,QAAO;CAGT,MAAM,YAAY,IAAI,aAAa,CAAC,OAAO,SAAS,aAAa,CAAC,MAAM,CAAC;CACzE,MAAM,SAAS,WAAW,QAAQ;AAClC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CAC5D,MAAM,aAAa,MAAM,OAAO,OAAO,WAAW,UAAU;AAC5D,QAAO,WAAW,IAAI,WAAW,WAAW,CAAC;;AAG/C,SAAgB,iBAAiB,MAAsC;CACrE,MAAM,cAAc,KAAK,MAAK,QAAO,IAAI,OAAO,IAAI;AACpD,KAAI,CAAC,eAAe,YAAY,SAAS,EAAG,QAAO;CAGnD,MAAM,YAAY,YAAY,KAAK,SAAS,YAAY,IAAI,GAAG,GAAG;AAClE,QAAO;EACL,gBAAgB,YAAY;EAC5B,cAAc,YAAY;EAC1B,WAAW,aAAa;EACxB,WAAW,YAAY,MAAM;EAC9B;;AAGH,SAAgB,kBAAkB,UAAiC;AACjE,QAAO;EACL;EACA,SAAS;EACT,SAAS;EACT,SAAS,WAAW,UAAU,IAAI;EAClC,SAAS,aAAa;EACvB;;AAGH,SAAgB,qBAAqB,OAA6B;AAEhE,KAAI,CADa,iBAAiB,MAAM,QAAQ,EAAE,CAAC,CACpC,QAAO;CAEtB,MAAM,MAAM,MAAM,MAAM,MAAK,MAAK,EAAE,OAAO,IAAI;AAC/C,QAAO,OAAO,IAAI,SAAS,IAAI,IAAI,MAAM,OAAO;;AAGlD,eAAsB,wBAAwB,OAAgC;AAC5E,KAAI;AAEF,MAAI,CADa,iBAAiB,MAAM,QAAQ,EAAE,CAAC,CACpC,QAAO;EAEtB,MAAM,YAAY,qBAAqB,MAAM;AAC7C,MAAI,CAAC,aAAa,CAAC,MAAM,OAAQ,QAAO;EAKxC,MAAM,cAAc,MAAM,OAAO,MAAM,OAAO;EAC9C,MAAM,iBAAiB,WAAW,UAAU;EAC5C,MAAM,cAAc,WAAW,MAAM,OAAO;AAE5C,SAAO,UAAU,OAAO,gBAAgB,aAAa,YAAY;UAC1D,GAAG;AACV,SAAO;;;AAIX,eAAe,OAAO,SAAsC;CAC1D,MAAM,YAAY,IAAI,aAAa,CAAC,OAAO,QAAQ;CACnD,MAAM,SAAS,WAAW,QAAQ;AAClC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B;CAC5D,MAAM,aAAa,MAAM,OAAO,OAAO,WAAW,UAAU;AAC5D,QAAO,IAAI,WAAW,WAAW;;;;;AAMnC,IAAa,iBAAb,MAA0D;CACxD;CAGA,kBAAkC;CAGlC,kBAA0C;EACxC,SAAS;EACT,YAAY;EACb;CAGD,cAAmC,EAAE;;;;;CAMrC,YAAY,SAA6B;AAEvC,QAAKK,WAAY,IAAI,SAAS,SAAS,aAAa;AAEpD,MAAI,SAAS,eACX,OAAKC,iBAAkB;GAAE,GAAG,MAAKA;GAAiB,GAAG,QAAQ;GAAgB;EAI/E,MAAM,mBAAmB,SAAS,YAAY,oBAAoB;AAClE,MAAI,SAAS,WACX,OAAKC,aAAc;GAAE,GAAG,QAAQ;GAAY;GAAkB;MAE9D,OAAKA,aAAc,EAAE,kBAAkB;AAIzC,MAAI,MAAKD,eAAgB,SAAS;GAChC,MAAM,gBAAgB,MAAKE,wBAAyB;AACpD,OAAI,cACF,OAAKC,iBAAkB;;;;;;;CAS7B,kBAAkB,SAAgD;AAChE,QAAKH,iBAAkB;GAAE,GAAG,MAAKA;GAAiB,GAAG;GAAS;AAE9D,MAAI,QAAQ,YAAY,MACtB,MAAK,oBAAoB;;;;;CAO7B,oBAA4C;AAC1C,SAAO,EAAE,GAAG,MAAKA,gBAAiB;;;;;;CAOpC,kBAAkB,SAAwB;AACxC,QAAKG,iBAAkB;AAEvB,MAAI,MAAKH,eAAgB,QACvB,CAAK,MAAKI,qBAAsB,QAAQ;;;;;CAO5C,oBAAoC;AAElC,MAAI,CAAC,MAAKD,kBAAmB,MAAKH,eAAgB,QAChD,OAAKG,iBAAkB,MAAKD,wBAAyB;AAEvD,SAAO,MAAKC;;;;;;CAOd,aAAsB;AACpB,MAAI,MAAKA,eACP,QAAO;AAGT,MAAI,MAAKH,eAAgB,SAAS;GAChC,MAAM,gBAAgB,MAAKE,wBAAyB;AACpD,OAAI,eAAe;AACjB,UAAKC,iBAAkB;AACvB,WAAO;;;AAIX,SAAO;;;;;;CAOT,OAAMC,qBAAsB,SAAiC;AAC3D,MAAI,CAAC,MAAKJ,eAAgB,QAAS;EAEnC,MAAM,UACJ,MAAKA,eAAgB,YAAY,OAAO,iBAAiB,cAAc,eAAe;AAExF,MAAI,CAAC,QAAS;EAEd,MAAM,MAAM,MAAKA,eAAgB,cAAc;AAC/C,UAAQ,QAAQ,KAAK,KAAK,UAAU,QAAQ,CAAC;;;;;CAM/C,0BAA0C;AACxC,MAAI,CAAC,MAAKA,eAAgB,QAAS,QAAO;EAE1C,MAAM,UACJ,MAAKA,eAAgB,YAAY,OAAO,iBAAiB,cAAc,eAAe;AAExF,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,MAAM,MAAKA,eAAgB,cAAc;EAC/C,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAEjC,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI;AACF,UAAO,KAAK,MAAM,KAAK;WAChB,GAAG;AACV,WAAQ,MAAM,kCAAkC,EAAE;AAClD,UAAO;;;;;;CAOX,qBAA2B;EACzB,MAAM,UACJ,MAAKA,eAAgB,YAAY,OAAO,iBAAiB,cAAc,eAAe;AAExF,MAAI,CAAC,QAAS;EAEd,MAAM,MAAM,MAAKA,eAAgB,cAAc;AAC/C,UAAQ,WAAW,IAAI;AAGvB,QAAKG,iBAAkB;;;;;;CAOzB,MAAM,eAAgC;EACpC,MAAM,UAAU,KAAK,mBAAmB;AACxC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,yBAAyB;AAE3C,SAAO,QAAQ;;;;;;;CAQjB,MAAM,UAAU,OAA8B;EAC5C,MAAM,UAAU,KAAK,mBAAmB;AACxC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,yBAAyB;AAE3C,SAAO,KAAK,qBAAqB,OAAO,QAAQ;;;;;CAMlD,gBAAgB,SAAyC;AACvD,QAAKJ,SAAU,gBAAgB,QAAQ;;CAGzC,kBAAmC;AACjC,SAAO,MAAKA,SAAU,iBAAiB;;CAGzC,mBAAmB,cAA2D;AAC5E,SAAO,MAAKA,SAAU,OAAO,aAAa;;;;;CAM5C,eAAe,cAAyC;AACtD,QAAKA,SAAU,eAAe,aAAa;;CAG7C,qBAA2B;AACzB,QAAKA,SAAU,oBAAoB;;;;;;CAOrC,MAAM,cAAc,UAAkC,EAAE,EAAuB;AAC7E,SAAO,cAAc;GACnB,IAAI;IACF,IAAI,MAAKE,WAAY;IACrB,MAAM,MAAKA,WAAY;IACxB;GACD,wBAAwB,EACtB,kBAAkB,MAAKA,WAAY,kBACpC;GACD,GAAG;GACJ,CAAC;;;;;CAMJ,MAAM,kBAAoC;AACxC,SAAO,iBAAiB;;;;;;;;CAS1B,MAAM,UAAU,cAA2B,UAAmB,UAAsB,EAAE,EAAoB;EACxG,MAAM,eAAe,MAAM,KAAK,iBAAiB;EAEjD,IAAI;AAEJ,MAAI,cAAc;AAChB,aAAU,MAAM,KAAK,kBAAkB,cAAc,QAAQ;AAG7D,OAAI,QAAQ,iBACV,WAAU,MAAM,KAAK,oBAAoB,QAAQ,kBAAkB,aAAa;SAE7E;AACL,OAAI,CAAC,SACH,OAAM,IAAI,MAAM,iDAAiD;AAEnE,OAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MAAM,iDAAiD;AAEnE,aAAU,MAAM,KAAK,gCAAgC,UAAU,QAAQ;;AAGzE,SAAO;;;;;CAMT,MAAM,kBAAkB,cAA2B,UAAsB,EAAE,EAAoB;EAC7F,MAAM,EAAE,QAAQ,IAAI,IAAI,eAAe,MAAM,aAAa,cAAc,MAAKA,WAAY;AAEzF,MAAI,GAAG,OAAO,SAAS,SAAS,EAAE,CAChC,OAAM,IAAI,MAAM,gCAAgC;AAGpC,aAAW,GAAG;EAC5B,MAAM,YAAY,aAAa,GAAG;EAElC,MAAM,OAAO,MAAM,uBAAuB,QAAQ,SAAS;EAE3D,MAAM,UAAmB;GACvB,cAAc,WAAW,gBAAgB,WAAW;GACpD,QAAQ;GACF;GACN,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,UAAU;GACvD;AAED,MAAI,MAAKF,SAAU,WAAW,IAAI,MAAKA,SAAU,iBAAiB,CAAC,gBACjE,OAAKA,SAAU,OAAO,QAAQ,cAAc,GAAG;AAGjD,SAAO;;;;;;;CAQT,MAAM,gCAAgC,UAAkB,UAAsB,EAAE,EAAoB;EAClG,MAAM,OAAO,MAAM,uBAAuB,QAAQ,SAAS;EAC3D,MAAM,SAAS,MAAM,yBAAyB,UAAU,KAAK;AAW7D,SAPyB;GACvB,cAHmB,YAAY,OAAO,WAAW,cAAc,OAAO,SAAU,WAAmB,QAAQ,gBAAgB,IAAI,WAAW,GAAG,CAAC,CAAC;GAIvI;GACF;GACN,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,UAAU;GACvD;;;;;;;CAUH,MAAM,qBACJ,OACA,SACA,UAAuB,EAAE,EACT;EAChB,MAAM,EAAE,cAAc,MAAM,MAAM,aAAa;EAE/C,MAAM,iBAAiB,MAAKA,SAAU,WAAW;EACjD,MAAM,oBAAoB,CAAC,QAAQ,2BAA2B,QAAQ;EAEtE,IAAI;AAEJ,MAAI,mBAAmB;AACrB,OAAI,eACF,MAAK,MAAKA,SAAU,OAAO,QAAQ,aAAa;AAElD,OAAI,CAAC,MAAM,UAAU;AACnB,SAAK,MAAM,sBAAsB,UAAU,QAAQ,KAAK;AACxD,QAAI,eACF,OAAKA,SAAU,OAAO,QAAQ,cAAc,GAAG;;AAGnD,OAAI,CAAC,GACH,OAAM,IAAI,MAAM,kEAAkE;aAE3E,QAAQ,yBAAyB;AAC1C,OAAI,eACF,MAAK,MAAKA,SAAU,OAAO,QAAQ,aAAa;AAElD,OAAI,CAAC,MAAM,UAAU;AACnB,SAAK,MAAM,kCAAkC,QAAQ,yBAA0B,SAAS;AACxF,QAAI,eACF,OAAKA,SAAU,OAAO,QAAQ,cAAc,GAAG;;AAGnD,OAAI,CAAC,GACH,OAAM,IAAI,MAAM,8FAA8F;SAE3G;AACL,OAAI,eACF,MAAK,MAAKA,SAAU,OAAO,QAAQ,aAAa;AAGlD,OAAI,CAAC,IAAI;IACP,MAAM,EAAE,QAAQ,cAAc,MAAM,aAClC,WAAW,QAAQ,aAAa,EAChC,MAAKE,WACN;AACD,SAAK;AAEL,QAAI,eACF,OAAKF,SAAU,OAAO,QAAQ,cAAc,GAAG;;;EAYrD,MAAM,cAAc,cAPA;GAClB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,YAAY,MAAM,cAAc,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAC7D,MAAM,OAAO,CAAC,GAAI,MAAM,QAAQ,EAAE,EAAG,GAAG,KAAK,GAAG,MAAM,QAAQ,EAAE;GACjE,EAE8C,GAAG;AAElD,MAAI,CAAC,kBAAkB,YACrB,OAAKM,SAAU,GAAG;AAGpB,SAAO;;;;;;;;CAST,MAAM,eAAe,SAAkB,cAA2B,UAAsB,EAAE,EAAmB;AAC3G,MAAI,QAAQ,yBAAyB;AACnC,OAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MAAM,mDAAmD;AAGrE,UAAO,WADI,MAAM,kCAAkC,QAAQ,yBAAyB,QAAQ,SAAS,CAChF;;AAIvB,MAD0B,CAAC,QAAQ,2BAA2B,QAAQ,MAC/C;AACrB,OAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MAAM,iDAAiD;AAGnE,UAAO,WADI,MAAM,sBAAsB,QAAQ,UAAU,QAAQ,KAAK,CACjD;;EAGvB,IAAI,mBAAmB;AAEvB,MAAI,CAAC,oBAAoB,QAAQ,aAC/B,oBAAmB,WAAW,QAAQ,aAAa;EAGrD,MAAM,EAAE,QAAQ,OAAO,MAAM,aAAa,kBAAkB,MAAKJ,WAAY;AAG7E,SAFc,WAAW,GAAG;;;;;CAQ9B,MAAM,iBAAmC;AACvC,SAAO,gBAAgB;;;;;;;CAQzB,MAAM,oBAAoB,UAAkB,qBAAoD;EAC9F,MAAM,UAAU,KAAK,mBAAmB;AACxC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,yBAAyB;AAG3C,MAAI,QAAQ,wBACV,OAAM,IAAI,MAAM,4DAA4D;AAG9E,MAAI,QAAQ,SACV,OAAM,IAAI,MAAM,8BAA8B;AAIhD,MAAI,EADqB,wBAAwB,QAAQ,eAAe,WAAW,QAAQ,aAAa,GAAG,SAEzG,OAAM,IAAI,MAAM,yBAAyB;EAM3C,MAAM,eAAe,YAHH,OAAO,WAAW,cAAc,OAAO,SAAU,WAAmB,QAG5C,gBAAgB,IAAI,WAAW,GAAG,CAAC,CAAC;EAG9E,MAAM,iBAAiB,MAAM,yBAAyB,UAAU,aAAa;EAG7E,MAAM,aAAa,MAAM,sBAAsB,UAAU,aAAa;EACtE,MAAM,YAAY,MAAKK,YAAa,YAAY,QAAQ,OAAO;AAC/D,QAAKD,SAAU,WAAW;EAE1B,MAAM,iBAA0B;GAC9B,GAAG;GACH,UAAU;IACR;IACA;IACA,WAAW,KAAK,KAAK;IACrB;IACD;GACF;AAED,OAAK,kBAAkB,eAAe;AACtC,SAAO;;CAGT,aAAa,IAAgB,SAAyB;AAOpD,SANc,cAAc;GAC1B,MAAM;GACN,SAAS;GACT,MAAM,EAAE;GACR,YAAY,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAC1C,EAAE,GAAG,CACO;;;;;;;;CASf,MAAM,qBAAqB,UAAkB,iBAA+C;EAC1F,MAAM,UAAU,KAAK,mBAAmB;AACxC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,yBAAyB;AAG3C,MAAI,CAAC,QAAQ,SACX,OAAM,IAAI,MAAM,6BAA6B;AAG/C,MAAI,CAAC,gBACH,OAAM,IAAI,MAAM,6CAA6C;EAG/D,MAAM,EAAE,gBAAgB,iBAAiB,QAAQ;AAIjD,MAD8B,MAAM,yBAAyB,UAAU,aAAa,KACtD,eAC5B,OAAM,IAAI,MAAM,4BAA4B;EAI9C,MAAM,EAAE,QAAQ,UAAU,MAAM,aAAa,iBAAiB,MAAKJ,WAAY;EAC/E,MAAM,YAAY,aAAa,MAAM;AACrC,QAAKI,SAAU,MAAM;EAIrB,MAAM,kBAAkB,YADN,OAAO,WAAW,cAAc,OAAO,SAAU,WAAmB,QACzC,gBAAgB,IAAI,WAAW,GAAG,CAAC,CAAC;EACjF,MAAM,oBAAoB,MAAM,yBAAyB,UAAU,gBAAgB;EAGnF,MAAM,aAAa,MAAM,sBAAsB,UAAU,aAAa;EACtE,MAAM,YAAY,MAAKC,YAAa,YAAY,UAAU;AAC1D,QAAKD,SAAU,WAAW;EAE1B,MAAM,iBAA0B;GAC9B,cAAc,WAAW,gBAAgB;GACzC,QAAQ;GACR,MAAM,QAAQ;GACd,UAAU;IACR,gBAAgB;IAChB,cAAc;IACd,WAAW,KAAK,KAAK;IACrB;IACD;GACF;AAED,OAAK,kBAAkB,eAAe;AACtC,SAAO;;;;;CAMT,sBAAuH;EACrH,MAAM,UAAU,KAAK,mBAAmB;AACxC,MAAI,CAAC,WAAW,CAAC,QAAQ,SAAU,QAAO;AAE1C,SAAO;GACL,gBAAgB,QAAQ,SAAS;GACjC,cAAc,QAAQ,SAAS;GAC/B,WAAW,QAAQ,SAAS;GAC5B,WAAW,QAAQ,SAAS;GAC7B;;;;;CAMH,UAAU,KAAuB;AAC/B,OAAK,OAAO,EAAE;;;;;;;;;;AChqBlB,MAAM,aAAa,IAAI,aAAa,CAAC,OAAO,YAAY;AACxD,MAAM,aAAa;AAEnB,SAAS,YAA0B;CACjC,MAAM,SAAS,WAAW,QAAQ;AAClC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC5D,QAAO;;;;;;;;AAST,eAAsB,gBAAgB,QAAoB,MAAsC;CAC9F,MAAM,SAAS,WAAW;CAC1B,MAAM,cAAc,MAAM,OAAO,UAAU,OAAO,QAAQ,QAAQ,OAAO,CAAC,YAAY,CAAC;AAEvF,QAAO,OAAO,UACZ;EAAE,MAAM;EAAQ,MAAM;EAAW;EAAM,MAAM;EAAY,EACzD,aACA;EAAE,MAAM;EAAW,QAAQ;EAAY,EACvC,OACA,CAAC,WAAW,UAAU,CACvB;;;;;;;;;AAUH,eAAsB,cAAc,KAAgB,IAAgB,WAAuB;CAEzF,MAAM,MAAM,MADG,WAAW,CACD,QAAQ;EAAE,MAAM;EAAW;EAAI,EAAE,KAAK,UAAU;CAEzE,MAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,QAAO;EACL,YAAY,MAAM,MAAM,GAAG,IAAI;EAC/B,KAAK,MAAM,MAAM,IAAI;EACtB;;;;;;;;;;AAWH,eAAsB,cACpB,KACA,IACA,IACA,KACqB;CAErB,MAAM,MAAM,MADG,WAAW,CACD,QACvB;EAAE,MAAM;EAAW;EAAI,EACvB,KACA,IAAI,WAAW,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAChC;AACD,QAAO,IAAI,WAAW,IAAI;;;;;;;;;;;;;;AC7D5B,eAAsB,qBAAqB,QAA8C;CAEvF,MAAM,iBAAiB,IAAI,WAAW,GAAG;AAEzC,MAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,IACzC,gBAAe,MAAM,IAAI,KAAK;CAGhC,MAAM,UAAU,IAAI,WAAW,GAAG;AAClC,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,SAAQ,MAAM,IAAI,KAAK;AAmBzB,QAhBmB;EACjB,IAAI;EACJ,OAAO;EACP,MAAM;EACN,UAAU;GACR,gBAAgB,IAAI,WAAW,EAAE;GACjC,mBAAmB,IAAI,WAAW,EAAE;GACpC,WAAW;GACX,mBAAmB,IAAI,WAAW,EAAE;GACpC,4BAA4B,IAAI,WAAW,EAAE;GAC7C,oBAAoB,IAAI,WAAW,EAAE;GACrC,6BAA6B;GAC7B,qBAAqB,CAAC,WAAW;GAClC;EACF;;;;;;;;;AC9BH,IAAa,cAAb,MAAyB;CAIvB,YAAY,SAA4B,EAAE,EAAE;iBAHH;AAIvC,OAAK,SAAS;GACZ,MAAM,OAAO,SAAS,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS,QAAQ,UAAU,GAAG,GAAG;GACvG,QAAQ,OAAO,UAAU,KAAK,kBAAkB;GAChD,YAAY,OAAO,cAAc;GACjC,gBAAgB,OAAO,kBAAkB,OAAU;GACnD,iBAAiB,OAAO,oBAAoB,SAAY,OAAO,kBAAkB;GAClF;;CAGH,AAAQ,mBAA2B;AACjC,MAAI,OAAO,WAAW,YAAa,QAAO;EAC1C,MAAM,WAAW,OAAO,SAAS;AACjC,MAAI,SAAS,SAAS,cAAc,CAAE,QAAO;AAC7C,SAAO,SAAS,QAAQ,UAAU,GAAG;;;;;CAMvC,AAAQ,aAA6B;AACnC,MAAI,CAAC,KAAK,QACR,MAAK,UAAU,IAAI,eAAe;GAChC,cAAc;IACZ,SAAS;IACT,WAAW,KAAK,OAAO;IACvB,iBAAiB,KAAK,OAAO;IAC9B;GACD,gBAAgB;IACd,SAAS;IACT,YAAY,KAAK,OAAO;IACzB;GACF,CAAC;AAEJ,SAAO,KAAK;;;;;;CAOd,MAAM,cAAc,UAAwC;EAC1D,MAAM,UAAU,KAAK,YAAY;EAEjC,MAAM,OAAO,KAAK,OAAO,SAAS,cAAc,cAAc,KAAK,OAAO;EAC1E,MAAM,SAAS,KAAK,OAAO;EAE3B,MAAM,kBAAkB,UAAU,MAAM;EACxC,MAAM,iBAAiB,kBACnB,kBACA,QAAQ,KAAK,KAAK,CAAC;EAEvB,MAAM,UAAkC;GACtC,IAAI;IACF,IAAI;IACJ,MAAM;IACP;GACD,MAAM;IACJ,MAAM;IACN,aAAa,mBAAmB;IACjC;GACD,wBAAwB;IACtB,yBAAyB;IACzB,aAAa;IACb,kBAAkB;IACnB;GACD,YAAY,EACV,KAAK,EAAE,EACR;GACF;AAED,SAAO,MAAM,QAAQ,cAAc,QAAQ;;;;;;;;;;CAW7C,MAAM,UAAU,cAA2B,UAAmB,SAAwC;AAEpG,SAAO,MADS,KAAK,YAAY,CACZ,UAAU,cAAc,UAAU,QAAQ;;;;;CAMjE,MAAM,kBAAoC;AAExC,SAAO,MADS,KAAK,YAAY,CACZ,iBAAiB;;;;;CAMxC,MAAM,eAAgC;AAEpC,SAAO,MADS,KAAK,YAAY,CACZ,cAAc;;;;;CAMrC,MAAM,UAAU,OAAc,SAAuC;AAEnE,SAAO,MADS,KAAK,YAAY,CACZ,UAAU,OAAO,QAAQ;;;;;CAMhD,oBAAoC;AAElC,SADgB,KAAK,YAAY,CAClB,mBAAmB;;;;;CAMpC,kBAAkB,SAAwB;AAExC,EADgB,KAAK,YAAY,CACzB,kBAAkB,QAAQ;;;;;CAMpC,aAAsB;AAEpB,SADgB,KAAK,YAAY,CAClB,YAAY;;;;;CAM7B,qBAA2B;AAEzB,EADgB,KAAK,YAAY,CACzB,oBAAoB;;;;;CAM9B,MAAM,iBAAmC;AACvC,SAAO,KAAK,iBAAiB;;;;;;CAO/B,MAAM,oBAAoB,UAAoC;AAE5D,SAAO,MADS,KAAK,YAAY,CACZ,oBAAoB,SAAS;;;;;;;;CASpD,MAAM,qBAAqB,UAAkB,iBAA+C;AAE1F,SAAO,MADS,KAAK,YAAY,CACZ,qBAAqB,UAAU,gBAAgB;;;;;CAMtE,sBAAmG;AAEjG,SADgB,KAAK,YAAY,CAClB,qBAAqB;;;;;;AC1LxC,MAAa,kBAAkB;AAC/B,MAAM,eAAe;AAErB,MAAa,kBAAkB,SAA0B;CACvD,MAAM,UAAU,KAAK,MAAM;AAC3B,QACE,QAAQ,SAAS,KACjB,QAAQ,UAAU,mBAClB,aAAa,KAAK,QAAQ;;AAI9B,MAAa,iBAAiB,WAC5B,OAAO,WAAW,MAAM,iBAAiB,KAAK,OAAO;AAWvD,MAAa,mBAAmB,QAAyB;AACvD,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,SAAO,CAAC,OAAO,OAAO,CAAC,SAAS,OAAO,SAAS,IAAI,OAAO,SAAS,SAAS;SACvE;AACN,SAAO;;;;;;;;;ACpBX,IAAa,eAAb,MAA0B;CASxB,YAAY,SAA6B,EAAE,EAAE;oBARL;uBAEhB,CAAC,uBAAuB;+BACP;mCACI;8BACL;sCACR,IAAI,KAAqB;AAGvD,OAAK,YAAY,KAAK,kBAAkB,OAAO,aAAa,KAAK,cAAc;;;;;CAMjF,WAAW,YAA8B;AACvC,OAAK,aAAa;AAElB,MAAI,cAAc,eAAe,cAAc,OAAO,WAAW,cAAc,WAC7E,CAAC,WAAmB,UAAU,KAAK,UAAU;;;;;CAOjD,UAAU,MAAsB;AAC9B,OAAK,YAAY,KAAK,kBAAkB,KAAK;AAC7C,MAAI,KAAK,cAAc,eAAe,KAAK,cAAc,OAAO,KAAK,WAAW,cAAc,WAC5F,CAAC,KAAK,WAAmB,UAAU,KAAK,UAAU;;;;;CAOtD,YAAsB;AACpB,SAAO,CAAC,GAAG,KAAK,UAAU;;;;;CAM5B,MAAM,aAAa,OAAc,YAAY,KAAwB;AACnE,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,KAAK,iBAAiB,WAAW,KAAK,qBAAqB;AACjE,SAAO,IAAI,SAAS,SAAS,WAAW;AACtC,OAAI,KAAK,UAAU,WAAW,GAAG;AAC/B,2BAAO,IAAI,MAAM,uBAAuB,CAAC;AACzC;;GAKF,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,YAAY,YAAY;AAC3D,2BAAO,IAAI,MAAM,6CAA6C,CAAC;AAC/D;;GAEF,MAAM,eAAe,WAAW,QAAQ,MAAM,CAAC,UAAU;IACvD,OAAO,aAAkB;AACvB,SAAI,UAAU,SAAS,MAAM;AAC3B,mBAAa,aAAa;AAC1B,cAAQ,KAAK;;;IAGjB,QAAQ,UAAiB;AACvB,kBAAa,aAAa;AAC1B,YAAO,MAAM;;IAEhB,CAAC;AAGF,oBAAiB;AACf,iBAAa,aAAa;AAC1B,YAAQ,MAAM;MACb,UAAU;IACb;;;;;CAMJ,MAAM,aAAa,QAAiD;AAClE,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,KAAK,iBAAiB,iBAAiB,KAAK,0BAA0B;AAC5E,SAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,SAAS;IACb,OAAO,CAAC,EAAE;IACV,SAAS,CAAC,OAAO;IACjB,OAAO;IACR;GAED,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,UAAU,YAAY;AACzD,YAAQ,KAAK;AACb;;GAEF,MAAM,eAAe,WAAW,MAAM,OAAO,CAAC,UAAU;IACtD,OAAO,WAAgB;AACrB,SAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,GAAG;MAC5C,MAAM,WAAW,KAAK,qBAAqB,OAAO,MAAM,QAAQ;AAChE,UAAI,UAAU;AACZ,oBAAa,aAAa;AAC1B,eAAQ,SAAS;AACjB;;AAEF,cAAQ,MAAM,mCAAmC;;;IAGrD,gBAAgB;AACd,kBAAa,aAAa;AAC1B,aAAQ,KAAK;;IAEf,QAAQ,UAAiB;AACvB,aAAQ,MAAM,2BAA2B,MAAM;AAC/C,kBAAa,aAAa;AAC1B,aAAQ,KAAK;;IAEhB,CAAC;AAGF,oBAAiB;AACf,iBAAa,aAAa;AAC1B,YAAQ,KAAK;MACZ,IAAK;IACR;;;;;CAMJ,MAAM,oBAAoB,QAAwC;AAChE,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,KAAK,iBAAiB,kBAAkB,KAAK,0BAA0B;AAC7E,SAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,SAAS;IACb,OAAO,CAAC,EAAE;IACV,SAAS,CAAC,OAAO;IACjB,OAAO;IACR;GAED,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,UAAU,YAAY;AACzD,YAAQ,KAAK;AACb;;GAEF,MAAM,eAAe,WAAW,MAAM,OAAO,CAAC,UAAU;IACtD,OAAO,WAAgB;AACrB,SAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,GAAG;MAC5C,MAAM,OAAO,OAAO,MAAM,QAAQ,EAAE;AACpC,WAAK,MAAM,OAAO,KAChB,KAAI,IAAI,OAAO,UAAU,IAAI,IAAI;OAC/B,MAAM,YAAY,IAAI,GAAG,MAAM;AAC/B,WAAI,eAAe,UAAU,EAAE;AAC7B,qBAAa,aAAa;AAC1B,gBAAQ,UAAU;AAClB;;;AAIN,mBAAa,aAAa;AAC1B,cAAQ,KAAK;;;IAGjB,gBAAgB;AACd,kBAAa,aAAa;AAC1B,aAAQ,KAAK;;IAEf,QAAQ,UAAiB;AACvB,aAAQ,MAAM,oCAAoC,MAAM;AACxD,kBAAa,aAAa;AAC1B,aAAQ,KAAK;;IAEhB,CAAC;AAEF,oBAAiB;AACf,iBAAa,aAAa;AAC1B,YAAQ,KAAK;MACZ,IAAK;IACR;;;;;CAMJ,MAAM,gBAAgB,QAAwC;AAC5D,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,KAAK,iBAAiB,qBAAqB,KAAK,0BAA0B;AAChF,SAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,SAAS;IACb,OAAO,CAAC,EAAE;IACV,SAAS,CAAC,OAAO;IACjB,OAAO;IACR;GAED,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,UAAU,YAAY;AACzD,YAAQ,EAAE,CAAC;AACX;;GAEF,MAAM,eAAe,WAAW,MAAM,OAAO,CAAC,UAAU;IACtD,OAAO,WAAgB;AACrB,SAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,GAAG;MAC5C,MAAM,aAA4B,EAAE;MACpC,MAAM,OAAO,OAAO,MAAM,QAAQ,EAAE;AAEpC,WAAK,MAAM,OAAO,KAChB,KAAI,IAAI,OAAO,OAAO,IAAI,GACxB,YAAW,KAAK;OACd,QAAQ,IAAI;OACZ,OAAO,IAAI,MAAM;OACjB,SAAS,IAAI,MAAM;OACpB,CAAC;AAIN,mBAAa,aAAa;AAC1B,cAAQ,WAAW;;;IAGvB,gBAAgB;AACd,kBAAa,aAAa;AAC1B,aAAQ,EAAE,CAAC;;IAEb,QAAQ,UAAiB;AACvB,aAAQ,MAAM,+BAA+B,MAAM;AACnD,kBAAa,aAAa;AAC1B,aAAQ,EAAE,CAAC;;IAEd,CAAC;AAEF,oBAAiB;AACf,iBAAa,aAAa;AAC1B,YAAQ,EAAE,CAAC;MACV,IAAM;IACT;;;;;CAMJ,MAAM,sBAAsB,SAA0D;AACpF,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,MAAI,QAAQ,WAAW,EACrB,wBAAO,IAAI,KAAK;AAGlB,QAAM,KAAK,iBAAiB,2BAA2B,KAAK,0BAA0B;AACtF,SAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,2BAAW,IAAI,KAA8B;GACnD,MAAM,SAAS;IACb,OAAO,CAAC,EAAE;IACV,SAAS;IACV;GAED,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,UAAU,YAAY;AACzD,4BAAQ,IAAI,KAAK,CAAC;AAClB;;GAEF,MAAM,eAAe,WAAW,MAAM,OAAO,CAAC,UAAU;IACtD,OAAO,WAAgB;AACrB,SAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,QAAQ;MACnE,MAAM,WAAW,KAAK,qBAAqB,OAAO,MAAM,QAAQ;AAChE,UAAI,SACF,UAAS,IAAI,OAAO,MAAM,QAAQ,SAAS;UAE3C,SAAQ,MAAM,mCAAmC;;;IAIvD,gBAAgB;AACd,kBAAa,aAAa;AAC1B,aAAQ,SAAS;;IAEnB,QAAQ,UAAiB;AACvB,aAAQ,MAAM,4BAA4B,MAAM;AAChD,kBAAa,aAAa;AAC1B,aAAQ,SAAS;;IAEpB,CAAC;AAEF,oBAAiB;AACf,iBAAa,aAAa;AAC1B,YAAQ,SAAS;MAChB,IAAK;IACR;;;;;;CAOJ,MAAM,cAAc,UAAoB,EAAE,EAAE,QAAQ,KAA4C;AAC9F,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,KAAK,iBAAiB,kBAAkB,KAAK,0BAA0B;AAC7E,SAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,2BAAW,IAAI,KAA+D;GACpF,MAAM,SAAc;IAClB,OAAO,CAAC,EAAE;IACV;IACD;AAED,OAAI,QAAQ,SAAS,EACnB,QAAO,UAAU;GAGnB,MAAM,aAAa,KAAK;AACxB,OAAI,CAAC,cAAc,OAAO,WAAW,UAAU,YAAY;AACzD,4BAAQ,IAAI,KAAK,CAAC;AAClB;;GAEF,MAAM,eAAe,WAAW,MAAM,OAAO,CAAC,UAAU;IACtD,OAAO,WAAgB;AACrB,SAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,QAAQ;MACnE,MAAM,WAAW,KAAK,qBAAqB,OAAO,MAAM,QAAQ;AAChE,UAAI,UAAU;OACZ,MAAM,YAAY,OAAO,MAAM,cAAc;OAC7C,MAAM,WAAW,SAAS,IAAI,OAAO,MAAM,OAAO;AAClD,WAAI,CAAC,YAAY,YAAY,SAAS,UACpC,UAAS,IAAI,OAAO,MAAM,QAAQ;QAAE;QAAU;QAAW,CAAC;YAG5D,SAAQ,MAAM,mCAAmC;;;IAIvD,gBAAgB;AACd,kBAAa,aAAa;KAC1B,MAAM,yBAAS,IAAI,KAA8B;AACjD,cAAS,SAAS,OAAO,WAAW;AAClC,aAAO,IAAI,QAAQ,MAAM,SAAS;OAClC;AACF,aAAQ,OAAO;;IAEjB,QAAQ,UAAiB;AACvB,aAAQ,MAAM,4BAA4B,MAAM;AAChD,kBAAa,aAAa;KAC1B,MAAM,yBAAS,IAAI,KAA8B;AACjD,cAAS,SAAS,OAAO,WAAW;AAClC,aAAO,IAAI,QAAQ,MAAM,SAAS;OAClC;AACF,aAAQ,OAAO;;IAElB,CAAC;AAEF,oBAAiB;AACf,iBAAa,aAAa;IAC1B,MAAM,yBAAS,IAAI,KAA8B;AACjD,aAAS,SAAS,OAAO,WAAW;AAClC,YAAO,IAAI,QAAQ,MAAM,SAAS;MAClC;AACF,YAAQ,OAAO;MACd,IAAM;IACT;;;;;CAMJ,MAAM,kBACJ,QACA,YACA,WACkB;EAClB,MAAM,OAAmB,WAAW,KAAK,UAAU;AACjD,OAAI,CAAC,cAAc,MAAM,OAAO,CAC9B,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAI,MAAM,SAAS,CAAC,gBAAgB,MAAM,MAAM,CAC9C,OAAM,IAAI,MAAM,kDAAkD;GAEpE,MAAM,MAAgB,CAAC,KAAK,MAAM,OAAO;AACzC,OAAI,MAAM,MACR,KAAI,KAAK,MAAM,MAAM;AAEvB,OAAI,MAAM,QACR,KAAI,KAAK,MAAM,QAAQ;AAEzB,UAAO;IACP;EASF,MAAM,cAAc,MAAM,UAPL;GACnB,MAAM;GACN,SAAS;GACT,YAAY,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GACzC;GACD,CAEyC;AAC1C,SAAO,MAAM,KAAK,aAAa,YAAY;;CAG7C,AAAQ,kBAAkB,MAA0B;AAClD,MAAI,KAAK,WAAW,EAClB,QAAO,EAAE;EAEX,MAAM,YAAY,KAAK,QAAQ,QAAQ,gBAAgB,IAAI,CAAC;AAC5D,MAAI,UAAU,WAAW,KAAK,OAC5B,OAAM,IAAI,MAAM,2BAA2B;AAE7C,SAAO;;CAGT,AAAQ,qBAAqB,SAAyC;AACpE,MAAI,QAAQ,SAAS,KAAK,sBACxB,QAAO;AAET,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,OAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,QAAO;GAET,MAAM,WAA4B,EAAE;AACpC,OAAI,OAAQ,OAA2B,SAAS,SAC9C,UAAS,OAAQ,OAA2B;AAE9C,OAAI,OAAQ,OAA2B,iBAAiB,SACtD,UAAS,eAAgB,OAA2B;AAEtD,OAAI,OAAQ,OAA2B,UAAU,SAC/C,UAAS,QAAS,OAA2B;AAE/C,OAAI,OAAQ,OAA2B,YAAY,SACjD,UAAS,UAAW,OAA2B;AAEjD,OAAI,OAAQ,OAA2B,YAAY,SACjD,UAAS,UAAW,OAA2B;AAEjD,UAAO;WACA,OAAO;AACd,WAAQ,MAAM,qCAAqC,MAAM;AACzD,UAAO;;;CAIX,MAAc,iBAAiB,QAAgB,eAAsC;EACnF,MAAM,SAAS,KAAK,aAAa,IAAI,OAAO,IAAI;EAEhD,MAAM,SAAS,iBADH,KAAK,KAAK,GACgB;AACtC,MAAI,SAAS,EACX,OAAM,IAAI,SAAS,YAAY,WAAW,SAAS,OAAO,CAAC;AAE7D,OAAK,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ns-auth-sdk",
3
- "version": "1.12.0",
3
+ "version": "1.12.2",
4
4
  "description": "Decentralized SSO library - Authentication, membership, and profile management",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",