135 lines
4.3 KiB
Swift
135 lines
4.3 KiB
Swift
//
|
|
// RequestZecStore.swift
|
|
// Zashi
|
|
//
|
|
// Created by Lukáš Korba on 09-20-2024.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
import ComposableArchitecture
|
|
import ZcashLightClientKit
|
|
import Pasteboard
|
|
import Generated
|
|
import Utils
|
|
import UIComponents
|
|
import ZcashSDKEnvironment
|
|
import ZcashPaymentURI
|
|
import Models
|
|
|
|
@Reducer
|
|
public struct RequestZec {
|
|
@ObservableState
|
|
public struct State: Equatable {
|
|
public var cancelId = UUID()
|
|
|
|
public var address: RedactableString = .empty
|
|
public var encryptedOutput: String?
|
|
public var encryptedOutputToBeShared: String?
|
|
public var isQRCodeAppreanceFlipped = false
|
|
public var maxPrivacy = false
|
|
public var memoState: MessageEditor.State = .initial
|
|
public var requestedZec: Zatoshi = .zero
|
|
@Shared(.inMemory(.selectedWalletAccount)) public var selectedWalletAccount: WalletAccount? = nil
|
|
public var storedQR: CGImage?
|
|
|
|
public init() {}
|
|
}
|
|
|
|
public enum Action: Equatable {
|
|
case cancelRequestTapped
|
|
case generateQRCode(Bool)
|
|
case memo(MessageEditor.Action)
|
|
case onAppear
|
|
case onDisappear
|
|
case qrCodeTapped
|
|
case rememberQR(CGImage?)
|
|
case requestTapped
|
|
case shareFinished
|
|
case shareQR
|
|
}
|
|
|
|
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
|
|
|
|
public init() { }
|
|
|
|
public var body: some Reducer<State, Action> {
|
|
Scope(state: \.memoState, action: \.memo) {
|
|
MessageEditor()
|
|
}
|
|
|
|
Reduce { state, action in
|
|
switch action {
|
|
case .onAppear:
|
|
state.memoState.charLimit = zcashSDKEnvironment.memoCharLimit
|
|
state.isQRCodeAppreanceFlipped = false
|
|
state.encryptedOutput = nil
|
|
return .none
|
|
|
|
case .onDisappear:
|
|
return .cancel(id: state.cancelId)
|
|
|
|
case .cancelRequestTapped:
|
|
return .none
|
|
|
|
case .memo:
|
|
return .none
|
|
|
|
case .requestTapped:
|
|
return .none
|
|
|
|
case .qrCodeTapped:
|
|
guard state.storedQR != nil else {
|
|
return .none
|
|
}
|
|
state.isQRCodeAppreanceFlipped.toggle()
|
|
return .send(.generateQRCode(true))
|
|
|
|
case let .rememberQR(image):
|
|
state.storedQR = image
|
|
return .none
|
|
|
|
case .generateQRCode:
|
|
if let recipient = RecipientAddress(value: state.address.data) {
|
|
do {
|
|
let payment = Payment(
|
|
recipientAddress: recipient,
|
|
amount: try Amount(value: state.requestedZec.decimalValue.doubleValue),
|
|
memo: state.memoState.text.isEmpty ? nil : try MemoBytes(utf8String: state.memoState.text),
|
|
label: nil,
|
|
message: nil,
|
|
otherParams: nil
|
|
)
|
|
|
|
let encryptedOutput = ZIP321.request(payment, formattingOptions: .useEmptyParamIndex(omitAddressLabel: true))
|
|
state.encryptedOutput = encryptedOutput
|
|
return .publisher {
|
|
QRCodeGenerator.generate(
|
|
from: encryptedOutput,
|
|
maxPrivacy: state.maxPrivacy,
|
|
vendor: state.selectedWalletAccount?.vendor == .keystone ? .keystone : .zashi,
|
|
color: state.isQRCodeAppreanceFlipped
|
|
? .black
|
|
: Asset.Colors.primary.systemColor
|
|
)
|
|
.map(Action.rememberQR)
|
|
}
|
|
.cancellable(id: state.cancelId)
|
|
} catch {
|
|
return .none
|
|
}
|
|
}
|
|
return .none
|
|
|
|
case .shareFinished:
|
|
state.encryptedOutputToBeShared = nil
|
|
return .none
|
|
|
|
case .shareQR:
|
|
state.encryptedOutputToBeShared = state.encryptedOutput
|
|
return .none
|
|
}
|
|
}
|
|
}
|
|
}
|