@lightninglabs/lnc-web
Version:
Lightning Node Connect npm module for web
96 lines • 3.62 kB
TypeScript
import { UnlockMethod, UnlockOptions } from '../types/lightningNodeConnect';
import { EncryptionService } from './encryptionService';
/**
* Pure passkey-based encryption service using WebAuthn PRF extension.
* No storage dependencies - just crypto operations.
*
* Encryption strategy:
* 1. User authenticates with their passkey (biometric/PIN)
* 2. WebAuthn PRF extension returns a deterministic secret from the authenticator
* 3. HKDF derives an AES-256-GCM key from the PRF output
* 4. Data is encrypted with AES-GCM using random 96-bit IVs
*
* The encryption key only exists in memory while unlocked and cannot be
* extracted - it requires the physical authenticator to re-derive.
*/
export declare class PasskeyEncryptionService implements EncryptionService {
private isUnlockedState;
private encryptionKey?;
private credentialId?;
private namespace;
private displayName;
constructor(namespace: string, displayName?: string);
/**
* Get the unlock method handled by this service (`passkey`).
*/
get method(): UnlockMethod;
/**
* Returns true when a derived encryption key is available and the
* service is marked as unlocked.
*/
get isUnlocked(): boolean;
/**
* Encrypt a plaintext string using the derived passkey-backed AES key.
* Throws if the service has not been unlocked.
*/
encrypt(data: string): Promise<string>;
/**
* Decrypt a ciphertext string using the derived passkey-backed AES key.
* Throws if the service has not been unlocked.
*/
decrypt(data: string): Promise<string>;
/**
* Unlock the service using an existing passkey credential or by creating
* a new one (when `createIfMissing` is true) and derive the encryption key.
*/
unlock(options: UnlockOptions): Promise<void>;
/**
* Clear in-memory encryption key and credential ID and reset the
* unlocked state.
*/
lock(): void;
/**
* Return true if this service can handle the provided unlock method.
*/
canHandle(method: UnlockMethod): boolean;
/**
* Get the current credential ID (for storage by repository)
*/
getCredentialId(): string;
/**
* Check if passkeys are supported in the current environment
*/
static isSupported(): Promise<boolean>;
/**
* Create a new WebAuthn passkey credential and derive an encryption key
* from its PRF extension output.
*/
private createNewPasskey;
/**
* Use an existing WebAuthn passkey credential to perform an assertion
* and derive an encryption key from its PRF extension output.
*/
private authenticateWithExistingPasskey;
/**
* Derive an AES-GCM encryption key from the PRF output using HKDF.
*
* HKDF parameters:
* - keyMaterial: PRF output (secret from authenticator)
* - salt: Challenge bytes (adds randomness)
* - info: Namespace (domain separation)
*
* Flow: passkey auth → PRF output → HKDF → AES-256-GCM key
*/
private deriveEncryptionKey;
/**
* Generate a deterministic challenge based on the namespace.
* This ensures the same PRF challenge is used across sessions for
* consistent key derivation.
*
* Uses SHA-256 to derive the challenge from the namespace. This provides
* uniform byte distribution and proper cryptographic mixing, ensuring the
* challenge cannot be trivially predicted or reversed from the namespace.
*/
private generateDeterministicChallenge;
}
//# sourceMappingURL=passkeyEncryptionService.d.ts.map