Updated on 2026-08-14
This commit is contained in:
parent
f1eb31f5f4
commit
da6ee825ab
13 changed files with 208 additions and 38 deletions
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.di.domain
|
|||
import com.tangem.domain.onramp.*
|
||||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -63,4 +64,36 @@ internal object OnrampDomainModule {
|
|||
fun provideGetOnrampCurrencyUseCase(onrampRepository: OnrampRepository): GetOnrampCurrencyUseCase {
|
||||
return GetOnrampCurrencyUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampTransactionsUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): GetOnrampTransactionsUseCase {
|
||||
return GetOnrampTransactionsUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): GetOnrampTransactionUseCase {
|
||||
return GetOnrampTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampRemoveTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): OnrampRemoveTransactionUseCase {
|
||||
return OnrampRemoveTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampSaveTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): OnrampSaveTransactionUseCase {
|
||||
return OnrampSaveTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -14,15 +14,11 @@ import com.tangem.blockchain.common.Token as SdkToken
|
|||
|
||||
class ResponseCryptoCurrenciesFactory {
|
||||
|
||||
fun createCurrency(
|
||||
currencyId: CryptoCurrency.ID,
|
||||
response: UserTokensResponse,
|
||||
scanResponse: ScanResponse,
|
||||
): CryptoCurrency {
|
||||
fun createCurrency(currencyId: String, response: UserTokensResponse, scanResponse: ScanResponse): CryptoCurrency {
|
||||
return response.tokens
|
||||
.asSequence()
|
||||
.mapNotNull { createCurrency(it, scanResponse) }
|
||||
.first { it.id == currencyId }
|
||||
.first { it.id.value == currencyId }
|
||||
}
|
||||
|
||||
fun createCurrencies(response: UserTokensResponse, scanResponse: ScanResponse): List<CryptoCurrency> {
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ internal class DefaultOnrampTransactionRepository(
|
|||
|
||||
override fun getTransactions(
|
||||
userWalletId: UserWalletId,
|
||||
toCryptoCurrency: CryptoCurrency.ID,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
): Flow<List<OnrampTransaction>> = appPreferencesStore
|
||||
.getObjectSet<OnrampTransaction>(PreferencesKeys.ONRAMP_TRANSACTIONS_STATUSES_KEY)
|
||||
.map { transactions ->
|
||||
transactions.filter {
|
||||
it.userWalletId == userWalletId && it.toCurrency.id == toCryptoCurrency
|
||||
it.userWalletId == userWalletId && it.toCurrencyId == cryptoCurrencyId.value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -293,23 +293,28 @@ internal class DefaultCurrenciesRepository(
|
|||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
): CryptoCurrency = withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
val response = requireNotNull(
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
responseCurrenciesFactory.createCurrency(
|
||||
currencyId = id,
|
||||
response = response,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
)
|
||||
getMultiCurrencyWalletCurrency(userWalletId, id.value)
|
||||
}
|
||||
|
||||
override suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: String): CryptoCurrency =
|
||||
withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
val response = requireNotNull(
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
responseCurrenciesFactory.createCurrency(
|
||||
currencyId = id,
|
||||
response = response,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getNetworkCoin(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
|
|
|
|||
|
|
@ -23,16 +23,32 @@ data class OnrampStatus(
|
|||
val paymentMethod: String,
|
||||
val countryCode: String,
|
||||
) {
|
||||
enum class Status {
|
||||
Created,
|
||||
Expired,
|
||||
Paused,
|
||||
WaitingForPayment,
|
||||
PaymentProcessing,
|
||||
Verifying,
|
||||
Failed,
|
||||
Paid,
|
||||
Sending,
|
||||
Finished,
|
||||
enum class Status(val order: Int) {
|
||||
Created(order = 1),
|
||||
Expired(order = 2),
|
||||
Paused(order = 3),
|
||||
WaitingForPayment(order = 4),
|
||||
PaymentProcessing(order = 5),
|
||||
Verifying(order = 6),
|
||||
Failed(order = 7),
|
||||
Paid(order = 8),
|
||||
Sending(order = 9),
|
||||
Finished(order = 10),
|
||||
;
|
||||
|
||||
fun isTerminal(): Boolean = when (this) {
|
||||
Expired,
|
||||
Failed,
|
||||
Paused,
|
||||
Finished,
|
||||
-> true
|
||||
Created,
|
||||
WaitingForPayment,
|
||||
PaymentProcessing,
|
||||
Verifying,
|
||||
Paid,
|
||||
Sending,
|
||||
-> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.tangem.domain.onramp.model.cache
|
|||
|
||||
import com.tangem.domain.core.serialization.SerializedBigDecimal
|
||||
import com.tangem.domain.onramp.model.OnrampCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
|
@ -13,8 +12,7 @@ data class OnrampTransaction(
|
|||
val fromAmount: SerializedBigDecimal,
|
||||
val fromCurrency: OnrampCurrency,
|
||||
val toAmount: SerializedBigDecimal,
|
||||
val toCurrency: CryptoCurrency,
|
||||
val timestamp: Long,
|
||||
val toCurrencyId: String,
|
||||
val providerName: String,
|
||||
val providerImageUrl: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.model.OnrampError
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
|
||||
class GetOnrampTransactionUseCase(
|
||||
private val onrampTransactionRepository: OnrampTransactionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(txId: String): Either<OnrampError, OnrampTransaction> {
|
||||
return Either.catch {
|
||||
requireNotNull(
|
||||
onrampTransactionRepository.getTransactionById(txId),
|
||||
)
|
||||
}.mapLeft {
|
||||
OnrampError.UnknownError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.model.OnrampError
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class GetOnrampTransactionsUseCase(
|
||||
private val onrampTransactionRepository: OnrampTransactionRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
): Either<OnrampError, Flow<List<OnrampTransaction>>> {
|
||||
return Either.catch {
|
||||
onrampTransactionRepository.getTransactions(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrencyId,
|
||||
)
|
||||
}.mapLeft {
|
||||
OnrampError.UnknownError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.model.OnrampError
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
|
||||
class OnrampRemoveTransactionUseCase(
|
||||
private val onrampTransactionRepository: OnrampTransactionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(txId: String): Either<OnrampError, Unit> {
|
||||
return Either.catch {
|
||||
onrampTransactionRepository.removeTransaction(txId)
|
||||
}.mapLeft {
|
||||
OnrampError.UnknownError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.model.OnrampError
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
|
||||
class OnrampSaveTransactionUseCase(
|
||||
private val onrampTransactionRepository: OnrampTransactionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(transaction: OnrampTransaction): Either<OnrampError, Unit> {
|
||||
return Either.catch { onrampTransactionRepository.storeTransaction(transaction) }
|
||||
.mapLeft { OnrampError.UnknownError }
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ interface OnrampTransactionRepository {
|
|||
|
||||
suspend fun getTransactionById(txId: String): OnrampTransaction?
|
||||
|
||||
fun getTransactions(userWalletId: UserWalletId, toCryptoCurrency: CryptoCurrency.ID): Flow<List<OnrampTransaction>>
|
||||
fun getTransactions(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Flow<List<OnrampTransaction>>
|
||||
|
||||
suspend fun removeTransaction(txId: String)
|
||||
}
|
||||
|
|
@ -27,6 +27,22 @@ class GetCryptoCurrencyUseCase(
|
|||
return either { getCurrency(userWalletId, id) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specific cryptocurrency for a given user wallet.
|
||||
*
|
||||
* !!! Important Use only [CryptoCurrency.ID.value] as cryptoCurrencyId
|
||||
*
|
||||
* @param userWalletId The ID of the user's wallet.
|
||||
* @param cryptoCurrencyId String representation of the [CryptoCurrency.ID.value] of the cryptocurrency.
|
||||
* @return An [Either] representing success (Right) or an error (Left) in fetching the status.
|
||||
*/
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyId: String,
|
||||
): Either<CurrencyStatusError, CryptoCurrency> {
|
||||
return either { getCurrency(userWalletId, cryptoCurrencyId) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary cryptocurrency for a given user wallet.
|
||||
*
|
||||
|
|
@ -49,6 +65,18 @@ class GetCryptoCurrencyUseCase(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun Raise<CurrencyStatusError>.getCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: String,
|
||||
): CryptoCurrency {
|
||||
return catch(
|
||||
block = {
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, id)
|
||||
},
|
||||
catch = { raise(CurrencyStatusError.DataError(it)) },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun Raise<CurrencyStatusError>.getPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {
|
||||
return catch(
|
||||
block = { currenciesRepository.getSingleCurrencyWalletPrimaryCurrency(userWalletId) },
|
||||
|
|
|
|||
|
|
@ -167,6 +167,17 @@ interface CurrenciesRepository {
|
|||
*/
|
||||
suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: CryptoCurrency.ID): CryptoCurrency
|
||||
|
||||
/**
|
||||
* Retrieves the cryptocurrency for a specific multi-currency user wallet.
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user wallet.
|
||||
* @param id The unique identifier of the cryptocurrency to be retrieved.
|
||||
* @return The cryptocurrency associated with the user wallet and ID.
|
||||
* @throws DataError.UserWalletError.WrongUserWallet If single-currency user wallet
|
||||
* ID provided.
|
||||
*/
|
||||
suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: String): CryptoCurrency
|
||||
|
||||
/**
|
||||
* Get the coin for a specific network.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue