Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-19 16:17:51 +04:00
parent 4c8537529a
commit 33b7a53905
37 changed files with 396 additions and 365 deletions

View file

@ -1,6 +1,6 @@
package com.tangem.common.test.domain.walletmanager
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.walletmanager.model.Address
import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount
import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction
@ -40,24 +40,24 @@ class MockUpdateWalletManagerResultFactory {
CryptoCurrencyAmount.Coin(value = BigDecimal.ONE),
),
currentTransactions = setOf(
CryptoCurrencyTransaction.Coin(txHistoryItem),
CryptoCurrencyTransaction.Coin(txInfo),
),
)
}
private companion object {
val txHistoryItem = TxHistoryItem(
val txInfo = TxInfo(
txHash = "erroribus",
timestampInMillis = 2771,
isOutgoing = false,
destinationType = TxHistoryItem.DestinationType.Single(
addressType = TxHistoryItem.AddressType.User(address = "0x1"),
destinationType = TxInfo.DestinationType.Single(
addressType = TxInfo.AddressType.User(address = "0x1"),
),
sourceType = TxHistoryItem.SourceType.Single(address = "0x2"),
sourceType = TxInfo.SourceType.Single(address = "0x2"),
interactionAddressType = null,
status = TxHistoryItem.TransactionStatus.Confirmed,
type = TxHistoryItem.TransactionType.Transfer,
status = TxInfo.TransactionStatus.Confirmed,
type = TxInfo.TransactionType.Transfer,
amount = BigDecimal.ONE,
)
}

View file

@ -2,25 +2,25 @@ package com.tangem.datasource.local.txhistory
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
import com.tangem.datasource.local.datastore.core.StringKeyDataStoreDecorator
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.utils.extensions.addOrReplace
internal class DefaultTxHistoryItemsStore(
dataStore: StringKeyDataStore<Set<PaginationWrapper<TxHistoryItem>>>,
dataStore: StringKeyDataStore<Set<PaginationWrapper<TxInfo>>>,
) : TxHistoryItemsStore,
StringKeyDataStoreDecorator<TxHistoryItemsStore.Key, Set<PaginationWrapper<TxHistoryItem>>>(dataStore) {
StringKeyDataStoreDecorator<TxHistoryItemsStore.Key, Set<PaginationWrapper<TxInfo>>>(dataStore) {
override fun provideStringKey(key: TxHistoryItemsStore.Key): String = key.toString()
override suspend fun getSyncOrNull(key: TxHistoryItemsStore.Key, page: Page): PaginationWrapper<TxHistoryItem>? {
override suspend fun getSyncOrNull(key: TxHistoryItemsStore.Key, page: Page): PaginationWrapper<TxInfo>? {
val storedValue = getSyncOrNull(key)
return storedValue?.firstOrNull { it.currentPage == page }
}
override suspend fun store(key: TxHistoryItemsStore.Key, value: PaginationWrapper<TxHistoryItem>) {
override suspend fun store(key: TxHistoryItemsStore.Key, value: PaginationWrapper<TxInfo>) {
val oldValue = getSyncOrNull(key).orEmpty()
val newValue = oldValue.addOrReplace(value) {
it.currentPage == value.currentPage

View file

@ -1,18 +1,18 @@
package com.tangem.datasource.local.txhistory
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.wallets.models.UserWalletId
interface TxHistoryItemsStore {
suspend fun getSyncOrNull(key: Key, page: Page): PaginationWrapper<TxHistoryItem>?
suspend fun getSyncOrNull(key: Key, page: Page): PaginationWrapper<TxInfo>?
suspend fun remove(key: Key)
suspend fun store(key: Key, value: PaginationWrapper<TxHistoryItem>)
suspend fun store(key: Key, value: PaginationWrapper<TxInfo>)
data class Key(
val userWalletId: UserWalletId,

View file

@ -2,11 +2,11 @@ package com.tangem.data.networks.utils
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus
import com.tangem.domain.tokens.model.NetworkAddress
import com.tangem.domain.tokens.model.NetworkStatus
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.walletmanager.model.Address
import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount
import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction
@ -116,7 +116,7 @@ object NetworkStatusFactory {
private fun formatTransactions(
transactions: Set<CryptoCurrencyTransaction>,
currencies: Set<CryptoCurrency>,
): Map<CryptoCurrency.ID, Set<TxHistoryItem>> {
): Map<CryptoCurrency.ID, Set<TxInfo>> {
if (transactions.isEmpty()) return emptyMap()
return currencies
@ -137,8 +137,8 @@ object NetworkStatusFactory {
.toMap()
}
private fun createCurrentTransactions(transactions: Set<CryptoCurrencyTransaction>): Set<TxHistoryItem> {
return transactions.mapTo(hashSetOf()) { it.txHistoryItem }
private fun createCurrentTransactions(transactions: Set<CryptoCurrencyTransaction>): Set<TxInfo> {
return transactions.mapTo(hashSetOf()) { it.txInfo }
}
private fun getNetworkAddress(selectedAddress: String, availableAddresses: Set<Address>): NetworkAddress {

View file

@ -6,11 +6,11 @@ import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
import com.tangem.common.test.domain.walletmanager.MockUpdateWalletManagerResultFactory
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus
import com.tangem.domain.tokens.model.NetworkAddress
import com.tangem.domain.tokens.model.NetworkStatus
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.walletmanager.model.Address
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
import org.junit.Test
@ -57,17 +57,17 @@ internal class NetworkStatusFactoryTest(private val model: Model) {
val currencies = with(MockCryptoCurrencyFactory()) { setOf(ethereum, createToken(Blockchain.Ethereum)) }
val txHistoryItem = TxHistoryItem(
val txInfo = TxInfo(
txHash = "erroribus",
timestampInMillis = 2771,
isOutgoing = false,
destinationType = TxHistoryItem.DestinationType.Single(
addressType = TxHistoryItem.AddressType.User("0x1"),
destinationType = TxInfo.DestinationType.Single(
addressType = TxInfo.AddressType.User("0x1"),
),
sourceType = TxHistoryItem.SourceType.Single("0x2"),
sourceType = TxInfo.SourceType.Single("0x2"),
interactionAddressType = null,
status = TxHistoryItem.TransactionStatus.Confirmed,
type = TxHistoryItem.TransactionType.Transfer,
status = TxInfo.TransactionStatus.Confirmed,
type = TxInfo.TransactionType.Transfer,
amount = BigDecimal.ONE,
)
@ -218,7 +218,7 @@ internal class NetworkStatusFactoryTest(private val model: Model) {
currencies.last().id to CryptoCurrencyAmountStatus.NotFound,
),
pendingTransactions = mapOf(
currencies.first().id to setOf(txHistoryItem),
currencies.first().id to setOf(txInfo),
currencies.last().id to setOf(),
),
source = StatusSource.ACTUAL,

View file

@ -10,9 +10,9 @@ import com.tangem.data.txhistory.repository.paging.TxHistoryPagingSource
import com.tangem.datasource.local.txhistory.TxHistoryItemsStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryState
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.txhistory.repository.TxHistoryRepository
@ -56,7 +56,7 @@ class DefaultTxHistoryRepository(
currency: CryptoCurrency,
pageSize: Int,
refresh: Boolean,
): Flow<PagingData<TxHistoryItem>> {
): Flow<PagingData<TxInfo>> {
val pager = Pager(
config = PagingConfig(
pageSize = pageSize,
@ -102,7 +102,7 @@ class DefaultTxHistoryRepository(
currency: CryptoCurrency,
pageSize: Int,
refresh: Boolean,
): List<TxHistoryItem> = withContext(dispatchers.io) {
): List<TxInfo> = withContext(dispatchers.io) {
try {
cacheRegistry.invokeOnExpire(
key = getTxHistoryPageKey(currency, userWalletId, Page.Initial),

View file

@ -3,12 +3,12 @@ package com.tangem.data.txhistory.repository
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.txhistory.repository.paging.TxHistoryPageBatchFetcher
import com.tangem.datasource.local.txhistory.TxHistoryItemsStore
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.model.TxHistoryListBatchFlow
import com.tangem.domain.txhistory.model.TxHistoryListBatchingContext
import com.tangem.domain.txhistory.model.TxHistoryListConfig
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.repository.TxHistoryRepositoryV2
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.walletmanager.utils.SdkPageConverter
@ -39,7 +39,7 @@ internal class RefactoredTxHistoryRepository(
private fun createFetcher(
batchSize: Int,
): TxHistoryPageBatchFetcher<TxHistoryListConfig, PaginationWrapper<TxHistoryItem>> =
): TxHistoryPageBatchFetcher<TxHistoryListConfig, PaginationWrapper<TxInfo>> =
TxHistoryPageBatchFetcher { request, _ ->
val wrappedItems = loadItems(request, batchSize)
BatchFetchResult.Success(
@ -52,7 +52,7 @@ internal class RefactoredTxHistoryRepository(
private suspend fun loadItems(
request: TxHistoryPageBatchFetcher.Request<TxHistoryListConfig>,
batchSize: Int,
): PaginationWrapper<TxHistoryItem> {
): PaginationWrapper<TxInfo> {
cacheRegistry.invokeOnExpire(
key = getTxHistoryPageKey(request.page, request.params),
skipCache = request.params.refresh,
@ -76,7 +76,7 @@ internal class RefactoredTxHistoryRepository(
private suspend fun TxHistoryItemsStore.getSync(
pageToLoad: Page,
config: TxHistoryListConfig,
): PaginationWrapper<TxHistoryItem> {
): PaginationWrapper<TxInfo> {
val storedItems = requireNotNull(getSyncOrNull(config.storeKey, pageToLoad)) {
"The transaction history page #$pageToLoad could not be retrieved"
}
@ -84,9 +84,9 @@ internal class RefactoredTxHistoryRepository(
return if (pageToLoad is Page.Initial) storedItems.addRecentTransactions(config) else storedItems
}
private suspend fun PaginationWrapper<TxHistoryItem>.addRecentTransactions(
private suspend fun PaginationWrapper<TxInfo>.addRecentTransactions(
config: TxHistoryListConfig,
): PaginationWrapper<TxHistoryItem> {
): PaginationWrapper<TxInfo> {
val recentItems = walletManagersFacade.getRecentTransactions(
userWalletId = config.userWalletId,
currency = config.currency,
@ -104,7 +104,7 @@ internal class RefactoredTxHistoryRepository(
recentItems.joinToString(
prefix = "[",
postfix = "]",
transform = TxHistoryItem::txHash,
transform = TxInfo::txHash,
),
)
@ -112,11 +112,11 @@ internal class RefactoredTxHistoryRepository(
}
}
private fun List<TxHistoryItem>.filterUnconfirmedTransaction(): List<TxHistoryItem> {
return filter { it.status == TxHistoryItem.TransactionStatus.Unconfirmed }
private fun List<TxInfo>.filterUnconfirmedTransaction(): List<TxInfo> {
return filter { it.status == TxInfo.TransactionStatus.Unconfirmed }
}
private fun List<TxHistoryItem>.filterIfTxAlreadyAdded(apiItems: List<TxHistoryItem>): List<TxHistoryItem> {
private fun List<TxInfo>.filterIfTxAlreadyAdded(apiItems: List<TxInfo>): List<TxInfo> {
return filter { item -> apiItems.none { it.txHash == item.txHash } }
}

View file

@ -1,8 +1,8 @@
package com.tangem.data.txhistory.repository.paging
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.pagination.BatchFetchResult
import com.tangem.pagination.exception.EndOfPaginationException
import com.tangem.pagination.fetcher.BatchFetcher
@ -10,7 +10,7 @@ import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableStateFlow
internal class TxHistoryPageBatchFetcher<TRequestParams : Any, TData : PaginationWrapper<TxHistoryItem>>(
internal class TxHistoryPageBatchFetcher<TRequestParams : Any, TData : PaginationWrapper<TxInfo>>(
private val subFetcher: SubFetcher<TRequestParams, TData>,
) : BatchFetcher<TRequestParams, TData> {
data class Request<TRequestParams>(val page: Page, val params: TRequestParams)

View file

@ -4,10 +4,10 @@ import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.datasource.local.txhistory.TxHistoryItemsStore
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.Page
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.walletmanager.utils.SdkPageConverter
import com.tangem.domain.wallets.models.UserWalletId
@ -18,18 +18,18 @@ internal class TxHistoryPagingSource(
private val txHistoryItemsStore: TxHistoryItemsStore,
private val walletManagersFacade: WalletManagersFacade,
private val cacheRegistry: CacheRegistry,
) : PagingSource<Page, TxHistoryItem>() {
) : PagingSource<Page, TxInfo>() {
private val storeKey = TxHistoryItemsStore.Key(sourceParams.userWalletId, sourceParams.currency)
private val sdkPageConverter by lazy { SdkPageConverter() }
override val keyReuseSupported: Boolean get() = true
override fun getRefreshKey(state: PagingState<Page, TxHistoryItem>): Page? {
override fun getRefreshKey(state: PagingState<Page, TxInfo>): Page? {
return null
}
override suspend fun load(params: LoadParams<Page>): LoadResult<Page, TxHistoryItem> {
override suspend fun load(params: LoadParams<Page>): LoadResult<Page, TxInfo> {
val pageToLoad = params.key ?: Page.Initial
return try {
@ -50,7 +50,7 @@ internal class TxHistoryPagingSource(
}
}
private suspend fun loadItems(pageToLoad: Page, pageSize: Int, refresh: Boolean): PaginationWrapper<TxHistoryItem> {
private suspend fun loadItems(pageToLoad: Page, pageSize: Int, refresh: Boolean): PaginationWrapper<TxInfo> {
cacheRegistry.invokeOnExpire(
key = getTxHistoryPageKey(pageToLoad),
skipCache = refresh,
@ -71,7 +71,7 @@ internal class TxHistoryPagingSource(
txHistoryItemsStore.store(key = storeKey, value = wrappedItems)
}
private suspend fun TxHistoryItemsStore.getSync(pageToLoad: Page): PaginationWrapper<TxHistoryItem> {
private suspend fun TxHistoryItemsStore.getSync(pageToLoad: Page): PaginationWrapper<TxInfo> {
val storedItems = requireNotNull(getSyncOrNull(storeKey, pageToLoad)) {
"The transaction history page #$pageToLoad could not be retrieved"
}
@ -79,7 +79,7 @@ internal class TxHistoryPagingSource(
return if (pageToLoad is Page.Initial) storedItems.addRecentTransactions() else storedItems
}
private suspend fun PaginationWrapper<TxHistoryItem>.addRecentTransactions(): PaginationWrapper<TxHistoryItem> {
private suspend fun PaginationWrapper<TxInfo>.addRecentTransactions(): PaginationWrapper<TxInfo> {
val recentItems = walletManagersFacade.getRecentTransactions(
userWalletId = sourceParams.userWalletId,
currency = sourceParams.currency,
@ -97,7 +97,7 @@ internal class TxHistoryPagingSource(
recentItems.joinToString(
prefix = "[",
postfix = "]",
transform = TxHistoryItem::txHash,
transform = TxInfo::txHash,
),
)
@ -105,11 +105,11 @@ internal class TxHistoryPagingSource(
}
}
private fun List<TxHistoryItem>.filterUnconfirmedTransaction(): List<TxHistoryItem> {
return filter { it.status == TxHistoryItem.TransactionStatus.Unconfirmed }
private fun List<TxInfo>.filterUnconfirmedTransaction(): List<TxInfo> {
return filter { it.status == TxInfo.TransactionStatus.Unconfirmed }
}
private fun List<TxHistoryItem>.filterIfTxAlreadyAdded(apiItems: List<TxHistoryItem>): List<TxHistoryItem> {
private fun List<TxInfo>.filterIfTxAlreadyAdded(apiItems: List<TxInfo>): List<TxInfo> {
return filter { item -> apiItems.none { it.txHash == item.txHash } }
}

View file

@ -27,10 +27,10 @@ import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.common.util.hasDerivation
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryState
import com.tangem.domain.walletmanager.model.RentData
import com.tangem.domain.walletmanager.model.SmartContractMethod
@ -234,7 +234,7 @@ class DefaultWalletManagersFacade(
currency: CryptoCurrency,
page: Page,
pageSize: Int,
): PaginationWrapper<TxHistoryItem> {
): PaginationWrapper<TxInfo> {
val walletManager = getOrCreateWalletManager(
userWalletId = userWalletId,
network = currency.network,
@ -534,10 +534,7 @@ class DefaultWalletManagersFacade(
return walletManager?.createTransaction(amount, fee, destination)
}
override suspend fun getRecentTransactions(
userWalletId: UserWalletId,
currency: CryptoCurrency,
): List<TxHistoryItem> {
override suspend fun getRecentTransactions(userWalletId: UserWalletId, currency: CryptoCurrency): List<TxInfo> {
val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network)
if (walletManager == null) {

View file

@ -13,10 +13,10 @@ import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.blockchain.nft.models.NFTAsset
import com.tangem.blockchain.nft.models.NFTCollection
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryState
import com.tangem.domain.walletmanager.model.RentData
import com.tangem.domain.walletmanager.model.TokenInfo
@ -106,7 +106,7 @@ interface WalletManagersFacade {
currency: CryptoCurrency,
page: Page,
pageSize: Int,
): PaginationWrapper<TxHistoryItem>
): PaginationWrapper<TxInfo>
@Deprecated("Will be removed in future")
suspend fun getOrCreateWalletManager(
@ -216,7 +216,7 @@ interface WalletManagersFacade {
): TransactionData?
/** Get recent transactions of [userWalletId] for [currency] */
suspend fun getRecentTransactions(userWalletId: UserWalletId, currency: CryptoCurrency): List<TxHistoryItem>
suspend fun getRecentTransactions(userWalletId: UserWalletId, currency: CryptoCurrency): List<TxInfo>
@Suppress("LongParameterList")
suspend fun tokenBalance(

View file

@ -1,17 +1,17 @@
package com.tangem.domain.walletmanager.model
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
// TODO: [REDACTED_JIRA] move to txhistory module
sealed class CryptoCurrencyTransaction {
abstract val txHistoryItem: TxHistoryItem
abstract val txInfo: TxInfo
data class Coin(override val txHistoryItem: TxHistoryItem) : CryptoCurrencyTransaction()
data class Coin(override val txInfo: TxInfo) : CryptoCurrencyTransaction()
data class Token(
val tokenId: String?,
val tokenContractAddress: String,
override val txHistoryItem: TxHistoryItem,
override val txInfo: TxInfo,
) : CryptoCurrencyTransaction()
}

View file

@ -1,18 +1,18 @@
package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.walletmanager.model.SmartContractMethod
import com.tangem.utils.converter.Converter
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem as SdkTransactionHistoryItem
internal class SdkTransactionHistoryItemConverter(
smartContractMethods: Map<String, SmartContractMethod>,
) : Converter<SdkTransactionHistoryItem, TxHistoryItem> {
) : Converter<SdkTransactionHistoryItem, TxInfo> {
private val typeConverter by lazy { SdkTransactionTypeConverter(smartContractMethods) }
override fun convert(value: SdkTransactionHistoryItem): TxHistoryItem = TxHistoryItem(
override fun convert(value: SdkTransactionHistoryItem): TxInfo = TxInfo(
txHash = value.txHash,
timestampInMillis = value.timestamp,
isOutgoing = value.isOutgoing,
@ -20,35 +20,35 @@ internal class SdkTransactionHistoryItemConverter(
sourceType = value.sourceType.toDomain(),
interactionAddressType = value.extractInteractionAddressType(),
status = when (value.status) {
SdkTransactionHistoryItem.TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
SdkTransactionHistoryItem.TransactionStatus.Failed -> TxHistoryItem.TransactionStatus.Failed
SdkTransactionHistoryItem.TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
SdkTransactionHistoryItem.TransactionStatus.Confirmed -> TxInfo.TransactionStatus.Confirmed
SdkTransactionHistoryItem.TransactionStatus.Failed -> TxInfo.TransactionStatus.Failed
SdkTransactionHistoryItem.TransactionStatus.Unconfirmed -> TxInfo.TransactionStatus.Unconfirmed
},
type = typeConverter.convert(value.type),
amount = requireNotNull(value.amount.value) { "Transaction amount value must not be null" },
)
private fun SdkTransactionHistoryItem.SourceType.toDomain(): TxHistoryItem.SourceType = when (this) {
is TransactionHistoryItem.SourceType.Single -> TxHistoryItem.SourceType.Single(address)
is TransactionHistoryItem.SourceType.Multiple -> TxHistoryItem.SourceType.Multiple(addresses)
private fun SdkTransactionHistoryItem.SourceType.toDomain(): TxInfo.SourceType = when (this) {
is TransactionHistoryItem.SourceType.Single -> TxInfo.SourceType.Single(address)
is TransactionHistoryItem.SourceType.Multiple -> TxInfo.SourceType.Multiple(addresses)
}
private fun SdkTransactionHistoryItem.DestinationType.toDomain(): TxHistoryItem.DestinationType = when (this) {
is SdkTransactionHistoryItem.DestinationType.Single -> TxHistoryItem.DestinationType.Single(
private fun SdkTransactionHistoryItem.DestinationType.toDomain(): TxInfo.DestinationType = when (this) {
is SdkTransactionHistoryItem.DestinationType.Single -> TxInfo.DestinationType.Single(
addressType.toDomain(),
)
is SdkTransactionHistoryItem.DestinationType.Multiple -> TxHistoryItem.DestinationType.Multiple(
is SdkTransactionHistoryItem.DestinationType.Multiple -> TxInfo.DestinationType.Multiple(
addressTypes.map { it.toDomain() },
)
}
private fun SdkTransactionHistoryItem.AddressType.toDomain(): TxHistoryItem.AddressType = when (this) {
is SdkTransactionHistoryItem.AddressType.Contract -> TxHistoryItem.AddressType.Contract(address)
is SdkTransactionHistoryItem.AddressType.User -> TxHistoryItem.AddressType.User(address)
is SdkTransactionHistoryItem.AddressType.Validator -> TxHistoryItem.AddressType.Validator(address)
private fun SdkTransactionHistoryItem.AddressType.toDomain(): TxInfo.AddressType = when (this) {
is SdkTransactionHistoryItem.AddressType.Contract -> TxInfo.AddressType.Contract(address)
is SdkTransactionHistoryItem.AddressType.User -> TxInfo.AddressType.User(address)
is SdkTransactionHistoryItem.AddressType.Validator -> TxInfo.AddressType.Validator(address)
}
private fun SdkTransactionHistoryItem.extractInteractionAddressType(): TxHistoryItem.InteractionAddressType? {
private fun SdkTransactionHistoryItem.extractInteractionAddressType(): TxInfo.InteractionAddressType? {
return when (val transactionType = type) {
SdkTransactionHistoryItem.TransactionType.Transfer -> if (isOutgoing) {
mapToInteractionAddressType(destinationType = destinationType)
@ -61,7 +61,7 @@ internal class SdkTransactionHistoryItemConverter(
-> mapToInteractionAddressType(destinationType = destinationType)
is SdkTransactionHistoryItem.TransactionType.TronStakingTransactionType.VoteWitnessContract -> {
TxHistoryItem.InteractionAddressType.Validator(address = transactionType.validatorAddress)
TxInfo.InteractionAddressType.Validator(address = transactionType.validatorAddress)
}
else -> null
}
@ -69,19 +69,19 @@ internal class SdkTransactionHistoryItemConverter(
private fun mapToInteractionAddressType(
destinationType: SdkTransactionHistoryItem.DestinationType,
): TxHistoryItem.InteractionAddressType {
): TxInfo.InteractionAddressType {
return when (destinationType) {
is TransactionHistoryItem.DestinationType.Multiple -> TxHistoryItem.InteractionAddressType.Multiple(
is TransactionHistoryItem.DestinationType.Multiple -> TxInfo.InteractionAddressType.Multiple(
destinationType.addressTypes.map { it.address },
)
is TransactionHistoryItem.DestinationType.Single -> when (destinationType.addressType) {
is TransactionHistoryItem.AddressType.Contract -> TxHistoryItem.InteractionAddressType.Contract(
is TransactionHistoryItem.AddressType.Contract -> TxInfo.InteractionAddressType.Contract(
destinationType.addressType.address,
)
is TransactionHistoryItem.AddressType.User -> TxHistoryItem.InteractionAddressType.User(
is TransactionHistoryItem.AddressType.User -> TxInfo.InteractionAddressType.User(
destinationType.addressType.address,
)
is TransactionHistoryItem.AddressType.Validator -> TxHistoryItem.InteractionAddressType.Validator(
is TransactionHistoryItem.AddressType.Validator -> TxInfo.InteractionAddressType.Validator(
destinationType.addressType.address,
)
}
@ -90,13 +90,13 @@ internal class SdkTransactionHistoryItemConverter(
private fun mapToInteractionAddressType(
sourceType: SdkTransactionHistoryItem.SourceType,
): TxHistoryItem.InteractionAddressType {
): TxInfo.InteractionAddressType {
return when (sourceType) {
is TransactionHistoryItem.SourceType.Multiple -> TxHistoryItem.InteractionAddressType.Multiple(
is TransactionHistoryItem.SourceType.Multiple -> TxInfo.InteractionAddressType.Multiple(
sourceType.addresses,
)
is TransactionHistoryItem.SourceType.Single -> {
TxHistoryItem.InteractionAddressType.User(sourceType.address)
TxInfo.InteractionAddressType.User(sourceType.address)
}
}
}

View file

@ -1,15 +1,15 @@
package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem.TransactionType
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.walletmanager.model.SmartContractMethod
import com.tangem.utils.converter.Converter
internal class SdkTransactionTypeConverter(
private val smartContractMethods: Map<String, SmartContractMethod>,
) : Converter<TransactionType, TxHistoryItem.TransactionType> {
) : Converter<TransactionType, TxInfo.TransactionType> {
override fun convert(value: TransactionType): TxHistoryItem.TransactionType {
override fun convert(value: TransactionType): TxInfo.TransactionType {
return when (value) {
is TransactionType.ContractMethod -> {
getTransactionType(methodName = smartContractMethods[value.id]?.name)
@ -18,49 +18,49 @@ internal class SdkTransactionTypeConverter(
getTransactionType(methodName = value.name)
}
is TransactionType.Transfer -> {
TxHistoryItem.TransactionType.Transfer
TxInfo.TransactionType.Transfer
}
is TransactionType.TronStakingTransactionType.FreezeBalanceV2Contract -> {
TxHistoryItem.TransactionType.Staking.Stake
TxInfo.TransactionType.Staking.Stake
}
is TransactionType.TronStakingTransactionType.UnfreezeBalanceV2Contract -> {
TxHistoryItem.TransactionType.Staking.Unstake
TxInfo.TransactionType.Staking.Unstake
}
is TransactionType.TronStakingTransactionType.VoteWitnessContract -> {
TxHistoryItem.TransactionType.Staking.Vote(value.validatorAddress)
TxInfo.TransactionType.Staking.Vote(value.validatorAddress)
}
is TransactionType.TronStakingTransactionType.WithdrawBalanceContract -> {
TxHistoryItem.TransactionType.Staking.ClaimRewards
TxInfo.TransactionType.Staking.ClaimRewards
}
is TransactionType.TronStakingTransactionType.WithdrawExpireUnfreezeContract -> {
TxHistoryItem.TransactionType.Staking.Withdraw
TxInfo.TransactionType.Staking.Withdraw
}
}
}
private fun getTransactionType(methodName: String?): TxHistoryItem.TransactionType {
private fun getTransactionType(methodName: String?): TxInfo.TransactionType {
return when (methodName) {
"transfer" -> TxHistoryItem.TransactionType.Transfer
"approve" -> TxHistoryItem.TransactionType.Approve
"swap" -> TxHistoryItem.TransactionType.Swap
"transfer" -> TxInfo.TransactionType.Transfer
"approve" -> TxInfo.TransactionType.Approve
"swap" -> TxInfo.TransactionType.Swap
"buyVoucher",
"buyVoucherPOL",
"delegate",
-> TxHistoryItem.TransactionType.Staking.Stake
-> TxInfo.TransactionType.Staking.Stake
"sellVoucher_new",
"sellVoucher_newPOL",
"undelegate",
-> TxHistoryItem.TransactionType.Staking.Unstake
-> TxInfo.TransactionType.Staking.Unstake
"unstakeClaimTokens_new",
"unstakeClaimTokens_newPOL",
"claim",
-> TxHistoryItem.TransactionType.Staking.Withdraw
-> TxInfo.TransactionType.Staking.Withdraw
"withdrawRewards",
"withdrawRewardsPOL",
-> TxHistoryItem.TransactionType.Staking.ClaimRewards
"redelegate" -> TxHistoryItem.TransactionType.Staking.Restake
null -> TxHistoryItem.TransactionType.UnknownOperation
else -> TxHistoryItem.TransactionType.Operation(name = methodName.replaceFirstChar { it.titlecase() })
-> TxInfo.TransactionType.Staking.ClaimRewards
"redelegate" -> TxInfo.TransactionType.Staking.Restake
null -> TxInfo.TransactionType.UnknownOperation
else -> TxInfo.TransactionType.Operation(name = methodName.replaceFirstChar { it.titlecase() })
}
}
}

View file

@ -1,14 +1,14 @@
package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.common.*
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.walletmanager.model.Address
import com.tangem.utils.converter.Converter
import timber.log.Timber
import java.math.BigDecimal
/**
* Convert [TransactionData] to [TxHistoryItem]
* Convert [TransactionData] to [TxInfo]
*
* @property walletAddresses wallet addresses
*
@ -17,30 +17,30 @@ import java.math.BigDecimal
internal class TransactionDataToTxHistoryItemConverter(
private val walletAddresses: Set<Address>,
private val feePaidCurrency: FeePaidCurrency,
) : Converter<TransactionData.Uncompiled, TxHistoryItem?> {
) : Converter<TransactionData.Uncompiled, TxInfo?> {
override fun convert(value: TransactionData.Uncompiled): TxHistoryItem? {
override fun convert(value: TransactionData.Uncompiled): TxInfo? {
val hash = value.hash ?: return null
val millis = value.date?.timeInMillis ?: return null
val amount = getTransactionAmountValue(value.amount, value.fee?.amount) ?: return null
val isOutgoing = value.sourceAddress in walletAddresses.map(Address::value)
return TxHistoryItem(
return TxInfo(
txHash = hash,
timestampInMillis = millis,
isOutgoing = isOutgoing,
destinationType = TxHistoryItem.DestinationType.Single(
addressType = TxHistoryItem.AddressType.User(value.destinationAddress),
destinationType = TxInfo.DestinationType.Single(
addressType = TxInfo.AddressType.User(value.destinationAddress),
),
sourceType = TxHistoryItem.SourceType.Single(value.sourceAddress),
interactionAddressType = TxHistoryItem.InteractionAddressType.User(
sourceType = TxInfo.SourceType.Single(value.sourceAddress),
interactionAddressType = TxInfo.InteractionAddressType.User(
address = if (isOutgoing) value.destinationAddress else value.sourceAddress,
),
status = when (value.status) {
TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
TransactionStatus.Confirmed -> TxInfo.TransactionStatus.Confirmed
TransactionStatus.Unconfirmed -> TxInfo.TransactionStatus.Unconfirmed
},
type = TxHistoryItem.TransactionType.Transfer,
type = TxInfo.TransactionType.Transfer,
amount = amount,
)
}

View file

@ -139,7 +139,7 @@ internal class UpdateWalletManagerResultFactory {
CryptoCurrencyTransaction.Token(
tokenId = type.token.id,
tokenContractAddress = type.token.contractAddress,
txHistoryItem = txHistoryItem,
txInfo = txHistoryItem,
)
}
is AmountType.FeeResource,

View file

@ -1,8 +1,21 @@
package com.tangem.domain.txhistory.models
package com.tangem.domain.models.network
import java.math.BigDecimal
data class TxHistoryItem(
/**
* Represents information about a transaction. Do not use it for sending transactions.
*
* @property txHash transaction hash
* @property timestampInMillis transaction timestamp in milliseconds
* @property isOutgoing flag that determines the direction of the transaction (incoming or outgoing)
* @property destinationType type of destination (single or multiple)
* @property sourceType type of source (single or multiple)
* @property interactionAddressType interaction address type
* @property status transaction status
* @property type transaction type
* @property amount transaction amount
*/
data class TxInfo(
val txHash: String,
val timestampInMillis: Long,
val isOutgoing: Boolean,
@ -14,18 +27,28 @@ data class TxHistoryItem(
val amount: BigDecimal,
) {
/** Destination type*/
sealed class DestinationType {
/**
* Single
*
* @property addressType address type
*/
data class Single(val addressType: AddressType) : DestinationType()
/**
* Multiple
*
* @property addressTypes addresses types
*/
data class Multiple(val addressTypes: List<AddressType>) : DestinationType()
}
sealed class SourceType {
data class Single(val address: String) : SourceType()
data class Multiple(val addresses: List<String>) : SourceType()
}
/** Address type */
sealed class AddressType {
/** Address value */
abstract val address: String
data class User(override val address: String) : AddressType()
@ -33,6 +56,25 @@ data class TxHistoryItem(
data class Validator(override val address: String) : AddressType()
}
/** Source type */
sealed class SourceType {
/**
* Single
*
* @property address address
*/
data class Single(val address: String) : SourceType()
/**
* Multiple
*
* @property addresses addresses
*/
data class Multiple(val addresses: List<String>) : SourceType()
}
/** Transaction type */
sealed interface TransactionType {
data object Transfer : TransactionType
data object Approve : TransactionType
@ -50,6 +92,7 @@ data class TxHistoryItem(
}
}
/** Transaction status */
sealed class TransactionStatus {
data object Failed : TransactionStatus()
data object Unconfirmed : TransactionStatus()

View file

@ -2,8 +2,8 @@ package com.tangem.domain.tokens.model
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.getResultStatusSource
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.txhistory.models.TxHistoryItem
import java.math.BigDecimal
/**
@ -44,7 +44,7 @@ data class CryptoCurrencyStatus(
open val hasCurrentNetworkTransactions: Boolean = false
/** The pending cryptocurrency transactions. */
open val pendingTransactions: Set<TxHistoryItem> = emptySet()
open val pendingTransactions: Set<TxInfo> = emptySet()
/** The network address */
open val networkAddress: NetworkAddress? = null
@ -132,7 +132,7 @@ data class CryptoCurrencyStatus(
override val priceChange: BigDecimal,
override val yieldBalance: YieldBalance?,
override val hasCurrentNetworkTransactions: Boolean,
override val pendingTransactions: Set<TxHistoryItem>,
override val pendingTransactions: Set<TxInfo>,
override val networkAddress: NetworkAddress,
override val sources: Sources,
) : Value(isError = false)
@ -155,7 +155,7 @@ data class CryptoCurrencyStatus(
override val priceChange: BigDecimal?,
override val yieldBalance: YieldBalance?,
override val hasCurrentNetworkTransactions: Boolean,
override val pendingTransactions: Set<TxHistoryItem>,
override val pendingTransactions: Set<TxInfo>,
override val networkAddress: NetworkAddress,
override val sources: Sources,
) : Value(isError = false)
@ -172,7 +172,7 @@ data class CryptoCurrencyStatus(
override val amount: BigDecimal,
override val yieldBalance: YieldBalance?,
override val hasCurrentNetworkTransactions: Boolean,
override val pendingTransactions: Set<TxHistoryItem>,
override val pendingTransactions: Set<TxInfo>,
override val networkAddress: NetworkAddress,
override val sources: Sources,
) : Value(isError = false)

View file

@ -2,7 +2,7 @@ package com.tangem.domain.tokens.model
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.Network
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import java.math.BigDecimal
/**
@ -58,7 +58,7 @@ data class NetworkStatus(val network: Network, val value: Value) {
data class Verified(
val address: NetworkAddress,
val amounts: Map<CryptoCurrency.ID, CryptoCurrencyAmountStatus>,
val pendingTransactions: Map<CryptoCurrency.ID, Set<TxHistoryItem>>,
val pendingTransactions: Map<CryptoCurrency.ID, Set<TxInfo>>,
override val source: StatusSource,
) : Value()

View file

@ -1,10 +1,10 @@
package com.tangem.domain.txhistory.model
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.pagination.BatchFlow
import com.tangem.pagination.BatchingContext
typealias TxHistoryListBatchingContext = BatchingContext<Int, TxHistoryListConfig, Nothing>
typealias TxHistoryListBatchFlow = BatchFlow<Int, PaginationWrapper<TxHistoryItem>, Nothing>
typealias TxHistoryListBatchFlow = BatchFlow<Int, PaginationWrapper<TxInfo>, Nothing>

View file

@ -2,8 +2,8 @@ package com.tangem.domain.txhistory.repository
import androidx.paging.PagingData
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.wallets.models.UserWalletId
@ -20,7 +20,7 @@ interface TxHistoryRepository {
currency: CryptoCurrency,
pageSize: Int,
refresh: Boolean,
): Flow<PagingData<TxHistoryItem>>
): Flow<PagingData<TxInfo>>
fun getTxExploreUrl(txHash: String, networkId: Network.ID): String
@ -33,5 +33,5 @@ interface TxHistoryRepository {
currency: CryptoCurrency,
pageSize: Int,
refresh: Boolean,
): List<TxHistoryItem>
): List<TxInfo>
}

View file

@ -1,8 +1,8 @@
package com.tangem.domain.txhistory.usecase
import arrow.core.Either
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.repository.TxHistoryRepository
import com.tangem.domain.wallets.models.UserWalletId
@ -26,7 +26,7 @@ class GetFixedTxHistoryItemsUseCase(
currency: CryptoCurrency,
pageSize: Int = DEFAULT_PAGE_SIZE,
refresh: Boolean = false,
): Either<TxHistoryListError, Flow<List<TxHistoryItem>>> {
): Either<TxHistoryListError, Flow<List<TxInfo>>> {
return Either.catch {
flow {
emit(repository.getFixedSizeTxHistoryItems(userWalletId, currency, pageSize, refresh))
@ -39,7 +39,7 @@ class GetFixedTxHistoryItemsUseCase(
currency: CryptoCurrency,
pageSize: Int = DEFAULT_PAGE_SIZE,
refresh: Boolean = false,
): Either<TxHistoryListError, List<TxHistoryItem>> {
): Either<TxHistoryListError, List<TxInfo>> {
return Either.catch {
repository.getFixedSizeTxHistoryItems(userWalletId, currency, pageSize, refresh)
}.mapLeft { TxHistoryListError.DataError(it) }

View file

@ -3,8 +3,8 @@ package com.tangem.domain.txhistory.usecase
import androidx.paging.PagingData
import arrow.core.Either
import arrow.core.raise.either
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.repository.TxHistoryRepository
import com.tangem.domain.wallets.models.UserWalletId
@ -22,7 +22,7 @@ class GetTxHistoryItemsUseCase(private val repository: TxHistoryRepository) {
currency: CryptoCurrency,
pageSize: Int = DEFAULT_PAGE_SIZE,
refresh: Boolean = false,
): Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>> {
): Either<TxHistoryListError, Flow<PagingData<TxInfo>>> {
return either {
repository
.getTxHistoryItems(userWalletId, currency, pageSize, refresh)

View file

@ -9,13 +9,13 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.RECENT_DEFAULT_COUNT
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.RECENT_KEY_TAG
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.emptyListState
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isZero
import kotlinx.collections.immutable.ImmutableList
@ -23,21 +23,21 @@ import kotlinx.collections.immutable.toPersistentList
internal class SendRecipientHistoryListConverter(
private val cryptoCurrency: CryptoCurrency,
) : Converter<List<TxHistoryItem>, ImmutableList<DestinationRecipientListUM>> {
) : Converter<List<TxInfo>, ImmutableList<DestinationRecipientListUM>> {
override fun convert(value: List<TxHistoryItem>): ImmutableList<DestinationRecipientListUM> {
override fun convert(value: List<TxInfo>): ImmutableList<DestinationRecipientListUM> {
return value.filterRecipients(cryptoCurrency).ifEmpty {
emptyListState(RECENT_KEY_TAG, RECENT_DEFAULT_COUNT)
}
}
private fun List<TxHistoryItem>.filterRecipients(cryptoCurrency: CryptoCurrency) = this.filter { item ->
val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer
val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User
private fun List<TxInfo>.filterRecipients(cryptoCurrency: CryptoCurrency) = this.filter { item ->
val isTransfer = item.type == TxInfo.TransactionType.Transfer
val isNotContract = item.interactionAddressType is TxInfo.InteractionAddressType.User
val isSingleAddress = if (item.isOutgoing) {
item.destinationType is TxHistoryItem.DestinationType.Single
item.destinationType is TxInfo.DestinationType.Single
} else {
item.sourceType is TxHistoryItem.SourceType.Single
item.sourceType is TxInfo.SourceType.Single
}
val notZero = !item.amount.isZero()
isTransfer && isSingleAddress && isNotContract && item.isOutgoing && notZero
@ -54,31 +54,31 @@ internal class SendRecipientHistoryListConverter(
)
}.toPersistentList()
private fun TxHistoryItem.extractAddress(): TextReference = if (isOutgoing) {
private fun TxInfo.extractAddress(): TextReference = if (isOutgoing) {
when (val destination = destinationType) {
is TxHistoryItem.DestinationType.Multiple -> resourceReference(
is TxInfo.DestinationType.Multiple -> resourceReference(
R.string.transaction_history_multiple_addresses,
)
is TxHistoryItem.DestinationType.Single -> stringReference(destination.addressType.address)
is TxInfo.DestinationType.Single -> stringReference(destination.addressType.address)
}
} else {
when (val source = sourceType) {
is TxHistoryItem.SourceType.Multiple -> resourceReference(R.string.transaction_history_multiple_addresses)
is TxHistoryItem.SourceType.Single -> stringReference(source.address)
is TxInfo.SourceType.Multiple -> resourceReference(R.string.transaction_history_multiple_addresses)
is TxInfo.SourceType.Single -> stringReference(source.address)
}
}
private fun TxHistoryItem.extractIconRes() = if (isOutgoing) {
private fun TxInfo.extractIconRes() = if (isOutgoing) {
R.drawable.ic_arrow_up_24
} else {
R.drawable.ic_arrow_down_24
}
private fun TxHistoryItem.getAmount(cryptoCurrency: CryptoCurrency): String {
private fun TxInfo.getAmount(cryptoCurrency: CryptoCurrency): String {
return amount.format { crypto(cryptoCurrency) }
}
private fun TxHistoryItem.extractTimestamp(): TextReference {
private fun TxInfo.extractTimestamp(): TextReference {
val date = timestampInMillis.toDateFormatWithTodayYesterday(
formatter = DateTimeFormatters.dateDDMMYYYY,
)

View file

@ -1,10 +1,10 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.model.converters.SendRecipientHistoryListConverter
import com.tangem.features.send.v2.subcomponents.destination.model.converters.SendRecipientWalletListConverter
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationWalletUM
import com.tangem.utils.transformer.Transformer
@ -13,7 +13,7 @@ internal class SendDestinationRecentListTransformer(
private val cryptoCurrency: CryptoCurrency,
private val isUtxoConsolidationAvailable: Boolean,
private val destinationWalletList: List<DestinationWalletUM>,
private val txHistoryList: List<TxHistoryItem>,
private val txHistoryList: List<TxInfo>,
) : Transformer<DestinationUM> {
override fun transform(prevState: DestinationUM): DestinationUM {
val state = prevState as? DestinationUM.Content ?: return prevState

View file

@ -2,11 +2,11 @@ package com.tangem.features.send.impl.presentation.state.recipient
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.transaction.error.AddressValidation
import com.tangem.domain.transaction.error.AddressValidationResult
import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.domain.AvailableWallet
import com.tangem.features.send.impl.presentation.state.SendUiState
@ -42,7 +42,7 @@ internal class RecipientSendFactory(
)
}
fun onLoadedHistoryList(txHistory: List<TxHistoryItem>): SendUiState {
fun onLoadedHistoryList(txHistory: List<TxInfo>): SendUiState {
val state = currentStateProvider()
return state.copy(
recipientState = state.recipientState?.copy(

View file

@ -9,9 +9,9 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.domain.SendRecipientListContent
import com.tangem.features.send.impl.presentation.state.recipient.utils.RECENT_DEFAULT_COUNT
@ -24,22 +24,22 @@ import kotlinx.collections.immutable.toPersistentList
internal class SendRecipientHistoryListConverter(
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
) : Converter<List<TxHistoryItem>, ImmutableList<SendRecipientListContent>> {
) : Converter<List<TxInfo>, ImmutableList<SendRecipientListContent>> {
override fun convert(value: List<TxHistoryItem>): ImmutableList<SendRecipientListContent> {
override fun convert(value: List<TxInfo>): ImmutableList<SendRecipientListContent> {
val cryptoCurrency = cryptoCurrencyStatusProvider().currency
return value.filterRecipients(cryptoCurrency).ifEmpty {
emptyListState(RECENT_KEY_TAG, RECENT_DEFAULT_COUNT)
}
}
private fun List<TxHistoryItem>.filterRecipients(cryptoCurrency: CryptoCurrency) = this.filter { item ->
val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer
val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User
private fun List<TxInfo>.filterRecipients(cryptoCurrency: CryptoCurrency) = this.filter { item ->
val isTransfer = item.type == TxInfo.TransactionType.Transfer
val isNotContract = item.interactionAddressType is TxInfo.InteractionAddressType.User
val isSingleAddress = if (item.isOutgoing) {
item.destinationType is TxHistoryItem.DestinationType.Single
item.destinationType is TxInfo.DestinationType.Single
} else {
item.sourceType is TxHistoryItem.SourceType.Single
item.sourceType is TxInfo.SourceType.Single
}
val notZero = !item.amount.isZero()
isTransfer && isSingleAddress && isNotContract && item.isOutgoing && notZero
@ -56,31 +56,31 @@ internal class SendRecipientHistoryListConverter(
)
}.toPersistentList()
private fun TxHistoryItem.extractAddress(): TextReference = if (isOutgoing) {
private fun TxInfo.extractAddress(): TextReference = if (isOutgoing) {
when (val destination = destinationType) {
is TxHistoryItem.DestinationType.Multiple -> TextReference.Res(
is TxInfo.DestinationType.Multiple -> TextReference.Res(
R.string.transaction_history_multiple_addresses,
)
is TxHistoryItem.DestinationType.Single -> TextReference.Str(destination.addressType.address)
is TxInfo.DestinationType.Single -> TextReference.Str(destination.addressType.address)
}
} else {
when (val source = sourceType) {
is TxHistoryItem.SourceType.Multiple -> TextReference.Res(R.string.transaction_history_multiple_addresses)
is TxHistoryItem.SourceType.Single -> TextReference.Str(source.address)
is TxInfo.SourceType.Multiple -> TextReference.Res(R.string.transaction_history_multiple_addresses)
is TxInfo.SourceType.Single -> TextReference.Str(source.address)
}
}
private fun TxHistoryItem.extractIconRes() = if (isOutgoing) {
private fun TxInfo.extractIconRes() = if (isOutgoing) {
R.drawable.ic_arrow_up_24
} else {
R.drawable.ic_arrow_down_24
}
private fun TxHistoryItem.getAmount(cryptoCurrency: CryptoCurrency): String {
private fun TxInfo.getAmount(cryptoCurrency: CryptoCurrency): String {
return amount.format { crypto(cryptoCurrency) }
}
private fun TxHistoryItem.extractTimestamp(): TextReference {
private fun TxInfo.extractTimestamp(): TextReference {
val date = timestampInMillis.toDateFormatWithTodayYesterday(
formatter = DateTimeFormatters.dateDDMMYYYY,
)

View file

@ -16,13 +16,13 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.card.NetworkHasDerivationUseCase
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.staking.GetStakingIntegrationIdUseCase
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingEntryInfo
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.model.*
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.wallets.models.UserWalletId
@ -168,7 +168,7 @@ internal class TokenDetailsStateFactory(
}
fun getLoadedTxHistoryState(
txHistoryEither: Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>,
txHistoryEither: Either<TxHistoryListError, Flow<PagingData<TxInfo>>>,
): TokenDetailsState {
return currentStateProvider().copy(
txHistoryState = loadedTxHistoryConverter.convert(txHistoryEither),

View file

@ -3,10 +3,10 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.
import androidx.paging.PagingData
import arrow.core.Either
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.coroutines.flow.Flow
@ -16,7 +16,7 @@ internal class TokenDetailsLoadedTxHistoryConverter(
private val clickIntents: TokenDetailsClickIntents,
symbol: String,
decimals: Int,
) : Converter<Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>, TxHistoryState> {
) : Converter<Either<TxHistoryListError, Flow<PagingData<TxInfo>>>, TxHistoryState> {
private val txHistoryItemFlowConverter by lazy {
TokenDetailsTxHistoryItemFlowConverter(
@ -27,7 +27,7 @@ internal class TokenDetailsLoadedTxHistoryConverter(
)
}
override fun convert(value: Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>): TxHistoryState {
override fun convert(value: Either<TxHistoryListError, Flow<PagingData<TxInfo>>>): TxHistoryState {
return value.fold(ifLeft = ::convertError, ifRight = ::convert)
}
@ -42,7 +42,7 @@ internal class TokenDetailsLoadedTxHistoryConverter(
}
}
private fun convert(items: Flow<PagingData<TxHistoryItem>>): TxHistoryState {
private fun convert(items: Flow<PagingData<TxInfo>>): TxHistoryState {
return txHistoryItemFlowConverter.convert(value = items)
}
}

View file

@ -5,9 +5,9 @@ import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.core.ui.components.transactions.state.TxHistoryState.TxHistoryItemState
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.domain.models.network.TxInfo
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.coroutines.CoroutineScope
@ -20,7 +20,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
private val symbol: String,
private val decimals: Int,
private val clickIntents: TokenDetailsClickIntents,
) : Converter<Flow<PagingData<TxHistoryItem>>, TxHistoryState> {
) : Converter<Flow<PagingData<TxInfo>>, TxHistoryState> {
private val txHistoryItemConverter by lazy {
TokenDetailsTxHistoryTransactionStateConverter(
@ -30,7 +30,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
)
}
override fun convert(value: Flow<PagingData<TxHistoryItem>>): TxHistoryState {
override fun convert(value: Flow<PagingData<TxInfo>>): TxHistoryState {
val state = currentStateProvider()
val txHistoryContent = if (state.txHistoryState is TxHistoryState.Content) {
state.txHistoryState
@ -43,7 +43,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
.onEach { txHistoryStatePagingData ->
txHistoryContent.contentItems.update {
txHistoryStatePagingData
.map<TxHistoryItem, TxHistoryItemState> { item ->
.map<TxInfo, TxHistoryItemState> { item ->
// [createTransactionState] returns timestamp without formatting
TxHistoryItemState.Transaction(state = createTransactionState(item))
}
@ -59,7 +59,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
return txHistoryContent
}
private fun createTransactionState(item: TxHistoryItem): TransactionState {
private fun createTransactionState(item: TxInfo): TransactionState {
return txHistoryItemConverter.convert(value = item)
}

View file

@ -10,8 +10,8 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryItem.*
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.models.network.TxInfo.*
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.features.tokendetails.impl.R
import com.tangem.utils.StringsSigns.MINUS
@ -23,14 +23,14 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
private val symbol: String,
private val decimals: Int,
private val clickIntents: TokenDetailsClickIntents,
) : Converter<TxHistoryItem, TransactionState> {
) : Converter<TxInfo, TransactionState> {
override fun convert(value: TxHistoryItem): TransactionState {
override fun convert(value: TxInfo): TransactionState {
return createTransactionStateItem(item = value)
}
@Suppress("LongMethod")
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
private fun createTransactionStateItem(item: TxInfo): TransactionState {
return TransactionState.Content(
txHash = item.txHash,
amount = item.getAmount(),
@ -45,7 +45,7 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
)
}
private fun TxHistoryItem.extractIcon(): Int = if (status == TransactionStatus.Failed) {
private fun TxInfo.extractIcon(): Int = if (status == TransactionStatus.Failed) {
R.drawable.ic_close_24
} else {
when (type) {
@ -67,7 +67,7 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
}
}
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
private fun TxInfo.extractTitle(): TextReference = when (val type = type) {
is TransactionType.Approve -> resourceReference(R.string.common_approval)
is TransactionType.Operation -> stringReference(type.name)
is TransactionType.Swap -> resourceReference(R.string.common_swap)
@ -81,38 +81,37 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
is TransactionType.Staking.Restake -> resourceReference(R.string.staking_restake)
}
private fun TxHistoryItem.extractSubtitle(): TextReference =
when (val interactionAddress = interactionAddressType) {
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
private fun TxInfo.extractSubtitle(): TextReference = when (val interactionAddress = interactionAddressType) {
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
}
private fun TxHistoryItem.extractDirection() = if (isOutgoing) Direction.OUTGOING else Direction.INCOMING
private fun TxInfo.extractDirection() = if (isOutgoing) Direction.OUTGOING else Direction.INCOMING
private fun TransactionStatus.tiUiStatus() = when (this) {
TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
@ -120,7 +119,7 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
private fun TxHistoryItem.getAmount(): String {
private fun TxInfo.getAmount(): String {
if (type is TransactionType.Staking.Vote ||
type == TransactionType.Staking.ClaimRewards ||
type == TransactionType.Staking.Withdraw

View file

@ -8,8 +8,8 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.txhistory.impl.R
import com.tangem.features.txhistory.utils.TxHistoryUiActions
import com.tangem.utils.StringsSigns
@ -20,8 +20,8 @@ import com.tangem.utils.toBriefAddressFormat
internal class TxHistoryItemToTransactionStateConverter(
private val currency: CryptoCurrency,
private val txHistoryUiActions: TxHistoryUiActions,
) : Converter<TxHistoryItem, TransactionState> {
override fun convert(value: TxHistoryItem): TransactionState {
) : Converter<TxInfo, TransactionState> {
override fun convert(value: TxInfo): TransactionState {
return TransactionState.Content(
txHash = value.txHash,
amount = value.getAmount(),
@ -36,94 +36,93 @@ internal class TxHistoryItemToTransactionStateConverter(
)
}
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
private fun TxInfo.extractIcon(): Int = if (status == TxInfo.TransactionStatus.Failed) {
R.drawable.ic_close_24
} else {
when (type) {
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
is TxHistoryItem.TransactionType.Staking.Stake,
is TxHistoryItem.TransactionType.Staking.Vote,
is TxHistoryItem.TransactionType.Staking.Restake,
is TxInfo.TransactionType.Approve -> R.drawable.ic_doc_24
is TxInfo.TransactionType.Staking.Stake,
is TxInfo.TransactionType.Staking.Vote,
is TxInfo.TransactionType.Staking.Restake,
-> R.drawable.ic_transaction_history_staking_24
is TxHistoryItem.TransactionType.Staking.ClaimRewards,
is TxInfo.TransactionType.Staking.ClaimRewards,
-> R.drawable.ic_transaction_history_claim_rewards_24
is TxHistoryItem.TransactionType.Staking.Unstake,
is TxHistoryItem.TransactionType.Staking.Withdraw,
is TxInfo.TransactionType.Staking.Unstake,
is TxInfo.TransactionType.Staking.Withdraw,
-> R.drawable.ic_transaction_history_unstaking_24
is TxHistoryItem.TransactionType.Operation,
is TxHistoryItem.TransactionType.Swap,
is TxHistoryItem.TransactionType.Transfer,
is TxHistoryItem.TransactionType.UnknownOperation,
is TxInfo.TransactionType.Operation,
is TxInfo.TransactionType.Swap,
is TxInfo.TransactionType.Transfer,
is TxInfo.TransactionType.UnknownOperation,
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
}
}
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TxHistoryItem.TransactionType.Staking.Stake -> resourceReference(R.string.common_stake)
is TxHistoryItem.TransactionType.Staking.Unstake -> resourceReference(R.string.common_unstake)
is TxHistoryItem.TransactionType.Staking.Vote -> resourceReference(R.string.staking_vote)
is TxHistoryItem.TransactionType.Staking.ClaimRewards -> resourceReference(R.string.common_claim_rewards)
is TxHistoryItem.TransactionType.Staking.Withdraw -> resourceReference(R.string.staking_withdraw)
is TxHistoryItem.TransactionType.Staking.Restake -> resourceReference(R.string.staking_restake)
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
private fun TxInfo.extractTitle(): TextReference = when (val type = type) {
is TxInfo.TransactionType.Approve -> resourceReference(R.string.common_approval)
is TxInfo.TransactionType.Operation -> stringReference(type.name)
is TxInfo.TransactionType.Swap -> resourceReference(R.string.common_swap)
is TxInfo.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TxInfo.TransactionType.Staking.Stake -> resourceReference(R.string.common_stake)
is TxInfo.TransactionType.Staking.Unstake -> resourceReference(R.string.common_unstake)
is TxInfo.TransactionType.Staking.Vote -> resourceReference(R.string.staking_vote)
is TxInfo.TransactionType.Staking.ClaimRewards -> resourceReference(R.string.common_claim_rewards)
is TxInfo.TransactionType.Staking.Withdraw -> resourceReference(R.string.staking_withdraw)
is TxInfo.TransactionType.Staking.Restake -> resourceReference(R.string.staking_restake)
is TxInfo.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
}
private fun TxHistoryItem.extractSubtitle(): TextReference =
when (val interactionAddress = interactionAddressType) {
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxHistoryItem.InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
private fun TxInfo.extractSubtitle(): TextReference = when (val interactionAddress = interactionAddressType) {
is TxInfo.InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxInfo.InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is TxInfo.InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxInfo.InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
}
private fun TxHistoryItem.extractDirection() =
private fun TxInfo.extractDirection() =
if (isOutgoing) TransactionState.Content.Direction.OUTGOING else TransactionState.Content.Direction.INCOMING
private fun TxHistoryItem.getAmount(): String {
if (type is TxHistoryItem.TransactionType.Staking.Vote ||
type == TxHistoryItem.TransactionType.Staking.ClaimRewards ||
type == TxHistoryItem.TransactionType.Staking.Withdraw
private fun TxInfo.getAmount(): String {
if (type is TxInfo.TransactionType.Staking.Vote ||
type == TxInfo.TransactionType.Staking.ClaimRewards ||
type == TxInfo.TransactionType.Staking.Withdraw
) {
return ""
}
val prefix = when {
status == TxHistoryItem.TransactionStatus.Failed -> ""
status == TxInfo.TransactionStatus.Failed -> ""
this.amount.isZero() -> ""
else -> if (isOutgoing) StringsSigns.MINUS else StringsSigns.PLUS
}
return prefix + amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
}
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
private fun TxInfo.TransactionStatus.tiUiStatus() = when (this) {
TxInfo.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TxInfo.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TxInfo.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
}

View file

@ -1,10 +1,10 @@
package com.tangem.features.txhistory.utils
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.txhistory.model.TxHistoryListBatchingContext
import com.tangem.domain.txhistory.model.TxHistoryListConfig
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.repository.TxHistoryRepositoryV2
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.txhistory.converter.TxHistoryItemToTransactionStateConverter
@ -85,7 +85,7 @@ internal class TxHistoryListManager(
)
}
private fun updateState(batchListState: BatchListState<Int, PaginationWrapper<TxHistoryItem>>) {
private fun updateState(batchListState: BatchListState<Int, PaginationWrapper<TxInfo>>) {
state.update { state ->
val clearUiBatches =
state.status is PaginationStatus.InitialLoading && batchListState.status is PaginationStatus.Paginating

View file

@ -1,8 +1,8 @@
package com.tangem.features.txhistory.utils
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.txhistory.converter.TxHistoryItemToTransactionStateConverter
import com.tangem.features.txhistory.entity.TxHistoryUM
import com.tangem.pagination.Batch
@ -10,11 +10,7 @@ import com.tangem.pagination.PaginationStatus
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.*
import java.util.UUID
internal class TxHistoryUiManager(
@ -35,7 +31,7 @@ internal class TxHistoryUiManager(
.distinctUntilChanged()
fun createOrUpdateUiBatches(
newCurrencyBatches: List<Batch<Int, PaginationWrapper<TxHistoryItem>>>,
newCurrencyBatches: List<Batch<Int, PaginationWrapper<TxInfo>>>,
clearUiBatches: Boolean,
): List<Batch<Int, List<TxHistoryUM.TxHistoryItemUM>>> {
val currentUiBatches = state.value.uiBatches
@ -67,7 +63,7 @@ internal class TxHistoryUiManager(
return batches
}
private fun generateUiItems(key: Int, data: PaginationWrapper<TxHistoryItem>): List<TxHistoryUM.TxHistoryItemUM> {
private fun generateUiItems(key: Int, data: PaginationWrapper<TxInfo>): List<TxHistoryUM.TxHistoryItemUM> {
val items = mutableListOf<TxHistoryUM.TxHistoryItemUM>()
// Add title for the first batch
@ -109,9 +105,7 @@ internal class TxHistoryUiManager(
return items
}
private fun List<TxHistoryUM.TxHistoryItemUM>.transactionItemsSizeNotEqual(
txHistoryItems: List<TxHistoryItem>,
): Boolean {
return this.filterIsInstance<TxHistoryUM.TxHistoryItemUM.Transaction>().size != txHistoryItems.size
private fun List<TxHistoryUM.TxHistoryItemUM>.transactionItemsSizeNotEqual(txInfos: List<TxInfo>): Boolean {
return this.filterIsInstance<TxHistoryUM.TxHistoryItemUM.Transaction>().size != txInfos.size
}
}

View file

@ -2,19 +2,19 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TxHistoryItemStateConverter
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import kotlinx.collections.immutable.toImmutableList
import timber.log.Timber
internal class SetTxHistoryCountErrorTransformer(
private val userWallet: UserWallet,
private val error: TxHistoryStateError,
private val pendingTransactions: Set<TxHistoryItem>,
private val pendingTransactions: Set<TxInfo>,
private val clickIntents: WalletClickIntents,
) : WalletStateTransformer(userWallet.walletId) {

View file

@ -9,10 +9,10 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryItem.*
import com.tangem.feature.wallet.impl.R
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.models.network.TxInfo.*
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.impl.R
import com.tangem.utils.StringsSigns.MINUS
import com.tangem.utils.StringsSigns.PLUS
import com.tangem.utils.converter.Converter
@ -22,14 +22,14 @@ internal class TxHistoryItemStateConverter(
private val symbol: String,
private val decimals: Int,
private val clickIntents: WalletClickIntents,
) : Converter<TxHistoryItem, TransactionState> {
) : Converter<TxInfo, TransactionState> {
override fun convert(value: TxHistoryItem): TransactionState {
override fun convert(value: TxInfo): TransactionState {
return createTransactionStateItem(item = value)
}
@Suppress("LongMethod")
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
private fun createTransactionStateItem(item: TxInfo): TransactionState {
return TransactionState.Content(
txHash = item.txHash,
amount = item.getAmount(),
@ -44,7 +44,7 @@ internal class TxHistoryItemStateConverter(
)
}
private fun TxHistoryItem.extractIcon(): Int = if (status == TransactionStatus.Failed) {
private fun TxInfo.extractIcon(): Int = if (status == TransactionStatus.Failed) {
R.drawable.ic_close_24
} else {
when (type) {
@ -66,7 +66,7 @@ internal class TxHistoryItemStateConverter(
}
}
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
private fun TxInfo.extractTitle(): TextReference = when (val type = type) {
is TransactionType.Approve -> resourceReference(R.string.common_approval)
is TransactionType.Operation -> stringReference(type.name)
is TransactionType.Swap -> resourceReference(R.string.common_swap)
@ -80,38 +80,37 @@ internal class TxHistoryItemStateConverter(
is TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
}
private fun TxHistoryItem.extractSubtitle(): TextReference =
when (val interactionAddress = interactionAddressType) {
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
private fun TxInfo.extractSubtitle(): TextReference = when (val interactionAddress = interactionAddressType) {
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
R.string.transaction_history_transaction_from_address
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Validator -> resourceReference(
id = R.string.transaction_history_transaction_validator,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
null -> {
TextReference.EMPTY
}
}
private fun TxHistoryItem.extractDirection() =
private fun TxInfo.extractDirection() =
if (isOutgoing) TransactionState.Content.Direction.OUTGOING else TransactionState.Content.Direction.INCOMING
private fun TransactionStatus.tiUiStatus() = when (this) {
@ -120,7 +119,7 @@ internal class TxHistoryItemStateConverter(
TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
private fun TxHistoryItem.getAmount(): String {
private fun TxInfo.getAmount(): String {
if (type is TransactionType.Staking.Vote ||
type == TransactionType.Staking.ClaimRewards ||
type == TransactionType.Staking.Withdraw

View file

@ -5,9 +5,9 @@ import androidx.paging.cachedIn
import androidx.paging.map
import arrow.core.Either
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
typealias MaybeTxHistoryCount = Either<TxHistoryStateError, Int>
typealias MaybeTxHistoryItems = Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>
typealias MaybeTxHistoryItems = Either<TxHistoryListError, Flow<PagingData<TxInfo>>>
@Suppress("LongParameterList")
internal class TxHistorySubscriber(
@ -40,7 +40,7 @@ internal class TxHistorySubscriber(
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
) : WalletSubscriber() {
override fun create(coroutineScope: CoroutineScope): Flow<PagingData<TxHistoryItem>> {
override fun create(coroutineScope: CoroutineScope): Flow<PagingData<TxInfo>> {
return flow {
getSingleCryptoCurrencyStatusUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
val maybeTxHistoryItemCount = txHistoryItemsCountUseCase(