import SwiftUI import CryptoKit /// Montana Private — Приватные кошельки и зашифрованные транзакции /// Zero-knowledge proof, stealth addresses, полная анонимность struct PrivateView: View { @EnvironmentObject var engine: PresenceEngine @State private var privateNickname = "" @State private var isPurchasing = false @State private var purchaseStatus = "" @State private var hasPrivateWallet = false @State private var privateBalance = 0 @State private var privateAddress = "" @State private var showSidebar = false // Montana colors (from website efir.org) private let gold = Color(red: 0.83, green: 0.69, blue: 0.22) // #D4AF37 private let goldLight = Color(red: 0.94, green: 0.82, blue: 0.38) // #F0D060 private let goldDark = Color(red: 0.55, green: 0.41, blue: 0.08) // #8B6914 private let bgDark = Color(red: 0.04, green: 0.04, blue: 0.04) // #0a0a0a private let textBeige = Color(red: 0.91, green: 0.88, blue: 0.82) // #e8e0d0 private let crimson = Color(red: 0.55, green: 0.10, blue: 0.10) // #8B1A1A var body: some View { ZStack(alignment: .leading) { VStack(spacing: 0) { // ── BURGER MENU BUTTON ── HStack { Button(action: { withAnimation(.easeInOut(duration: 0.3)) { showSidebar = true } }) { Image(systemName: "line.3.horizontal") .font(.system(size: 18, weight: .medium)) .foregroundColor(gold) .padding(8) } .buttonStyle(.plain) Spacer() } .padding(.horizontal, 12) .padding(.top, 8) // Header header Divider() // Main content ScrollView { VStack(spacing: 24) { if hasPrivateWallet { // Private wallet card privateWalletCard } else { // Purchase card purchaseCard } // Info section infoSection } .padding() } } .background(Color(NSColor.windowBackgroundColor)) .onAppear { loadPrivateWallet() } // Sidebar overlay if showSidebar { Color.black.opacity(0.3) .ignoresSafeArea() .onTapGesture { withAnimation(.easeInOut(duration: 0.3)) { showSidebar = false } } SharedSidebar(isVisible: $showSidebar) .transition(.move(edge: .leading)) } } } // MARK: - Header private var header: some View { HStack(spacing: 12) { // Private icon (gold style) Circle() .fill( LinearGradient( colors: [goldDark, gold], startPoint: .topLeading, endPoint: .bottomTrailing ) ) .frame(width: 40, height: 40) .overlay( Image(systemName: "eye.slash.fill") .font(.system(size: 20)) .foregroundColor(.black) ) VStack(alignment: .leading, spacing: 2) { Text("Приват") .font(.headline) .foregroundColor(textBeige) Text("Зашифрованные транзакции") .font(.caption) .foregroundColor(.secondary) } Spacer() // Privacy badge (gold) HStack(spacing: 4) { Image(systemName: "lock.shield.fill") .font(.system(size: 10)) Text("ZERO-KNOWLEDGE") .font(.system(size: 8, weight: .bold)) } .foregroundColor(gold) .padding(.horizontal, 8) .padding(.vertical, 4) .background(gold.opacity(0.1)) .cornerRadius(8) } .padding() } // MARK: - Purchase Card private var purchaseCard: some View { VStack(spacing: 20) { Image(systemName: "eye.slash.circle.fill") .font(.system(size: 60)) .foregroundColor(gold) Text("🔐 Приватный кошелёк") .font(.title) .fontWeight(.bold) .foregroundColor(textBeige) Text("Покупка приватного ника открывает доступ к зашифрованным транзакциям. Баланс, история, адрес — всё скрыто от blockchain explorer.") .font(.body) .foregroundColor(.secondary) .multilineTextAlignment(.center) .lineSpacing(4) Divider() // Nickname input VStack(alignment: .leading, spacing: 8) { Text("Выбери приватный ник") .font(.callout) .fontWeight(.semibold) HStack(spacing: 8) { TextField("nickname", text: $privateNickname) .textFieldStyle(.plain) .font(.system(size: 14, design: .monospaced)) .padding(10) .background(Color(NSColor.controlBackgroundColor)) .cornerRadius(8) .disabled(isPurchasing) Text("@private.montana") .font(.system(size: 14, design: .monospaced)) .foregroundColor(.secondary) } if !purchaseStatus.isEmpty { Text(purchaseStatus) .font(.caption) .foregroundColor(purchaseStatus.contains("✅") ? .green : .red) } } // Purchase button (gold gradient like website) Button(action: purchasePrivateNick) { HStack(spacing: 8) { if isPurchasing { ProgressView() .controlSize(.small) .scaleEffect(0.8) } else { Image(systemName: "cart.fill") .font(.system(size: 14)) } Text("Купить приватный ник") .font(.system(size: 14, weight: .semibold)) } .foregroundColor(.black) .frame(maxWidth: .infinity) .padding(.vertical, 12) .background( LinearGradient( colors: [goldDark, gold, goldLight], startPoint: .leading, endPoint: .trailing ) ) .cornerRadius(12) .shadow(color: gold.opacity(0.4), radius: 8, x: 0, y: 4) } .buttonStyle(.plain) .disabled(privateNickname.isEmpty || isPurchasing) } .frame(maxWidth: .infinity) .padding(40) .background(gold.opacity(0.03)) .cornerRadius(20) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(gold.opacity(0.08), lineWidth: 1) ) } // MARK: - Private Wallet Card private var privateWalletCard: some View { VStack(spacing: 16) { HStack { VStack(alignment: .leading, spacing: 4) { Text("Приватный кошелёк") .font(.system(size: 13, weight: .semibold)) .foregroundColor(.secondary) Text("\(privateNickname)@private.montana") .font(.system(size: 16, weight: .bold, design: .monospaced)) .foregroundColor(gold) } Spacer() Image(systemName: "checkmark.shield.fill") .font(.system(size: 24)) .foregroundColor(.green) } Divider() // Balance (encrypted) HStack { VStack(alignment: .leading, spacing: 4) { Text("БАЛАНС") .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.secondary) Text("█████ Ɉ") .font(.system(size: 20, weight: .bold, design: .monospaced)) .foregroundColor(gold) } Spacer() Text("🔒 ЗАШИФРОВАНО") .font(.system(size: 9, weight: .bold)) .foregroundColor(crimson) .padding(.horizontal, 8) .padding(.vertical, 4) .background(crimson.opacity(0.1)) .cornerRadius(6) } // Stealth address VStack(alignment: .leading, spacing: 4) { Text("STEALTH ADDRESS") .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.secondary) Text(privateAddress.isEmpty ? "████████████████████████████" : privateAddress) .font(.system(size: 10, design: .monospaced)) .foregroundColor(.secondary) .lineLimit(1) } // Private actions (gold style) HStack(spacing: 8) { Button(action: {}) { HStack(spacing: 4) { Text("Ɉ") .font(.system(size: 12, weight: .bold)) Image(systemName: "arrow.up") .font(.system(size: 10, weight: .bold)) Text("Отправить") .font(.system(size: 11, weight: .semibold)) } .frame(maxWidth: .infinity) .padding(.vertical, 8) .background(gold.opacity(0.15)) .foregroundColor(gold) .cornerRadius(8) } .buttonStyle(.plain) Button(action: {}) { HStack(spacing: 4) { Text("Ɉ") .font(.system(size: 12, weight: .bold)) Image(systemName: "arrow.down") .font(.system(size: 10, weight: .bold)) Text("Получить") .font(.system(size: 11, weight: .semibold)) } .frame(maxWidth: .infinity) .padding(.vertical, 8) .background(goldDark.opacity(0.15)) .foregroundColor(goldLight) .cornerRadius(8) } .buttonStyle(.plain) } } .padding(16) .background(gold.opacity(0.03)) .cornerRadius(20) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(gold.opacity(0.25), lineWidth: 1) ) .shadow(color: gold.opacity(0.1), radius: 10, x: 0, y: 4) } // MARK: - Info Section private var infoSection: some View { VStack(alignment: .leading, spacing: 12) { Text("💡 Как работает приват") .font(.title3) .fontWeight(.semibold) .foregroundColor(textBeige) VStack(alignment: .leading, spacing: 8) { InfoRow(icon: "🔐", text: "Zero-knowledge proof — никто не видит баланс") InfoRow(icon: "🎭", text: "Stealth addresses — новый адрес для каждой транзакции") InfoRow(icon: "🔒", text: "Ring signatures — невозможно отследить отправителя") InfoRow(icon: "👻", text: "Не отображается в blockchain explorer") InfoRow(icon: "💰", text: "Покупка приватного ника = доступ навсегда") } } .padding() .background(gold.opacity(0.05)) .cornerRadius(20) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(gold.opacity(0.08), lineWidth: 1) ) } // MARK: - Actions private func loadPrivateWallet() { let savedNick = UserDefaults.standard.string(forKey: "private_wallet_nick") ?? "" if !savedNick.isEmpty { privateNickname = savedNick hasPrivateWallet = true privateAddress = UserDefaults.standard.string(forKey: "private_wallet_address") ?? "" } else { hasPrivateWallet = false } } private func purchasePrivateNick() { guard !privateNickname.isEmpty else { return } isPurchasing = true purchaseStatus = "" let nick = privateNickname.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() guard nick.range(of: "^[a-z0-9_-]+$", options: .regularExpression) != nil else { purchaseStatus = "❌ Только латиница, цифры, _ и -" isPurchasing = false return } // Generate stealth address from nickname + wallet address using SHA256 let seed = "\(nick)@private.montana:\(engine.address ?? "local"):\(Date().timeIntervalSince1970)" let digest = SHA256.hash(data: Data(seed.utf8)) let stealthAddr = "stealth_" + digest.compactMap { String(format: "%02x", $0) }.joined().prefix(40) privateAddress = String(stealthAddr) privateNickname = nick hasPrivateWallet = true purchaseStatus = "✅ Приватный ник куплен!" UserDefaults.standard.set(nick, forKey: "private_wallet_nick") UserDefaults.standard.set(privateAddress, forKey: "private_wallet_address") isPurchasing = false } } // MARK: - Supporting Views private struct InfoRow: View { let icon: String let text: String var body: some View { HStack(spacing: 8) { Text(icon) .font(.body) Text(text) .font(.callout) .foregroundColor(.secondary) } } } // MARK: - Preview #Preview { PrivateView() .environmentObject(PresenceEngine.shared) .frame(width: 600, height: 500) }