docs: update BLOCKERS.md with Task 3 completion status
This commit is contained in:
parent
db4c262b27
commit
19637833a6
8 changed files with 1230 additions and 75 deletions
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2026 Sulkta Coop.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package io.element.android.features.wallet.api.storage
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
|
||||
/**
|
||||
* Result of wallet creation containing the generated seed phrase and derived addresses.
|
||||
*/
|
||||
data class WalletCreationResult(
|
||||
val mnemonic: List<String>,
|
||||
val baseAddress: String,
|
||||
val stakeAddress: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* Interface for secure storage and retrieval of Cardano wallet keys.
|
||||
*
|
||||
* Wallets are scoped PER SESSION (per Matrix account). Each [SessionId] can have
|
||||
* exactly one wallet associated with it.
|
||||
*
|
||||
* ## Security Properties
|
||||
* - Keys are stored encrypted using Android Keystore
|
||||
* - Biometric/PIN authentication required for every signing operation
|
||||
* - Keys are INVALIDATED if biometric enrollment changes
|
||||
* - Mnemonic is stored encrypted, never in plaintext
|
||||
*
|
||||
* ## Implementation Notes
|
||||
* - Use `setInvalidatedByBiometricEnrollment(true)` for Keystore keys
|
||||
* - Use `setUserAuthenticationRequired(true)` with duration -1 (every time)
|
||||
* - Key alias format: "cardano_wallet_{sessionId}"
|
||||
*/
|
||||
interface CardanoKeyStorage {
|
||||
/**
|
||||
* Checks if a wallet exists for the given session.
|
||||
*/
|
||||
suspend fun hasWallet(sessionId: SessionId): Boolean
|
||||
|
||||
/**
|
||||
* Generates a new wallet with a 24-word BIP-39 mnemonic.
|
||||
*
|
||||
* @param sessionId The Matrix session to create the wallet for
|
||||
* @return [WalletCreationResult] containing the mnemonic and derived addresses
|
||||
* @throws IllegalStateException if a wallet already exists for this session
|
||||
*/
|
||||
suspend fun generateWallet(sessionId: SessionId): Result<WalletCreationResult>
|
||||
|
||||
/**
|
||||
* Imports an existing wallet from a mnemonic phrase.
|
||||
*
|
||||
* @param sessionId The Matrix session to import the wallet for
|
||||
* @param mnemonic The BIP-39 mnemonic phrase (12, 15, 18, 21, or 24 words)
|
||||
* @return The derived base address on success
|
||||
* @throws IllegalArgumentException if the mnemonic is invalid
|
||||
* @throws IllegalStateException if a wallet already exists for this session
|
||||
*/
|
||||
suspend fun importWallet(sessionId: SessionId, mnemonic: List<String>): Result<String>
|
||||
|
||||
/**
|
||||
* Retrieves the encrypted mnemonic for backup display.
|
||||
*
|
||||
* ⚠️ WARNING: This returns sensitive data. UI must use FLAG_SECURE.
|
||||
*
|
||||
* @param sessionId The Matrix session
|
||||
* @return The mnemonic word list
|
||||
*/
|
||||
suspend fun getMnemonic(sessionId: SessionId): Result<List<String>>
|
||||
|
||||
/**
|
||||
* Gets the base address (payment + staking key hash) for the wallet.
|
||||
*
|
||||
* @param sessionId The Matrix session
|
||||
* @param addressIndex The address index (default 0)
|
||||
*/
|
||||
suspend fun getBaseAddress(sessionId: SessionId, addressIndex: Int = 0): Result<String>
|
||||
|
||||
/**
|
||||
* Gets the staking/reward address for the wallet.
|
||||
*
|
||||
* @param sessionId The Matrix session
|
||||
*/
|
||||
suspend fun getStakeAddress(sessionId: SessionId): Result<String>
|
||||
|
||||
/**
|
||||
* Permanently deletes the wallet and all associated key material.
|
||||
*
|
||||
* @param sessionId The Matrix session
|
||||
*/
|
||||
suspend fun deleteWallet(sessionId: SessionId): Result<Unit>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue