69 lines
2.4 KiB
Swift
69 lines
2.4 KiB
Swift
import Foundation
|
||
import SwiftUI
|
||
|
||
/// Минимальный держатель identity для первой итерации.
|
||
/// Полные derived keys (ML-DSA + ML-KEM) — Phase 2 (FFI к Rust).
|
||
struct Identity: Equatable {
|
||
let masterSeed: Data
|
||
let accountIdHex: String
|
||
let mnemonic: String?
|
||
}
|
||
|
||
@MainActor
|
||
final class IdentityManager: ObservableObject {
|
||
@Published private(set) var identity: Identity?
|
||
|
||
private let storageKey = "MontanaIdentity_v1"
|
||
|
||
init() {}
|
||
|
||
/// Загрузить existing identity из Keychain (если есть).
|
||
func loadIfPresent() {
|
||
guard let data = KeychainStore.read(key: storageKey),
|
||
let stored = try? JSONDecoder().decode(StoredIdentity.self, from: data) else {
|
||
return
|
||
}
|
||
identity = Identity(
|
||
masterSeed: stored.masterSeed,
|
||
accountIdHex: stored.accountIdHex,
|
||
mnemonic: nil
|
||
)
|
||
}
|
||
|
||
/// Создать новую identity из случайной мнемоники.
|
||
func createNew() throws -> String {
|
||
let mnemonic = Mnemonic.generate()
|
||
try install(mnemonic: mnemonic)
|
||
return mnemonic
|
||
}
|
||
|
||
/// Восстановить identity из существующей мнемоники.
|
||
func restore(from mnemonic: String) throws {
|
||
try install(mnemonic: mnemonic)
|
||
}
|
||
|
||
/// Стереть identity локально (для тестов / переустановки).
|
||
func wipe() {
|
||
KeychainStore.delete(key: storageKey)
|
||
identity = nil
|
||
}
|
||
|
||
private func install(mnemonic: String) throws {
|
||
let masterSeed = try Mnemonic.decodeAndDerive(mnemonic: mnemonic)
|
||
// Placeholder account_id = SHA-256("mt-account-placeholder" || masterSeed[0..16])
|
||
// Реальный account_id = SHA-256("mt-account" || pubkey_suite || ml_dsa_pubkey) — Phase 2
|
||
let accountIdHex = HashUtil.sha256Hex(prefix: "mt-account-placeholder", body: masterSeed.prefix(16))
|
||
|
||
let stored = StoredIdentity(masterSeed: masterSeed, accountIdHex: accountIdHex)
|
||
let data = try JSONEncoder().encode(stored)
|
||
KeychainStore.write(key: storageKey, value: data)
|
||
|
||
identity = Identity(masterSeed: masterSeed, accountIdHex: accountIdHex, mnemonic: mnemonic)
|
||
}
|
||
}
|
||
|
||
private struct StoredIdentity: Codable {
|
||
let masterSeed: Data
|
||
let accountIdHex: String
|
||
}
|