import type { IdentityKeyPair, SignedPreKey, OneTimePreKey, SessionState } from './types.js'; /** A retired identity kept in history during the rotation grace period */ export interface RetiredIdentity { keyPair: IdentityKeyPair; retiredAt: number; } /** * Persisted stream-transfer resume record. Holds enough state for either * side of a transfer to resume after restart. The `streamSecret` MUST be * encrypted before storage (see `@shade/transfer` for the deviceKey-based * AES-GCM at-rest scheme). */ export interface PersistedStreamState { streamId: string; direction: 'send' | 'receive'; peerAddress: string; status: 'active' | 'paused' | 'finished' | 'aborted'; /** JSON-serialized `StreamMetadata`. */ metadataJson: string; /** JSON-serialized `LaneInitSpec[]`. */ partitionJson: string; /** JSON-serialized per-lane progress array (laneId/nextSeq/bytesProcessed). */ laneStateJson: string; /** JSON-serialized I/O descriptor (file path / file handle reference / buffer). */ ioDescriptorJson: string; /** AES-GCM-encrypted streamSecret (under deviceKey). */ secretEnc: Uint8Array; /** AES-GCM nonce used for `secretEnc`. */ secretNonce: Uint8Array; /** * Reserved for future hasher serialization. Empty in v0.2.0; resume * re-hashes received bytes from disk. */ overallHashState?: string; createdAt: number; updatedAt: number; } /** * StorageProvider — abstract interface for persisting cryptographic state. * * Implementations per platform: * - In-memory (testing) * - IndexedDB (browser) * - SQLite/PostgreSQL (server) * - EncryptedSharedPreferences (Android) */ export interface StorageProvider { // ─── Identity ────────────────────────────────────────────── /** Get our local identity keypair, or null if not yet generated */ getIdentityKeyPair(): Promise; /** Persist our local identity keypair */ saveIdentityKeyPair(keyPair: IdentityKeyPair): Promise; /** Get our local registration ID (unique per installation) */ getLocalRegistrationId(): Promise; /** Save our local registration ID */ saveLocalRegistrationId(id: number): Promise; // ─── Signed Pre-Keys ────────────────────────────────────── /** Get a signed prekey by ID */ getSignedPreKey(keyId: number): Promise; /** Persist a signed prekey */ saveSignedPreKey(key: SignedPreKey): Promise; /** Remove a signed prekey (after rotation grace period) */ removeSignedPreKey(keyId: number): Promise; // ─── One-Time Pre-Keys ──────────────────────────────────── /** Get a one-time prekey by ID */ getOneTimePreKey(keyId: number): Promise; /** Persist a one-time prekey */ saveOneTimePreKey(key: OneTimePreKey): Promise; /** Remove a consumed one-time prekey */ removeOneTimePreKey(keyId: number): Promise; /** Count remaining one-time prekeys */ getOneTimePreKeyCount(): Promise; // ─── Sessions ───────────────────────────────────────────── /** Get session state for a peer address (e.g. "device:abc123") */ getSession(address: string): Promise; /** Persist session state for a peer */ saveSession(address: string, state: SessionState): Promise; /** Remove session for a peer */ removeSession(address: string): Promise; /** Check if we trust a remote identity key (for TOFU or pinned keys) */ isTrustedIdentity(address: string, identityKey: Uint8Array): Promise; /** Save a trusted remote identity key */ saveTrustedIdentity(address: string, identityKey: Uint8Array): Promise; // ─── Identity History (rotation with grace period) ────── /** Add an identity to the retired history */ addRetiredIdentity(identity: RetiredIdentity): Promise; /** Get all retired identities (for grace-period decryption) */ getRetiredIdentities(): Promise; /** Remove retired identities older than the given timestamp */ pruneRetiredIdentities(olderThan: number): Promise; // ─── Stream-transfer resume state (optional, added in v0.2.0) ── /** * Persist or update the stream-state row for a given streamId. Idempotent: * upserts on `streamId`. Optional — providers that don't support resume * can omit this and consumers will fall back to in-memory state. */ saveStreamState?(state: PersistedStreamState): Promise; /** Look up the stream-state row by streamId. Returns null if absent. */ getStreamState?(streamId: string): Promise; /** Remove a stream-state row (e.g. on completion or abort). */ removeStreamState?(streamId: string): Promise; /** List active or paused stream-state rows (for resume on startup). */ listActiveStreamStates?( direction?: 'send' | 'receive', ): Promise; /** Prune stream-state rows in `'finished' | 'aborted'` status older than `olderThan`. */ pruneStreamStates?(olderThan: number): Promise; }