Updated on 2026-08-14
This commit is contained in:
parent
9efe573323
commit
9af7bad7b8
22 changed files with 1680 additions and 238 deletions
|
|
@ -27,5 +27,6 @@ dependencies {
|
|||
api(projects.domain.express.models)
|
||||
api(projects.domain.models)
|
||||
api(projects.domain.txhistory.models)
|
||||
api(projects.domain.visa.models)
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.tangem.domain.txhistory.list
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.txhistory.list.HistoryTxListManager.HistoryState
|
||||
import com.tangem.domain.txhistory.model.TxHistoryInfo
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Reads the unified transaction history for a currency: the on-chain backbone (BSDK / TangemPay / index-backed
|
||||
|
||||
* (wallet, currency) via [Factory].
|
||||
*/
|
||||
interface HistoryTxListManager {
|
||||
|
||||
/** The whole history state, newest first — the single source of truth for the UI. */
|
||||
val state: StateFlow<HistoryState>
|
||||
|
||||
val historySources: Flow<HistorySources>
|
||||
|
||||
fun reload()
|
||||
|
||||
fun loadMore()
|
||||
|
||||
/** Universal history state: the caller renders exactly one of these. */
|
||||
sealed interface HistoryState {
|
||||
data object Loading : HistoryState
|
||||
data object Unavailable : HistoryState
|
||||
data object Empty : HistoryState
|
||||
data object Error : HistoryState
|
||||
data class Content(
|
||||
val items: List<TxHistoryInfo>,
|
||||
val isLoadingMore: Boolean,
|
||||
val hasMore: Boolean,
|
||||
) : HistoryState
|
||||
}
|
||||
|
||||
/** How the history starts for a currency: which on-chain backbone exists and whether express is available. */
|
||||
data class HistorySources(
|
||||
val onChainSource: OnChainSource,
|
||||
val isExchangeAvailable: Boolean,
|
||||
val isOnrampAvailable: Boolean,
|
||||
)
|
||||
|
||||
data class HistoryEnvironment(
|
||||
val userWalletId: UserWalletId,
|
||||
val currency: CryptoCurrency,
|
||||
val modelScope: CoroutineScope,
|
||||
)
|
||||
|
||||
enum class OnChainSource { BSDK, TangemPay, IndexTable }
|
||||
|
||||
interface Factory {
|
||||
fun create(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
modelScope: CoroutineScope,
|
||||
): HistoryTxListManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactive stream of a single row tracked by its [TxHistoryInfo.txId], for the in-app details sheet.
|
||||
*
|
||||
* Seeded with the tapped [item] so the sheet always has an immediate snapshot, then re-emits the matching row from
|
||||
* the live merged list as its status changes. The seed also covers rows not present in [state] yet (e.g. a pending
|
||||
* tx surfaced from the currency status), which would otherwise never resolve.
|
||||
*/
|
||||
fun HistoryTxListManager.txHistoryInfoFlow(item: TxHistoryInfo): Flow<TxHistoryInfo> = state
|
||||
.mapNotNull { (it as? HistoryState.Content)?.items }
|
||||
.mapNotNull { list -> list.firstOrNull { it.txId == item.txId } }
|
||||
.onStart { emit(item) }
|
||||
.distinctUntilChanged()
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.domain.express.models.ExchangeTransaction
|
|||
import com.tangem.domain.express.models.ExpressProvider
|
||||
import com.tangem.domain.express.models.OnrampTransaction
|
||||
import com.tangem.domain.models.network.TxInfo
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
|
||||
/**
|
||||
* A single row of the unified transaction history shown on the token-details screen.
|
||||
|
|
@ -38,11 +39,10 @@ sealed interface OnChainTx : TxHistoryInfo {
|
|||
override val timestampMillis: Long get() = txInfo.timestampInMillis
|
||||
}
|
||||
|
||||
// todo txHistory next step
|
||||
/*data class TangemPay(val txInfo: TangemPayTxHistoryItem) : OnChainTx {
|
||||
data class TangemPay(val txInfo: TangemPayTxHistoryItem) : OnChainTx {
|
||||
override val txId: String get() = txInfo.id
|
||||
override val timestampMillis: Long get() = txInfo.date.millis
|
||||
}*/
|
||||
}
|
||||
|
||||
// todo txHistory next step
|
||||
/*data class Gateway() : OnChainTx {
|
||||
|
|
@ -71,6 +71,13 @@ fun TxInfo.identityKey(): String = "$txHash|$type"
|
|||
inline val TxHistoryInfo.explorerHash: String?
|
||||
get() = when (this) {
|
||||
is OnChainTx.BSDK -> txInfo.txHash
|
||||
is OnChainTx.TangemPay -> when (val item = txInfo) {
|
||||
is TangemPayTxHistoryItem.Payment -> item.transactionHash
|
||||
is TangemPayTxHistoryItem.Collateral -> item.transactionHash
|
||||
is TangemPayTxHistoryItem.Spend,
|
||||
is TangemPayTxHistoryItem.Fee,
|
||||
-> null
|
||||
}
|
||||
is ExpressTx -> matchHash
|
||||
}
|
||||
|
||||
|
|
@ -78,6 +85,7 @@ inline val TxHistoryInfo.explorerHash: String?
|
|||
inline val TxHistoryInfo.idToCopy: String
|
||||
get() = when (this) {
|
||||
is OnChainTx.BSDK -> txInfo.txHash
|
||||
is OnChainTx.TangemPay -> explorerHash ?: txId
|
||||
is ExpressTx -> txId
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue