Updated on 2026-08-14
This commit is contained in:
parent
4ea919aed9
commit
6455a837b7
8 changed files with 99 additions and 47 deletions
|
|
@ -1,22 +1,15 @@
|
|||
package com.tangem.tap.domain.model.builders
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.SaltPayWorkaround
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.common.TwinsHelper
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.TangemApi
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.domain.userWalletList.GetCardImageUseCase
|
||||
|
||||
class UserWalletBuilder(
|
||||
private val scanResponse: ScanResponse,
|
||||
private val onlineCardVerifier: OnlineCardVerifier = OnlineCardVerifier(),
|
||||
private val getCardImageUseCase: GetCardImageUseCase = GetCardImageUseCase(),
|
||||
) {
|
||||
private var backupCardsIds: Set<String> = emptySet()
|
||||
|
||||
|
|
@ -50,7 +43,7 @@ class UserWalletBuilder(
|
|||
UserWallet(
|
||||
walletId = it,
|
||||
name = userWalletName,
|
||||
artworkUrl = loadArtworkUrl(card.cardId, card.cardPublicKey),
|
||||
artworkUrl = getCardImageUseCase.invoke(card.cardId, card.cardPublicKey),
|
||||
cardsInWallet = backupCardsIds.plus(card.cardId),
|
||||
scanResponse = this,
|
||||
isMultiCurrency = cardTypesResolver.isMultiwalletAllowed(),
|
||||
|
|
@ -58,37 +51,4 @@ class UserWalletBuilder(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadArtworkUrl(cardId: String, cardPublicKey: ByteArray): String {
|
||||
return when (val result = onlineCardVerifier.getCardInfo(cardId, cardPublicKey)) {
|
||||
is Result.Success -> {
|
||||
val artworkId = result.data.artwork?.id
|
||||
if (artworkId.isNullOrEmpty()) {
|
||||
getFallbackArtworkUrl(cardId)
|
||||
} else {
|
||||
getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
}
|
||||
|
||||
is Result.Failure -> getFallbackArtworkUrl(cardId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFallbackArtworkUrl(cardId: String): String {
|
||||
return when {
|
||||
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
|
||||
cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL
|
||||
SaltPayWorkaround.isSaltPayCardId(cardId) -> Artwork.SALT_PAY_URL
|
||||
else -> when (TwinsHelper.getTwinCardNumber(cardId)) {
|
||||
TwinCardNumber.First -> Artwork.TWIN_CARD_1
|
||||
TwinCardNumber.Second -> Artwork.TWIN_CARD_2
|
||||
else -> Artwork.DEFAULT_IMG_URL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUrlForArtwork(cardId: String, cardPublicKeyHex: String, artworkId: String): String {
|
||||
return TangemApi.Companion.BaseUrl.VERIFY.url + TangemApi.ARTWORK +
|
||||
"?artworkId=$artworkId&CID=$cardId&publicKey=$cardPublicKeyHex"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.tangem.tap.domain.userWalletList
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.SaltPayWorkaround
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.common.TwinsHelper
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.TangemApi
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
|
||||
/**
|
||||
* Use case for getting card image url
|
||||
*
|
||||
* @property verifier REST API
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetCardImageUseCase(private val verifier: OnlineCardVerifier = OnlineCardVerifier()) {
|
||||
|
||||
/**
|
||||
* Get card image url
|
||||
*
|
||||
* @param cardId card id
|
||||
* @param cardPublicKey card public key
|
||||
*/
|
||||
suspend operator fun invoke(cardId: String, cardPublicKey: ByteArray): String {
|
||||
return when (val result = verifier.getCardInfo(cardId, cardPublicKey)) {
|
||||
is Result.Success -> {
|
||||
val artworkId = result.data.artwork?.id
|
||||
if (artworkId.isNullOrEmpty()) {
|
||||
getFallbackArtworkUrl(cardId)
|
||||
} else {
|
||||
getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
}
|
||||
|
||||
is Result.Failure -> getFallbackArtworkUrl(cardId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFallbackArtworkUrl(cardId: String): String {
|
||||
return when {
|
||||
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
|
||||
cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL
|
||||
SaltPayWorkaround.isSaltPayCardId(cardId) -> Artwork.SALT_PAY_URL
|
||||
else -> when (TwinsHelper.getTwinCardNumber(cardId)) {
|
||||
TwinCardNumber.First -> Artwork.TWIN_CARD_1
|
||||
TwinCardNumber.Second -> Artwork.TWIN_CARD_2
|
||||
else -> Artwork.DEFAULT_IMG_URL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUrlForArtwork(cardId: String, cardPublicKeyHex: String, artworkId: String): String {
|
||||
return TangemApi.Companion.BaseUrl.VERIFY.url + TangemApi.ARTWORK +
|
||||
"?artworkId=$artworkId&CID=$cardId&publicKey=$cardPublicKeyHex"
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,10 @@ interface UserWalletsListManager {
|
|||
* @return [CompletionResult.Success] with updated [UserWallet]
|
||||
* or [CompletionResult.Failure] with [NoSuchElementException] if [UserWallet] with [userWalletId] not found
|
||||
* */
|
||||
suspend fun update(userWalletId: UserWalletId, update: (UserWallet) -> UserWallet): CompletionResult<UserWallet>
|
||||
suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): CompletionResult<UserWallet>
|
||||
|
||||
/**
|
||||
* Delete saved [UserWallet]s with provided [UserWalletId]s
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ internal class BiometricUserWalletsListManager(
|
|||
|
||||
override suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: (UserWallet) -> UserWallet,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): CompletionResult<UserWallet> {
|
||||
return get(userWalletId)
|
||||
.map { storedUserWallet ->
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager {
|
|||
|
||||
override suspend fun update(
|
||||
userWalletId: UserWalletId,
|
||||
update: (UserWallet) -> UserWallet,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): CompletionResult<UserWallet> = catching {
|
||||
val wallet = state.value.userWallet
|
||||
?.takeIf { it.walletId == userWalletId }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
|
|
@ -130,4 +131,8 @@ sealed class WalletAction : Action {
|
|||
data class WalletStoresChanged(val walletStores: List<WalletStoreModel>) : WalletAction()
|
||||
|
||||
data class TotalFiatBalanceChanged(val balance: TotalFiatBalance) : WalletAction()
|
||||
|
||||
data class UpdateUserWalletArtwork(val walletId: UserWalletId) : WalletAction()
|
||||
|
||||
data class SetArtworkUrl(val url: String) : WalletAction()
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import com.tangem.blockchain.common.Amount
|
|||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
|
|
@ -25,6 +26,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction
|
|||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.model.WalletDataModel
|
||||
import com.tangem.tap.domain.model.WalletStoreModel
|
||||
import com.tangem.tap.domain.userWalletList.GetCardImageUseCase
|
||||
import com.tangem.tap.domain.userWalletList.lockIfLockable
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
|
|
@ -133,6 +135,9 @@ class WalletMiddleware {
|
|||
Timber.e("Unable to load/refresh wallets data, no user wallet selected")
|
||||
return
|
||||
}
|
||||
|
||||
store.dispatch(WalletAction.UpdateUserWalletArtwork(selectedWallet.walletId))
|
||||
|
||||
scope.launch {
|
||||
globalState.tapWalletManager.loadData(
|
||||
userWallet = selectedWallet,
|
||||
|
|
@ -205,6 +210,23 @@ class WalletMiddleware {
|
|||
is WalletAction.ChangeSelectedAddress -> {
|
||||
changeSelectedWalletAddress(action.type, walletState)
|
||||
}
|
||||
is WalletAction.UpdateUserWalletArtwork -> {
|
||||
scope.launch {
|
||||
userWalletsListManager
|
||||
.update(
|
||||
userWalletId = action.walletId,
|
||||
update = { userWallet ->
|
||||
userWallet.copy(
|
||||
artworkUrl = GetCardImageUseCase().invoke(
|
||||
cardId = userWallet.cardId,
|
||||
cardPublicKey = userWallet.scanResponse.card.cardPublicKey,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
.doOnSuccess { store.dispatch(WalletAction.SetArtworkUrl(it.artworkUrl)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,8 +113,11 @@ private fun internalReduce(action: Action, state: AppState, appStateHolder: AppS
|
|||
)
|
||||
}
|
||||
is WalletAction.UpdateCanSaveUserWallets -> {
|
||||
newState = newState.copy(canSaveUserWallets = action.canSaveUserWallets)
|
||||
}
|
||||
is WalletAction.SetArtworkUrl -> {
|
||||
newState = newState.copy(
|
||||
canSaveUserWallets = action.canSaveUserWallets,
|
||||
cardImage = Artwork(artworkId = action.url, artwork = newState.cardImage?.artwork),
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue