WalletSeedSource

@Singleton
class WalletSeedSource @Inject constructor(context: Context, seedVault: SeedVault, walletKeyManager: WalletKeyManager, passkeyManager: PasskeyManager, sigilStateStore: SigilStateStore)

Single source of truth for the wallet's BIP-39 seed.

Every Kuira ecosystem consumer that needs the seed — WalletPanelViewModel, BBoardViewModel, Kicks's MatchManager, future agent runtimes — injects this @Singleton and calls ensureSeedReady. They all observe the same seed, the same biometric prompt cadence, and the same dev override.

Bootstrap contract:

  1. Dev-seed escape hatch (debug only) — when local.properties defines kuira.dev.seed, decode + return without touching the vault or the passkey. See module-level KDoc in build.gradle.kts.

  2. Sigil gate — no passkey forged ⇒ SigilRequiredException. Consumers translate this to whatever UI affordance they own (WalletStatus.SigilRequired in the panel, a "forge sigil" screen in custom dApps, etc.). Throwing here is defense-in-depth — the host UI should also gate.

  3. Cache hit — SeedVault holds a seed AND the seedIsPrfDerived flag is set ⇒ biometric prompt to decrypt, return the cached PRF-derived seed.

  4. Cache miss OR legacy unflagged vault ⇒ wipe the legacy entry (decision B — legacy random seeds are abandoned, not migrated), run ONE passkey PRF authentication to derive the new seed, store in the vault, set the flag, return.

Caller MUST wipe the returned ByteArray once the SDK builder has copied it (typically in a finally block).

Constructors

Link copied to clipboard
@Inject
constructor(context: Context, seedVault: SeedVault, walletKeyManager: WalletKeyManager, passkeyManager: PasskeyManager, sigilStateStore: SigilStateStore)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
suspend fun acceptPreDerivedSeed(activity: FragmentActivity, prfEntropy: ByteArray): ByteArray

Pre-warm SeedVault with a PRF output the caller already derived in a multi-purpose ceremony — used by SigilSession to collapse "sign in + first wallet refresh" to one biometric.

Link copied to clipboard

Returns the wallet's BIP-39 seed, deriving it from the user's passkey via PRF if not already cached. See class-level KDoc for the full bootstrap contract.