AppStateBackup
Coordinates PRF-encrypted backup and restore of app-specific state (e.g. Kicks's MatchStore witnesses + commitments, BBoard drafts, future game/agent state).
Why "AppState" and not "Sigil": the wallet seed and the sigil DID both derive from the user's passkey via PRF (see WalletSeedSource and SigilIdentityProvider). Neither needs to travel through a Block Store blob to survive a new device — the passkey carries them. What can't be re-derived from the passkey is per-app state that's accumulated mid-session: witness keys paired to a deployed contract, draft data, in-flight game moves. That's what this class persists.
Flow:
Authenticate passkey with
BACKUP_SALT→ 32-byte PRF output.HKDF(PRF output) → AES-256-GCM key.
Encrypt
appMetadata→ versioned blob.Store blob in BackupStorage (Block Store by default).
Restore (new device or sign-in flow):
Passkey syncs via Google Password Manager.
Authenticate with the same salt → same PRF output → same AES key.
Decrypt blob → RestoredAppState.appMetadata handed to the host.
Security: intermediate key material (PRF output, AES key, plaintext) is wiped in finally blocks immediately after use. Google sees only an opaque encrypted blob.
Versioning: the blob's leading byte is the schema version. v2 is the post-PRF format (this class); v1 blobs from before the AppStateBackup extraction are silently rejected as "no backup" — the seed and sigil fields they carried are redundant now, and the appMetadata they carried isn't decryptable under the v2 schema.
Functions
Encrypts appMetadata and writes the blob to storage.
Delete the backup.
Whether the storage backend is available.
Reads + decrypts the app-state blob from storage.