import type { Store } from "@tanstack/store"; import { clearKeyData, decryptWithKeyData, encryptWithKeyData, } from "./crypto.ts"; import { signWithKeyData } from "./sign.ts"; import type { Key, KeyData, KeyId, KeyStoreState } from "./types/index.ts"; import { verifyWithKeyData } from "./verify.ts"; /** * Adds a key to the reactive store. * * @param store - The TanStack store instance for {@link KeyStoreState}. * @param key - The {@link Key} metadata to add. */ export function addKey(store: Store, key: Key): void { store.setState((s) => ({ ...s, keys: [...s.keys, key] })); } /** * Removes a key from the reactive store by its ID. * * @param params - The removal parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.keyId - The {@link KeyId} of the key to remove. */ export function removeKey({ store, keyId, }: { store: Store; keyId: KeyId; }): void { store.setState((s) => ({ ...s, keys: s.keys.filter((k) => k.id !== keyId) })); } /** * Sets the current status of the keystore. * * @param params - The status parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.status - A string representing the current operation (e.g., "signing", "generating", "idle"). */ export function setStatus({ store, status, }: { store: Store; status: string; }): void { store.setState((s) => ({ ...s, status })); } /** * Clears all keys from the store and resets status to "idle". * * @param params - The store parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. */ export function clearKeyStore({ store, }: { store: Store; }): void { store.setState({ keys: [], status: "idle" }); } /** * Retrieves a key from the store by its ID. * * @param params - The retrieval parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.id - The {@link KeyId} of the key to retrieve. * @returns The {@link Key} metadata if found, otherwise undefined. */ export function getKey({ store, id, }: { store: Store; id: KeyId; }): Key | undefined { return store.state.keys.find((k) => k.id === id); } /** * Initializes the keystore with a list of keys and sets status to "idle". * * @param params - The initialization parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.keys - The array of {@link Key} metadata to initialize with. */ export function initializeKeyStore({ store, keys, }: { store: Store; keys: Key[]; }): void { store.setState({ keys, status: "idle" }); } /** * Encrypts data using the provided key data. * * @param params - The encryption parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.key - The {@link KeyData} containing the secret key. * @param params.data - The data to encrypt. * @param params.algorithm - Optional algorithm to use. * @returns A promise that resolves to the encrypted data. */ export async function encrypt({ store, key, data, algorithm, }: { store: Store; key: KeyData; data: Uint8Array; algorithm?: string; }): Promise { setStatus({ store, status: "encrypting" }); try { return encryptWithKeyData({ key, data, algorithm }); } finally { clearKeyData(key); setStatus({ store, status: "idle" }); } } /** * Decrypts data using the provided key data. * * @param params - The decryption parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.key - The {@link KeyData} containing the secret key. * @param params.data - The data to decrypt. * @param params.algorithm - Optional algorithm to use. * @returns A promise that resolves to the decrypted data. */ export async function decrypt({ store, key, data, }: { store: Store; key: KeyData; data: Uint8Array; algorithm?: string; }): Promise> { setStatus({ store, status: "decrypting" }); try { return decryptWithKeyData({ key, data }); } finally { clearKeyData(key); setStatus({ store, status: "idle" }); } } /** * Verifies a signature using the provided key data. * * @param params - The verification parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.key - The {@link KeyData} containing the public key. * @param params.data - The data that was signed. * @param params.signature - The signature to verify. * @param params.algorithm - Optional algorithm to use. * @returns A promise that resolves to true if the signature is valid, false otherwise. */ export async function verify({ store, key, data, signature, }: { store: Store; key: KeyData; data: Uint8Array; signature: Uint8Array; algorithm?: string; }): Promise { setStatus({ store, status: "verifying" }); try { return verifyWithKeyData({ key, data, signature }); } finally { clearKeyData(key); setStatus({ store, status: "idle" }); } } /** * Signs data using the provided key data. * * @param params - The signing parameters. * @param params.store - The TanStack store instance for {@link KeyStoreState}. * @param params.key - The {@link KeyData} containing the private key. * @param params.parentKey - Optional parent key data for HD derivation. * @param params.data - The data to sign. * @param params.algorithm - Optional algorithm to use. * @returns A promise that resolves to the signature. */ export async function sign({ store, key, parentKey, data, }: { store: Store; key: KeyData; parentKey?: KeyData; data: Uint8Array; algorithm?: string; }): Promise { setStatus({ store, status: "signing" }); try { return signWithKeyData({ key, data, parentKey }); } finally { clearKeyData(key); clearKeyData(parentKey); setStatus({ store, status: "idle" }); } }