[#516] Adopt unreleased changes that will go live with SDK 0.18.0-beta release (#532)

- all issues refactored
- previous transactions replaced by new data type from the SDK
- unit tests fixed
This commit is contained in:
Lukas Korba 2023-02-06 09:38:34 +01:00 committed by GitHub
parent 1aca887800
commit fdd6ff19c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 321 additions and 127 deletions

View File

@ -2617,7 +2617,7 @@
repositoryURL = "https://github.com/zcash/ZcashLightClientKit/";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = "0.17.0-beta";
minimumVersion = "0.18.0-beta";
};
};
6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {

View File

@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/stephencelis/SQLite.swift.git",
"state" : {
"revision" : "4d543d811ee644fa4cc4bfa0be996b4dd6ba0f54",
"version" : "0.13.3"
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb",
"version" : "0.14.1"
}
},
{
@ -203,8 +203,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi.git",
"state" : {
"revision" : "fad9802b907822d5a1877584c91f3786824521b7",
"version" : "0.1.0"
"revision" : "b6013b8b313523b2c72ce62dbdc17f6ffad3a500",
"version" : "0.1.1"
}
},
{
@ -212,8 +212,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash/ZcashLightClientKit",
"state" : {
"revision" : "d9b85b40ad36ac5183f44b6db9805e44171ee988",
"version" : "0.17.0-beta"
"revision" : "731c7bbf4514a90b879c5c15968cdb41ac728e3a",
"version" : "0.18.0-beta"
}
}
],

View File

@ -59,6 +59,8 @@ protocol SDKSynchronizerClient {
func getShieldedBalance() -> WalletBalance?
func getTransparentBalance() -> WalletBalance?
func getAllSentTransactions() -> Effect<[WalletEvent], Never>
func getAllReceivedTransactions() -> Effect<[WalletEvent], Never>
func getAllClearedTransactions() -> Effect<[WalletEvent], Never>
func getAllPendingTransactions() -> Effect<[WalletEvent], Never>
func getAllTransactions() -> Effect<[WalletEvent], Never>

View File

@ -113,10 +113,35 @@ class LiveSDKSynchronizerClient: SDKSynchronizerClient {
latestScannedSynchronizerState?.transparentBalance
}
func getAllSentTransactions() -> Effect<[WalletEvent], Never> {
if let transactions = try? synchronizer?.allSentTransactions() {
return Effect(value: transactions.map {
let memos = try? synchronizer?.getMemos(for: $0)
let transaction = TransactionState.init(transaction: $0, memos: memos)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
})
}
return .none
}
func getAllReceivedTransactions() -> Effect<[WalletEvent], Never> {
if let transactions = try? synchronizer?.allReceivedTransactions() {
return Effect(value: transactions.map {
let memos = try? synchronizer?.getMemos(for: $0)
let transaction = TransactionState.init(transaction: $0, memos: memos)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
})
}
return .none
}
func getAllClearedTransactions() -> Effect<[WalletEvent], Never> {
if let clearedTransactions = try? synchronizer?.allClearedTransactions() {
return Effect(value: clearedTransactions.map {
let transaction = TransactionState.init(confirmedTransaction: $0, sent: ($0.toAddress != nil))
if let transactions = try? synchronizer?.allClearedTransactions() {
return Effect(value: transactions.map {
let memos = try? synchronizer?.getMemos(for: $0)
let transaction = TransactionState.init(transaction: $0, memos: memos)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
})
}
@ -125,9 +150,9 @@ class LiveSDKSynchronizerClient: SDKSynchronizerClient {
}
func getAllPendingTransactions() -> Effect<[WalletEvent], Never> {
if let pendingTransactions = try? synchronizer?.allPendingTransactions(),
if let transactions = try? synchronizer?.allPendingTransactions(),
let syncedBlockHeight = synchronizer?.latestScannedHeight {
return Effect(value: pendingTransactions.map {
return Effect(value: transactions.map {
let transaction = TransactionState.init(pendingTransaction: $0, latestBlockHeight: syncedBlockHeight)
return WalletEvent(id: transaction.id, state: .pending(transaction), timestamp: transaction.timestamp)
})
@ -141,21 +166,21 @@ class LiveSDKSynchronizerClient: SDKSynchronizerClient {
let clearedTransactions = try? synchronizer?.allClearedTransactions(),
let syncedBlockHeight = synchronizer?.latestScannedHeight {
let clearedTxs: [WalletEvent] = clearedTransactions.map {
let transaction = TransactionState.init(confirmedTransaction: $0, sent: ($0.toAddress != nil))
let transaction = TransactionState.init(transaction: $0)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
}
let pendingTxs: [WalletEvent] = pendingTransactions.map {
let transaction = TransactionState.init(pendingTransaction: $0, latestBlockHeight: syncedBlockHeight)
return WalletEvent(id: transaction.id, state: .pending(transaction), timestamp: transaction.timestamp)
}
let txs = clearedTxs.filter { cleared in
let cTxs = clearedTxs.filter { transaction in
pendingTxs.first { pending in
pending.id == cleared.id
pending.id == transaction.id
} == nil
}
return .merge(
Effect(value: txs),
Effect(value: cTxs),
Effect(value: pendingTxs)
)
.flatMap(Publishers.Sequence.init(sequence:))

View File

@ -47,6 +47,56 @@ class MockSDKSynchronizerClient: SDKSynchronizerClient {
WalletBalance(verified: Zatoshi(12345000), total: Zatoshi(12345000))
}
func getAllSentTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
]
return Effect(
value:
mocked.map {
let transaction = TransactionState.placeholder(
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp ?? 0)
}
)
}
func getAllReceivedTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
]
return Effect(
value:
mocked.map {
let transaction = TransactionState.placeholder(
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp ?? 0)
}
)
}
func getAllClearedTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
@ -67,7 +117,7 @@ class MockSDKSynchronizerClient: SDKSynchronizerClient {
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp ?? 0)
}
)
}
@ -132,9 +182,12 @@ class MockSDKSynchronizerClient: SDKSynchronizerClient {
to recipientAddress: Recipient,
memo: Memo?
) -> Effect<Result<TransactionState, NSError>, Never> {
var memos: [Memo]? = []
if let memo { memos?.append(memo) }
let transactionState = TransactionState(
expirationHeight: 40,
memo: memo,
expiryHeight: 40,
memos: memos,
minedHeight: 50,
shielded: true,
zAddress: "tteafadlamnelkqe",

View File

@ -42,6 +42,10 @@ class NoopSDKSynchronizer: SDKSynchronizerClient {
func getTransparentBalance() -> WalletBalance? { nil }
func getAllSentTransactions() -> Effect<[WalletEvent], Never> { Effect(value: []) }
func getAllReceivedTransactions() -> Effect<[WalletEvent], Never> { Effect(value: []) }
func getAllClearedTransactions() -> Effect<[WalletEvent], Never> { Effect(value: []) }
func getAllPendingTransactions() -> Effect<[WalletEvent], Never> { Effect(value: []) }
@ -69,7 +73,6 @@ class NoopSDKSynchronizer: SDKSynchronizerClient {
}
class TestSDKSynchronizerClient: SDKSynchronizerClient {
private(set) var blockProcessor: CompactBlockProcessor?
private(set) var notificationCenter: NotificationCenterClient
private(set) var synchronizer: SDKSynchronizer?
private(set) var stateChanged: CurrentValueSubject<SDKSynchronizerState, Never>
@ -97,6 +100,56 @@ class TestSDKSynchronizerClient: SDKSynchronizerClient {
func getTransparentBalance() -> WalletBalance? { nil }
func getAllSentTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
]
return Effect(
value:
mocked.map {
let transaction = TransactionState.placeholder(
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
}
)
}
func getAllReceivedTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
]
return Effect(
value:
mocked.map {
let transaction = TransactionState.placeholder(
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
}
)
}
func getAllClearedTransactions() -> Effect<[WalletEvent], Never> {
let mocked: [TransactionStateMockHelper] = [
TransactionStateMockHelper(date: 1651039202, amount: Zatoshi(1), status: .paid(success: false), uuid: "aa11"),

View File

@ -40,8 +40,8 @@ struct HomeReducer: ReducerProtocol {
Zatoshi.from(decimal: shieldedBalance.total.decimalValue.decimalValue * zecPrice)
}
var isDownloading: Bool {
if case .downloading = synchronizerStatusSnapshot.syncStatus {
var isSyncing: Bool {
if case .syncing = synchronizerStatusSnapshot.syncStatus {
return true
}
return false
@ -120,7 +120,7 @@ struct HomeReducer: ReducerProtocol {
case .synchronizerStateChanged(.synced):
return .merge(
sdkSynchronizer.getAllClearedTransactions()
sdkSynchronizer.getAllTransactions()
.receive(on: mainQueue)
.map(HomeReducer.Action.updateWalletEvents)
.eraseToEffect(),

View File

@ -118,8 +118,8 @@ extension HomeView {
VStack {
ZStack {
CircularProgress(
outerCircleProgress: viewStore.isDownloading ? 0 : viewStore.synchronizerStatusSnapshot.progress,
innerCircleProgress: viewStore.isDownloading ? viewStore.synchronizerStatusSnapshot.progress : 1,
outerCircleProgress: viewStore.isSyncing ? 0 : viewStore.synchronizerStatusSnapshot.progress,
innerCircleProgress: 1,
maxSegments: viewStore.requiredTransactionConfirmations,
innerCircleHidden: viewStore.isUpToDate
)

View File

@ -25,26 +25,26 @@ struct TransactionDetailView: View {
plainText("fee \(transaction.fee.decimalString()) ZEC", mark: .inactive)
plainText("total amount \(transaction.totalAmount.decimalString()) ZEC", mark: .inactive)
address(mark: .inactive, viewStore: viewStore)
if let text = transaction.memo?.toString() { memo(text, viewStore, mark: .highlight) }
if let text = transaction.memos?.first?.toString() { memo(text, viewStore, mark: .highlight) }
confirmed(mark: .success, viewStore: viewStore)
case .pending:
plainText("You are sending \(transaction.zecAmount.decimalString()) ZEC")
plainText("Includes network fee \(transaction.fee.decimalString()) ZEC", mark: .inactive)
plainText("total amount \(transaction.totalAmount.decimalString()) ZEC", mark: .inactive)
if let text = transaction.memo?.toString() { memo(text, viewStore, mark: .inactive) }
if let text = transaction.memos?.first?.toString() { memo(text, viewStore, mark: .inactive) }
confirming(mark: .highlight, viewStore: viewStore)
case .received:
plainText("You received \(transaction.zecAmount.decimalString()) ZEC")
plainText("fee \(transaction.fee.decimalString()) ZEC")
plainText("total amount \(transaction.totalAmount.decimalString()) ZEC")
address(mark: .inactive, viewStore: viewStore)
if let text = transaction.memo?.toString() { memo(text, viewStore, mark: .highlight) }
if let text = transaction.memos?.first?.toString() { memo(text, viewStore, mark: .highlight) }
confirmed(mark: .success, viewStore: viewStore)
case .failed:
plainText("You DID NOT send \(transaction.zecAmount.decimalString()) ZEC", mark: .fail)
plainText("Includes network fee \(transaction.fee.decimalString()) ZEC", mark: .inactive)
plainText("total amount \(transaction.totalAmount.decimalString()) ZEC", mark: .inactive)
if let text = transaction.memo?.toString() { memo(text, viewStore, mark: .inactive) }
if let text = transaction.memos?.first?.toString() { memo(text, viewStore, mark: .inactive) }
if let errorMessage = transaction.errorMessage {
plainTwoColumnText(left: "Failed", right: errorMessage, mark: .fail)
}
@ -68,11 +68,11 @@ extension TransactionDetailView {
Text("PENDING")
Spacer()
case .failed:
Text("\(transaction.date.asHumanReadable())")
Text("\(transaction.date?.asHumanReadable() ?? "date not available")")
Spacer()
Text("FAILED")
default:
Text("\(transaction.date.asHumanReadable())")
Text("\(transaction.date?.asHumanReadable() ?? "date not available")")
Spacer()
Text("HEIGHT \(heightText)")
}
@ -192,7 +192,8 @@ extension TransactionDetailView {
}
var heightText: String {
transaction.minedHeight > 0 ? String(transaction.minedHeight) : "unconfirmed"
guard let minedHeight = transaction.minedHeight else { return "unconfirmed" }
return minedHeight > 0 ? String(minedHeight) : "unconfirmed"
}
}
@ -253,12 +254,7 @@ struct TransactionDetail_Previews: PreviewProvider {
transaction:
TransactionState(
errorMessage: "possible roll back",
memo: try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
"""),
memos: [Memo.placeholder],
minedHeight: 1_875_256,
zAddress: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po",
fee: Zatoshi(1_000_000),
@ -273,3 +269,13 @@ struct TransactionDetail_Previews: PreviewProvider {
}
}
}
private extension Memo {
// swiftlint:disable:next force_try
static let placeholder = try! Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
""")
}

View File

@ -62,14 +62,14 @@ extension TransactionRowView {
var operationTitle: String {
switch transaction.status {
case .paid(success: _):
return "You sent to"
return "You sent"
case .received:
return "Unknown paid you"
case .failed:
// TODO: [#392] final text to be provided (https://github.com/zcash/secant-ios-wallet/issues/392)
return "Transaction failed"
case .pending:
return "You are sending to"
return "You are sending"
}
}

View File

@ -60,7 +60,7 @@ struct WalletEventsFlowReducer: ReducerProtocol {
if let latestMinedHeight = sdkSynchronizer.synchronizer?.latestScannedHeight {
state.latestMinedHeight = latestMinedHeight
}
return sdkSynchronizer.getAllTransactions()
return sdkSynchronizer.getAllClearedTransactions()
.receive(on: mainQueue)
.map(WalletEventsFlowReducer.Action.updateWalletEvents)
.eraseToEffect()
@ -71,7 +71,10 @@ struct WalletEventsFlowReducer: ReducerProtocol {
case .updateWalletEvents(let walletEvents):
let sortedWalletEvents = walletEvents
.sorted(by: { lhs, rhs in
lhs.timestamp > rhs.timestamp
guard let lhsTimestamp = lhs.timestamp, let rhsTimestamp = rhs.timestamp else {
return false
}
return lhsTimestamp > rhsTimestamp
})
state.walletEvents = IdentifiedArrayOf(uniqueElements: sortedWalletEvents)
return .none

View File

@ -21,18 +21,12 @@ struct SyncStatusSnapshot: Equatable {
static func snapshotFor(state: SyncStatus) -> SyncStatusSnapshot {
switch state {
case .downloading(let progress):
return SyncStatusSnapshot(state, "downloading - \(String(format: "%d%%", Int(progress.progress * 100.0)))", progress.progress)
case .enhancing(let enhanceProgress):
return SyncStatusSnapshot(state, "Enhancing tx \(enhanceProgress.enhancedTransactions) of \(enhanceProgress.totalTransactions)")
case .fetching:
return SyncStatusSnapshot(state, "fetching UTXOs")
case .scanning(let progress):
return SyncStatusSnapshot(state, "scanning - \(String(format: "%d%%", Int(progress.progress * 100.0)))", progress.progress)
case .disconnected:
return SyncStatusSnapshot(state, "disconnected 💔")
@ -45,11 +39,11 @@ struct SyncStatusSnapshot: Equatable {
case .unprepared:
return SyncStatusSnapshot(state, "Unprepared 😅")
case .validating:
return SyncStatusSnapshot(state, "Validating")
case .error(let err):
return SyncStatusSnapshot(state, "Error: \(err.localizedDescription)")
case .syncing(let progress):
return SyncStatusSnapshot(state, "Syncing \(progress)")
}
}
}

View File

@ -18,27 +18,38 @@ struct TransactionState: Equatable, Identifiable {
}
var errorMessage: String?
var expirationHeight = -1
var memo: Memo?
var minedHeight = -1
var expiryHeight: BlockHeight?
var memos: [Memo]?
var minedHeight: BlockHeight?
var shielded = true
var zAddress: String?
var fee: Zatoshi
var id: String
var status: Status
var timestamp: TimeInterval
var timestamp: TimeInterval?
var zecAmount: Zatoshi
var address: String { zAddress ?? "" }
var date: Date { Date(timeIntervalSince1970: timestamp) }
var totalAmount: Zatoshi { Zatoshi(zecAmount.amount + fee.amount) }
var address: String {
zAddress ?? ""
}
var date: Date? {
guard let timestamp else { return nil }
return Date(timeIntervalSince1970: timestamp)
}
var totalAmount: Zatoshi {
Zatoshi(zecAmount.amount + fee.amount)
}
var viewOnlineURL: URL? {
URL(string: "https://zcashblockexplorer.com/transactions/\(id)")
}
func confirmationsWith(_ latestMinedHeight: BlockHeight?) -> BlockHeight {
guard let latestMinedHeight = latestMinedHeight, minedHeight > 0, latestMinedHeight > 0 else {
guard let minedHeight, let latestMinedHeight, minedHeight > 0, latestMinedHeight > 0 else {
return 0
}
@ -47,20 +58,39 @@ struct TransactionState: Equatable, Identifiable {
}
extension TransactionState {
init(confirmedTransaction: ConfirmedTransactionEntity, sent: Bool = false) {
timestamp = confirmedTransaction.blockTimeInSeconds
id = confirmedTransaction.transactionEntity.transactionId.toHexStringTxId()
shielded = true
status = sent ? .paid(success: confirmedTransaction.minedHeight > 0) : .received
zAddress = confirmedTransaction.toAddress
zecAmount = sent ? Zatoshi(-confirmedTransaction.value.amount) : confirmedTransaction.value
fee = Zatoshi(10)
if let memoData = confirmedTransaction.memo {
self.memo = try? Memo(bytes: Array(memoData))
}
minedHeight = confirmedTransaction.minedHeight
init(transaction: ZcashTransaction.Overview, memos: [Memo]? = nil) {
expiryHeight = transaction.expiryHeight
minedHeight = transaction.minedHeight
fee = transaction.fee ?? Zatoshi(0)
id = transaction.rawID.toHexStringTxId()
status = transaction.isSentTransaction ? .paid(success: minedHeight ?? 0 > 0) : .received
timestamp = transaction.blockTime
zecAmount = transaction.isSentTransaction ? Zatoshi(-transaction.value.amount) : transaction.value
self.memos = memos
}
init(transaction: ZcashTransaction.Sent, memos: [Memo]? = nil) {
expiryHeight = transaction.expiryHeight
minedHeight = transaction.minedHeight
fee = .zero
id = transaction.rawID?.toHexStringTxId() ?? ""
status = .paid(success: minedHeight ?? 0 > 0)
timestamp = transaction.blockTime
zecAmount = transaction.value
self.memos = memos
}
init(transaction: ZcashTransaction.Received, memos: [Memo]? = nil) {
expiryHeight = transaction.expiryHeight
minedHeight = transaction.minedHeight
fee = .zero
id = transaction.rawID?.toHexStringTxId() ?? ""
status = .received
timestamp = transaction.blockTime
zecAmount = transaction.value
self.memos = memos
}
init(pendingTransaction: PendingTransactionEntity, latestBlockHeight: BlockHeight? = nil) {
timestamp = pendingTransaction.createTime
id = pendingTransaction.rawTransactionId?.toHexStringTxId() ?? String(pendingTransaction.createTime)
@ -69,12 +99,9 @@ extension TransactionState {
pendingTransaction.minedHeight > 0 ?
.paid(success: pendingTransaction.isSubmitSuccess) :
.pending
expirationHeight = pendingTransaction.expiryHeight
expiryHeight = pendingTransaction.expiryHeight
zecAmount = pendingTransaction.value
fee = Zatoshi(10)
if let memoData = pendingTransaction.memo {
self.memo = try? Memo(bytes: Array(memoData))
}
minedHeight = pendingTransaction.minedHeight
errorMessage = pendingTransaction.errorMessage
@ -99,8 +126,8 @@ extension TransactionState {
uuid: String = UUID().debugDescription
) -> TransactionState {
.init(
expirationHeight: -1,
memo: nil,
expiryHeight: -1,
memos: nil,
minedHeight: -1,
shielded: shielded,
zAddress: nil,

View File

@ -24,7 +24,7 @@ struct WalletEvent: Equatable, Identifiable {
let id: String
let state: WalletEventState
var timestamp: TimeInterval
var timestamp: TimeInterval?
}
// MARK: - Rows

View File

@ -50,18 +50,27 @@ class HomeTests: XCTestCase {
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55"),
TransactionStateMockHelper(
date: 1651039606,
amount: Zatoshi(6),
status: .paid(success: false),
uuid: "ff66"
),
TransactionStateMockHelper(date: 1651039303, amount: Zatoshi(7), uuid: "gg77"),
TransactionStateMockHelper(date: 1651039707, amount: Zatoshi(8), status: .paid(success: true), uuid: "hh88"),
TransactionStateMockHelper(date: 1651039808, amount: Zatoshi(9), uuid: "ii99")
]
let walletEvents: [WalletEvent] = transactionsHelper.map {
let transaction = TransactionState.placeholder(
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.status,
status: $0.amount.amount > 5 ? .pending : $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
return WalletEvent(id: transaction.id, state: .send(transaction), timestamp: transaction.timestamp)
return WalletEvent(id: transaction.id, state: $0.amount.amount > 5 ? .pending(transaction) : .send(transaction), timestamp: transaction.timestamp)
}
store.receive(.updateWalletEvents(walletEvents))

View File

@ -62,10 +62,14 @@ class SendTests: XCTestCase {
}
await testScheduler.advance(by: 0.01)
guard let memo = try? Memo(string: "test") else {
XCTFail("testSendSucceeded: memo is expected to be successfuly initialized.")
return
}
let transactionState = TransactionState(
expirationHeight: 40,
memo: try? Memo(string: "test"),
expiryHeight: 40,
memos: [memo],
minedHeight: 50,
shielded: true,
zAddress: "tteafadlamnelkqe",
@ -132,8 +136,8 @@ class SendTests: XCTestCase {
await testScheduler.advance(by: 0.01)
let transactionState = TransactionState(
expirationHeight: 40,
memo: nil,
expiryHeight: 40,
memos: [],
minedHeight: 50,
shielded: true,
zAddress: "tteafadlamnelkqe",

View File

@ -21,7 +21,7 @@ class HomeCircularProgressSnapshotTests: XCTestCase {
progressHeight: BlockHeight(55)
)
return SyncStatusSnapshot.snapshotFor(state: .downloading(blockProgress))
return SyncStatusSnapshot.snapshotFor(state: .syncing(blockProgress))
}
}
@ -57,7 +57,7 @@ class HomeCircularProgressSnapshotTests: XCTestCase {
progressHeight: BlockHeight(72)
)
return SyncStatusSnapshot.snapshotFor(state: .scanning(blockProgress))
return SyncStatusSnapshot.snapshotFor(state: .syncing(blockProgress))
}
}

View File

@ -63,13 +63,19 @@ class WalletEventsSnapshotTests: XCTestCase {
}
func testWalletEventDetailSnapshot_sent() throws {
let memo = try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
""")
guard let memo else {
XCTFail("testWalletEventDetailSnapshot_sent: memo is expected to be successfuly initialized")
return
}
let transaction = TransactionState(
memo: try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
"""),
memos: [memo],
minedHeight: 1_875_256,
zAddress: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po",
fee: Zatoshi(1_000_000),
@ -110,13 +116,19 @@ class WalletEventsSnapshotTests: XCTestCase {
}
func testWalletEventDetailSnapshot_received() throws {
let memo = try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
""")
guard let memo else {
XCTFail("testWalletEventDetailSnapshot_received: memo is expected to be successfuly initialized")
return
}
let transaction = TransactionState(
memo: try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
"""),
memos: [memo],
minedHeight: 1_875_256,
zAddress: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po",
fee: Zatoshi(1_000_000),
@ -157,13 +169,19 @@ class WalletEventsSnapshotTests: XCTestCase {
}
func testWalletEventDetailSnapshot_pending() throws {
let memo = try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
""")
guard let memo else {
XCTFail("testWalletEventDetailSnapshot_pending: memo is expected to be successfuly initialized")
return
}
let transaction = TransactionState(
memo: try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
"""),
memos: [memo],
minedHeight: 1_875_256,
zAddress: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po",
fee: Zatoshi(1_000_000),
@ -209,14 +227,20 @@ class WalletEventsSnapshotTests: XCTestCase {
}
func testWalletEventDetailSnapshot_failed() throws {
let memo = try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
""")
guard let memo else {
XCTFail("testWalletEventDetailSnapshot_failed: memo is expected to be successfuly initialized")
return
}
let transaction = TransactionState(
errorMessage: "possible roll back",
memo: try? Memo(string:
"""
Testing some long memo so I can see many lines of text \
instead of just one. This can take some time and I'm \
bored to write all this stuff.
"""),
memos: [memo],
minedHeight: 1_875_256,
zAddress: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po",
fee: Zatoshi(1_000_000),

View File

@ -39,16 +39,7 @@ class WalletEventsTests: XCTestCase {
TransactionStateMockHelper(date: 1651039101, amount: Zatoshi(2), uuid: "bb22"),
TransactionStateMockHelper(date: 1651039000, amount: Zatoshi(3), status: .paid(success: true), uuid: "cc33"),
TransactionStateMockHelper(date: 1651039505, amount: Zatoshi(4), uuid: "dd44"),
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55"),
TransactionStateMockHelper(
date: 1651039606,
amount: Zatoshi(6),
status: .paid(success: false),
uuid: "ff66"
),
TransactionStateMockHelper(date: 1651039303, amount: Zatoshi(7), uuid: "gg77"),
TransactionStateMockHelper(date: 1651039707, amount: Zatoshi(8), status: .paid(success: true), uuid: "hh88"),
TransactionStateMockHelper(date: 1651039808, amount: Zatoshi(9), uuid: "ii99")
TransactionStateMockHelper(date: 1651039404, amount: Zatoshi(5), uuid: "ee55")
]
let walletEvents: [WalletEvent] = mocked.map {
@ -56,7 +47,7 @@ class WalletEventsTests: XCTestCase {
amount: $0.amount,
fee: Zatoshi(10),
shielded: $0.shielded,
status: $0.amount.amount > 5 ? .pending : $0.status,
status: $0.status,
timestamp: $0.date,
uuid: $0.uuid
)
@ -90,7 +81,10 @@ class WalletEventsTests: XCTestCase {
uniqueElements:
walletEvents
.sorted(by: { lhs, rhs in
lhs.timestamp > rhs.timestamp
guard let lhsTimestamp = lhs.timestamp, let rhsTimestamp = rhs.timestamp else {
return false
}
return lhsTimestamp > rhsTimestamp
})
)