import Foundation enum Chain: String, Codable, CaseIterable { case xrp case xmr var symbol: String { self == .xrp ? "XRP" : "XMR" } var title: String { self == .xrp ? "XRP Ledger" : "Monero" } var subtitle: String { self == .xrp ? "Fast, low-fee payments" : "Private, untraceable payments" } } struct WalletRecord: Codable, Identifiable, Equatable { let id: String var name: String var address: String var createdAt: Date } enum Direction: String, Codable { case incoming case outgoing } struct TransactionRecord: Identifiable, Codable { let id: String let amount: String let timestamp: Date? let direction: Direction let confirmed: Bool var fee: String? var tag: Int? var counterparty: String? var confirmations: UInt64? var height: UInt64? var paymentId: String? var accountIndex: Int? var subaddressIndex: Int? var note: String? var weight: UInt64? var ledgerIndex: UInt64? var sequence: UInt64? } struct Balance: Codable { var total: String var unlocked: String var funded: Bool } /// Persisted per chain so a switch or relaunch shows the last-known state /// instantly while the network catches up. struct ChainCache: Codable { var balance: Balance var transactions: [TransactionRecord] var accounts: [MoneroAccount]? var savedAt: Date } struct SyncStatus { var height: UInt64 var daemonHeight: UInt64 var syncing: Bool var connected: Bool var progress: Double { guard daemonHeight > 0 else { return 0 } return min(1, Double(height) / Double(daemonHeight)) } } enum TransactionPriority: Int { case defaultPriority = 0 case low = 1 case medium = 2 case high = 3 var label: String { switch self { case .defaultPriority: return "Default" case .low: return "Low" case .medium: return "Medium" case .high: return "High" } } } struct MoneroSubaddress: Identifiable, Codable { let accountIndex: Int let index: Int let address: String let label: String let balance: String let unlocked: String let isUsed: Bool var id: String { "\(accountIndex)/\(index)" } } struct MoneroAccount: Identifiable, Codable { let index: Int let address: String let balance: String let unlocked: String var subaddresses: [MoneroSubaddress] var id: Int { index } var title: String { index == 0 ? "Primary account" : "Account \(index + 1)" } }