SigilPanelViewModel

class SigilPanelViewModel @Inject constructor(context: Context, passkeyManager: PasskeyManager, sigilIdentityProvider: SigilIdentityProvider, sigilSession: SigilSession, sigilStateStore: SigilStateStore, appStateBackup: AppStateBackup, blockStoreStorage: BlockStoreBackupStorage, appDataProvider: Optional<AppDataBackupProvider>) : ViewModel

Self-contained sigil-identity bookkeeper for SigilStatusPanel.

Owns three flows:

  • Forge (forgeSigil): create a passkey via Credential Manager, then derive the sigil DID via SigilIdentityProvider (PRF(passkey, SIGIL_SALT) → Ed25519 → did:key:z6Mk… in the default impl). Two biometric prompts on first run.

  • Sign in (restoreSeed): one biometric covers BOTH the sigil DID derivation AND the wallet seed pre-warm via the multi-salt PRF ceremony in SigilSession.signIn. The wallet panel's first refresh after sign-in hits SeedVault cache instead of running its own PRF ceremony — no second prompt. Falls back to two biometrics on authenticators that don't support multi-salt PRF. Optionally restores host-app state via AppStateBackup after the sigil is forged.

  • Backup (backupSeed): write host-app state (not the seed) to Block Store via AppStateBackup.

Held in BBoard's VM (not migrated):

  • authorizeAccessKey — needs a MidnightSdk instance to derive the access key being authorized. The host bridges sigil + wallet for that flow.

Constructors

Link copied to clipboard
@Inject
constructor(context: Context, passkeyManager: PasskeyManager, sigilIdentityProvider: SigilIdentityProvider, sigilSession: SigilSession, sigilStateStore: SigilStateStore, appStateBackup: AppStateBackup, blockStoreStorage: BlockStoreBackupStorage, appDataProvider: Optional<AppDataBackupProvider>)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
val status: StateFlow<SigilStatus>

Functions

Link copied to clipboard
open fun addCloseable(closeable: AutoCloseable)
fun addCloseable(key: String, closeable: AutoCloseable)
Link copied to clipboard

Back up the current sigil identity + the locally-stored seed to Google Block Store. Pipeline: load seed via seedVault (biometric) → derive a PRF-encrypted AES key from the passkey → sigilBackup.backup uploads the encrypted blob.

Link copied to clipboard

User chose "Start fresh" from the SigilStatus.BackupAvailable prompt: they acknowledge the cloud backup but want to proceed without restoring. Persist a flag so future launches don't keep nagging, and move to SigilStatus.None so the wallet panel unblocks and auto-bootstraps a fresh wallet.

Link copied to clipboard

Create a passkey + derive its did:key. Triggers the platform's Credential Manager UI on activity; the user picks an authenticator (device biometric / hardware key / etc.) and authorizes the create.

Link copied to clipboard
Link copied to clipboard

Diagnostic — derive the SeedDeriver PRF output for the user's passkey and emit the 32-byte hex to logcat (tag PrfProbe). Used to verify that PRF is deterministic across Kuira ecosystem apps that share an RP via assetlinks.json, before relying on it as the wallet seed.

Link copied to clipboard

Sign in with an existing passkey — the post-PRF replacement for the old "restore from cloud" flow.

Link copied to clipboard
fun testPrf(activity: Activity)

Probe the passkey's PRF extension. Builds a deterministic salt from a versioned purpose string, runs an assertion twice with the same salt, and reports whether the outputs match — used during canary to confirm an authenticator supports CTAP2's hmac-secret extension before relying on it for backup.