import type { StorageProvider, IdentityKeyPair, SignedPreKey, OneTimePreKey, SessionState } from '@shade/core'; /** * In-memory StorageProvider for testing and embedded use. * All data is lost when the instance is garbage collected. */ export class MemoryStorage implements StorageProvider { private identityKeyPair: IdentityKeyPair | null = null; private registrationId: number = 0; private signedPreKeys = new Map(); private oneTimePreKeys = new Map(); private sessions = new Map(); private trustedIdentities = new Map(); // ─── Identity ────────────────────────────────────────────── async getIdentityKeyPair(): Promise { return this.identityKeyPair; } async saveIdentityKeyPair(keyPair: IdentityKeyPair): Promise { this.identityKeyPair = keyPair; } async getLocalRegistrationId(): Promise { return this.registrationId; } async saveLocalRegistrationId(id: number): Promise { this.registrationId = id; } // ─── Signed Pre-Keys ────────────────────────────────────── async getSignedPreKey(keyId: number): Promise { return this.signedPreKeys.get(keyId) ?? null; } async saveSignedPreKey(key: SignedPreKey): Promise { this.signedPreKeys.set(key.keyId, key); } async removeSignedPreKey(keyId: number): Promise { this.signedPreKeys.delete(keyId); } // ─── One-Time Pre-Keys ──────────────────────────────────── async getOneTimePreKey(keyId: number): Promise { return this.oneTimePreKeys.get(keyId) ?? null; } async saveOneTimePreKey(key: OneTimePreKey): Promise { this.oneTimePreKeys.set(key.keyId, key); } async removeOneTimePreKey(keyId: number): Promise { this.oneTimePreKeys.delete(keyId); } async getOneTimePreKeyCount(): Promise { return this.oneTimePreKeys.size; } // ─── Sessions ───────────────────────────────────────────── async getSession(address: string): Promise { return this.sessions.get(address) ?? null; } async saveSession(address: string, state: SessionState): Promise { this.sessions.set(address, state); } async removeSession(address: string): Promise { this.sessions.delete(address); } // ─── Trust ──────────────────────────────────────────────── async isTrustedIdentity(address: string, identityKey: Uint8Array): Promise { const stored = this.trustedIdentities.get(address); if (!stored) return true; // TOFU: trust on first use return arraysEqual(stored, identityKey); } async saveTrustedIdentity(address: string, identityKey: Uint8Array): Promise { this.trustedIdentities.set(address, identityKey); } } function arraysEqual(a: Uint8Array, b: Uint8Array): boolean { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; }