Updated on 2026-08-14
This commit is contained in:
parent
8541957ee3
commit
189ffd9927
73 changed files with 547 additions and 409 deletions
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.common.extensions
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.tap.common.analytics.paramsInterceptor.LinkedCardContextInterceptor
|
import com.tangem.tap.common.analytics.paramsInterceptor.LinkedCardContextInterceptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -21,6 +22,15 @@ fun Analytics.setContext(scanResponse: ScanResponse) {
|
||||||
addParamsInterceptor(LinkedCardContextInterceptor(scanResponse))
|
addParamsInterceptor(LinkedCardContextInterceptor(scanResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Analytics.setContext(userWallet: UserWallet) {
|
||||||
|
setUserId(userWallet.walletId.stringValue)
|
||||||
|
// TODO add product type for hot ([REDACTED_TASK_KEY])
|
||||||
|
|
||||||
|
if (userWallet is UserWallet.Cold) {
|
||||||
|
addParamsInterceptor(LinkedCardContextInterceptor(userWallet.scanResponse))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erases the context
|
* Erases the context
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import com.tangem.blockchain.common.Wallet
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.domain.common.extensions.withMainContext
|
import com.tangem.domain.common.extensions.withMainContext
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.tap.common.extensions.setContext
|
import com.tangem.tap.common.extensions.setContext
|
||||||
import com.tangem.tap.common.redux.global.GlobalAction
|
import com.tangem.tap.common.redux.global.GlobalAction
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
|
|
@ -35,16 +34,17 @@ class TapWalletManager(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun loadUserWalletData(userWallet: UserWallet) {
|
private suspend fun loadUserWalletData(userWallet: UserWallet) {
|
||||||
Analytics.setContext(userWallet.requireColdWallet().scanResponse) // [REDACTED_TASK_KEY]
|
Analytics.setContext(userWallet)
|
||||||
|
|
||||||
|
if (userWallet is UserWallet.Cold) {
|
||||||
val scanResponse = userWallet.scanResponse
|
val scanResponse = userWallet.scanResponse
|
||||||
|
|
||||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
||||||
|
|
||||||
withMainContext {
|
withMainContext {
|
||||||
// Order is important
|
// Order is important
|
||||||
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Wallet.getFirstToken(): Token? = getTokens().toList().getOrNull(index = 0)
|
fun Wallet.getFirstToken(): Token? = getTokens().toList().getOrNull(index = 0)
|
||||||
|
|
@ -50,7 +50,7 @@ internal class DefaultDerivationsRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null,
|
blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -91,7 +91,7 @@ internal class DefaultDerivationsRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
|
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockTy
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.isLocked
|
import com.tangem.domain.wallets.models.isLocked
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
||||||
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
|
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
|
||||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
|
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
|
||||||
|
|
@ -208,8 +207,7 @@ internal class BiometricUserWalletsListManager(
|
||||||
changeSelectedUserWallet: Boolean,
|
changeSelectedUserWallet: Boolean,
|
||||||
canOverridePublicInfo: Boolean,
|
canOverridePublicInfo: Boolean,
|
||||||
): CompletionResult<Unit> {
|
): CompletionResult<Unit> {
|
||||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
val encryptionKey = userWallet.encryptionKey
|
||||||
val encryptionKey = userWallet.scanResponse.card.encryptionKey
|
|
||||||
?.let { UserWalletEncryptionKey(userWallet.walletId, it) }
|
?.let { UserWalletEncryptionKey(userWallet.walletId, it) }
|
||||||
?: return CompletionResult.Success(Unit) // No encryption key, no need to save
|
?: return CompletionResult.Success(Unit) // No encryption key, no need to save
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,44 @@ package com.tangem.tap.domain.userWalletList.model
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
import com.tangem.domain.models.MobileWallet
|
||||||
import com.tangem.domain.models.scan.CardDTO
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.visa.model.VisaCardActivationStatus
|
import com.tangem.domain.visa.model.VisaCardActivationStatus
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import com.tangem.hot.sdk.model.HotWalletId
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class UserWalletSensitiveInformation(
|
internal data class UserWalletSensitiveInformation(
|
||||||
|
// Cold
|
||||||
@Json(name = "wallets")
|
@Json(name = "wallets")
|
||||||
val wallets: List<CardDTO.Wallet>,
|
val wallets: List<CardDTO.Wallet>?,
|
||||||
@Json(name = "visaCardActivationStatus")
|
@Json(name = "visaCardActivationStatus")
|
||||||
val visaCardActivationStatus: VisaCardActivationStatus? = null,
|
val visaCardActivationStatus: VisaCardActivationStatus? = null,
|
||||||
|
// Hot
|
||||||
|
@Json(name = "mobileWallets")
|
||||||
|
val mobileWallets: List<MobileWallet>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class UserWalletPublicInformation(
|
internal data class UserWalletPublicInformation(
|
||||||
|
// Common
|
||||||
@Json(name = "name")
|
@Json(name = "name")
|
||||||
val name: String,
|
val name: String,
|
||||||
@Json(name = "walletId")
|
@Json(name = "walletId")
|
||||||
val walletId: UserWalletId,
|
val walletId: UserWalletId,
|
||||||
|
// Cold
|
||||||
@Json(name = "cardsInWallet")
|
@Json(name = "cardsInWallet")
|
||||||
val cardsInWallet: Set<String>,
|
val cardsInWallet: Set<String>,
|
||||||
@Json(name = "scanResponse")
|
@Json(name = "scanResponse")
|
||||||
val scanResponse: ScanResponse,
|
val scanResponse: ScanResponse?,
|
||||||
@Json(name = "isMultiCurrency")
|
@Json(name = "isMultiCurrency")
|
||||||
val isMultiCurrency: Boolean,
|
val isMultiCurrency: Boolean,
|
||||||
@Json(name = "hasBackupError")
|
@Json(name = "hasBackupError")
|
||||||
val hasBackupError: Boolean = false,
|
val hasBackupError: Boolean = false,
|
||||||
|
// Hot
|
||||||
|
@Json(name = "hotWalletId")
|
||||||
|
val hotWalletId: HotWalletId? = null,
|
||||||
|
@Json(name = "backedUp")
|
||||||
|
val backedUp: Boolean? = null,
|
||||||
)
|
)
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.domain.userWalletList.utils
|
||||||
|
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||||
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
|
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
|
||||||
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
||||||
|
|
||||||
|
|
@ -10,8 +11,12 @@ internal val UserWallet.sensitiveInformation: UserWalletSensitiveInformation
|
||||||
is UserWallet.Cold -> UserWalletSensitiveInformation(
|
is UserWallet.Cold -> UserWalletSensitiveInformation(
|
||||||
wallets = scanResponse.card.wallets,
|
wallets = scanResponse.card.wallets,
|
||||||
visaCardActivationStatus = scanResponse.visaCardActivationStatus,
|
visaCardActivationStatus = scanResponse.visaCardActivationStatus,
|
||||||
|
mobileWallets = null,
|
||||||
|
)
|
||||||
|
is UserWallet.Hot -> UserWalletSensitiveInformation(
|
||||||
|
wallets = null,
|
||||||
|
mobileWallets = this.wallets,
|
||||||
)
|
)
|
||||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val UserWallet.publicInformation: UserWalletPublicInformation
|
internal val UserWallet.publicInformation: UserWalletPublicInformation
|
||||||
|
|
@ -28,20 +33,40 @@ internal val UserWallet.publicInformation: UserWalletPublicInformation
|
||||||
visaCardActivationStatus = null,
|
visaCardActivationStatus = null,
|
||||||
),
|
),
|
||||||
hasBackupError = hasBackupError,
|
hasBackupError = hasBackupError,
|
||||||
|
hotWalletId = null,
|
||||||
|
backedUp = null,
|
||||||
|
)
|
||||||
|
is UserWallet.Hot -> UserWalletPublicInformation(
|
||||||
|
name = name,
|
||||||
|
walletId = walletId,
|
||||||
|
isMultiCurrency = isMultiCurrency,
|
||||||
|
cardsInWallet = emptySet(),
|
||||||
|
scanResponse = null,
|
||||||
|
hotWalletId = hotWalletId,
|
||||||
|
backedUp = backedUp,
|
||||||
)
|
)
|
||||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun UserWalletPublicInformation.toUserWallet(): UserWallet {
|
internal fun UserWalletPublicInformation.toUserWallet(): UserWallet {
|
||||||
return UserWallet.Cold(
|
return if (hotWalletId != null) {
|
||||||
|
UserWallet.Hot(
|
||||||
|
name = name,
|
||||||
|
walletId = walletId,
|
||||||
|
hotWalletId = hotWalletId,
|
||||||
|
wallets = null,
|
||||||
|
backedUp = backedUp!!,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
UserWallet.Cold(
|
||||||
name = name,
|
name = name,
|
||||||
walletId = walletId,
|
walletId = walletId,
|
||||||
cardsInWallet = cardsInWallet,
|
cardsInWallet = cardsInWallet,
|
||||||
scanResponse = scanResponse,
|
scanResponse = scanResponse!!,
|
||||||
isMultiCurrency = isMultiCurrency,
|
isMultiCurrency = isMultiCurrency,
|
||||||
hasBackupError = hasBackupError,
|
hasBackupError = hasBackupError,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun List<UserWalletPublicInformation>.toUserWallets(): List<UserWallet> {
|
internal fun List<UserWalletPublicInformation>.toUserWallets(): List<UserWallet> {
|
||||||
return this.map { it.toUserWallet() }
|
return this.map { it.toUserWallet() }
|
||||||
|
|
@ -53,13 +78,15 @@ internal fun UserWallet.updateWith(sensitiveInformation: UserWalletSensitiveInfo
|
||||||
copy(
|
copy(
|
||||||
scanResponse = scanResponse.copy(
|
scanResponse = scanResponse.copy(
|
||||||
card = scanResponse.card.copy(
|
card = scanResponse.card.copy(
|
||||||
wallets = sensitiveInformation.wallets,
|
wallets = sensitiveInformation.wallets!!,
|
||||||
),
|
),
|
||||||
visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus,
|
visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
is UserWallet.Hot -> copy(
|
||||||
|
wallets = sensitiveInformation.mobileWallets,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
package com.tangem.tap.domain.userWalletList.utils
|
package com.tangem.tap.domain.userWalletList.utils
|
||||||
|
|
||||||
import com.tangem.common.extensions.calculateSha256
|
import com.tangem.common.extensions.calculateSha256
|
||||||
import com.tangem.domain.models.scan.CardDTO
|
|
||||||
import com.tangem.domain.common.extensions.calculateHmacSha256
|
import com.tangem.domain.common.extensions.calculateHmacSha256
|
||||||
|
import com.tangem.domain.models.MobileWallet
|
||||||
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
|
||||||
internal val CardDTO.encryptionKey: ByteArray?
|
internal val UserWallet.encryptionKey: ByteArray?
|
||||||
get() = findPublicKey(wallets)?.let { calculateEncryptionKey(it) }
|
get() = when (this) {
|
||||||
|
is UserWallet.Cold -> findPublicKey(this.scanResponse.card.wallets)
|
||||||
|
is UserWallet.Hot -> findPublicKey(this.wallets.orEmpty())
|
||||||
|
}?.let { calculateEncryptionKey(it) }
|
||||||
|
|
||||||
private fun calculateEncryptionKey(publicKey: ByteArray): ByteArray {
|
private fun calculateEncryptionKey(publicKey: ByteArray): ByteArray {
|
||||||
val message = MESSAGE_FOR_ENCRYPTION_KEY.toByteArray()
|
val message = MESSAGE_FOR_ENCRYPTION_KEY.toByteArray()
|
||||||
|
|
@ -15,8 +20,12 @@ private fun calculateEncryptionKey(publicKey: ByteArray): ByteArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findPublicKey(wallets: List<CardDTO.Wallet>): ByteArray? {
|
private fun findPublicKey(wallets: List<CardDTO.Wallet>): ByteArray? {
|
||||||
return wallets.firstOrNull()
|
return wallets.firstOrNull()?.publicKey
|
||||||
?.publicKey
|
}
|
||||||
|
|
||||||
|
@JvmName("findPublicKeyInMobileWallets")
|
||||||
|
private fun findPublicKey(wallets: List<MobileWallet>): ByteArray? {
|
||||||
|
return wallets.firstOrNull()?.publicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val MESSAGE_FOR_ENCRYPTION_KEY = "UserWalletEncryptionKey"
|
private const val MESSAGE_FOR_ENCRYPTION_KEY = "UserWalletEncryptionKey"
|
||||||
|
|
@ -14,7 +14,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||||
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
|
||||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||||
|
|
@ -422,8 +421,7 @@ class WalletConnectInteractor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCardId(userWallet: UserWallet): String? {
|
private fun getCardId(userWallet: UserWallet): String? {
|
||||||
userWallet.requireColdWallet() // [REDACTED_TASK_KEY]
|
return if (userWallet is UserWallet.Cold && userWallet.scanResponse.card.backupStatus?.isActive != true) {
|
||||||
return if (userWallet.scanResponse.card.backupStatus?.isActive != true) {
|
|
||||||
userWallet.cardId
|
userWallet.cardId
|
||||||
} else { // if wallet has backup, any card from wallet can be used to sign
|
} else { // if wallet has backup, any card from wallet can be used to sign
|
||||||
null
|
null
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
|
||||||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
import com.tangem.domain.wallets.models.requireColdWallet
|
||||||
import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase
|
import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase
|
||||||
import com.tangem.domain.wallets.usecase.GetSavedWalletChangesUseCase
|
import com.tangem.domain.wallets.usecase.GetSavedWalletChangesUseCase
|
||||||
|
|
@ -191,12 +190,7 @@ internal class MainViewModel @Inject constructor(
|
||||||
userWalletsListManager.selectedUserWallet
|
userWalletsListManager.selectedUserWallet
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { userWallet ->
|
.onEach { userWallet ->
|
||||||
when (userWallet) {
|
Analytics.setContext(userWallet)
|
||||||
is UserWallet.Cold -> Analytics.setContext(userWallet.scanResponse)
|
|
||||||
is UserWallet.Hot -> {
|
|
||||||
// TODO [REDACTED_TASK_KEY]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.flowOn(dispatchers.io)
|
.flowOn(dispatchers.io)
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
||||||
import com.tangem.domain.wallets.legacy.unlockIfLockable
|
import com.tangem.domain.wallets.legacy.unlockIfLockable
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.tap.backupService
|
import com.tangem.tap.backupService
|
||||||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||||
import com.tangem.tap.common.extensions.*
|
import com.tangem.tap.common.extensions.*
|
||||||
|
|
@ -95,7 +95,7 @@ internal class WelcomeMiddleware {
|
||||||
}
|
}
|
||||||
.doOnSuccess { selectedUserWallet ->
|
.doOnSuccess { selectedUserWallet ->
|
||||||
sendSignedInAnalyticsEvent(
|
sendSignedInAnalyticsEvent(
|
||||||
scanResponse = selectedUserWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = selectedUserWallet,
|
||||||
signInType = Basic.SignedIn.SignInType.Biometric,
|
signInType = Basic.SignedIn.SignInType.Biometric,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ internal class WelcomeMiddleware {
|
||||||
store.dispatchWithMain(WelcomeAction.ProceedWithCard.Error(error))
|
store.dispatchWithMain(WelcomeAction.ProceedWithCard.Error(error))
|
||||||
}
|
}
|
||||||
.doOnSuccess {
|
.doOnSuccess {
|
||||||
sendSignedInAnalyticsEvent(scanResponse = scanResponse, signInType = Basic.SignedIn.SignInType.Card)
|
sendSignedInAnalyticsEvent(userWallet, signInType = Basic.SignedIn.SignInType.Card)
|
||||||
|
|
||||||
store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) }
|
store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) }
|
||||||
store.dispatchWithMain(WelcomeAction.ProceedWithCard.Success)
|
store.dispatchWithMain(WelcomeAction.ProceedWithCard.Success)
|
||||||
|
|
@ -142,7 +142,14 @@ internal class WelcomeMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendSignedInAnalyticsEvent(scanResponse: ScanResponse, signInType: Basic.SignedIn.SignInType) {
|
private fun sendSignedInAnalyticsEvent(userWallet: UserWallet, signInType: Basic.SignedIn.SignInType) {
|
||||||
|
// TODO [REDACTED_TASK_KEY]
|
||||||
|
|
||||||
|
if (userWallet !is UserWallet.Cold) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val scanResponse = userWallet.scanResponse
|
||||||
val currency = ParamCardCurrencyConverter().convert(
|
val currency = ParamCardCurrencyConverter().convert(
|
||||||
value = scanResponse.cardTypesResolver,
|
value = scanResponse.cardTypesResolver,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,17 @@ import com.tangem.common.extensions.toHexString
|
||||||
import com.tangem.datasource.api.common.AuthProvider
|
import com.tangem.datasource.api.common.AuthProvider
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
|
|
||||||
internal class DefaultAuthProvider(private val userWalletsListManager: UserWalletsListManager) : AuthProvider {
|
internal class DefaultAuthProvider(private val userWalletsListManager: UserWalletsListManager) : AuthProvider {
|
||||||
|
|
||||||
override fun getCardPublicKey(): String {
|
override fun getCardPublicKey(): String {
|
||||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||||
|
|
||||||
return when (userWallet) {
|
if (userWallet !is UserWallet.Cold) {
|
||||||
is UserWallet.Cold -> userWallet.scanResponse.card.cardPublicKey.toHexString()
|
return ""
|
||||||
is UserWallet.Hot -> userWallet.wallets?.firstOrNull()?.publicKey?.toHexString() ?: ""
|
|
||||||
null -> ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return userWallet.scanResponse.card.cardPublicKey.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCardId(): String {
|
override fun getCardId(): String {
|
||||||
|
|
@ -25,7 +24,7 @@ internal class DefaultAuthProvider(private val userWalletsListManager: UserWalle
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return userWallet.requireColdWallet().scanResponse.card.cardId
|
return userWallet.scanResponse.card.cardId
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCardsPublicKeys(): Map<String, String> {
|
override fun getCardsPublicKeys(): Map<String, String> {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.tap.common.extensions.inject
|
import com.tangem.tap.common.extensions.inject
|
||||||
import com.tangem.tap.domain.model.Currency
|
import com.tangem.tap.domain.model.Currency
|
||||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||||
|
|
@ -25,10 +24,8 @@ internal class CryptoCurrencyConverter(
|
||||||
cryptoCurrencyFactory.createCoin(
|
cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = value.blockchain,
|
blockchain = value.blockchain,
|
||||||
extraDerivationPath = value.derivationPath,
|
extraDerivationPath = value.derivationPath,
|
||||||
scanResponse = requireNotNull(
|
userWallet = requireNotNull(
|
||||||
store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync
|
store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync,
|
||||||
?.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
|
||||||
?.scanResponse,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -37,10 +34,8 @@ internal class CryptoCurrencyConverter(
|
||||||
sdkToken = value.token,
|
sdkToken = value.token,
|
||||||
blockchain = value.blockchain,
|
blockchain = value.blockchain,
|
||||||
extraDerivationPath = value.derivationPath,
|
extraDerivationPath = value.derivationPath,
|
||||||
scanResponse = requireNotNull(
|
userWallet = requireNotNull(
|
||||||
store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync
|
store.inject(DaggerGraphState::generalUserWalletsListManager).selectedUserWalletSync,
|
||||||
?.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
|
||||||
?.scanResponse,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ internal class DefaultDerivationsRepositoryTest {
|
||||||
runCatching {
|
runCatching {
|
||||||
repository.derivePublicKeys(
|
repository.derivePublicKeys(
|
||||||
userWalletId = defaultUserWalletId,
|
userWalletId = defaultUserWalletId,
|
||||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
currencies = MockCryptoCurrencyFactory(userWallet).ethereum.let(::listOf),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onSuccess { Truth.assertThat(it) }
|
.onSuccess { Truth.assertThat(it) }
|
||||||
|
|
@ -129,7 +129,7 @@ internal class DefaultDerivationsRepositoryTest {
|
||||||
runCatching {
|
runCatching {
|
||||||
repository.derivePublicKeys(
|
repository.derivePublicKeys(
|
||||||
userWalletId = defaultUserWalletId,
|
userWalletId = defaultUserWalletId,
|
||||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
currencies = MockCryptoCurrencyFactory(userWallet).ethereum.let(::listOf),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onSuccess { error("Should throws exception") }
|
.onSuccess { error("Should throws exception") }
|
||||||
|
|
@ -155,7 +155,7 @@ internal class DefaultDerivationsRepositoryTest {
|
||||||
runCatching {
|
runCatching {
|
||||||
repository.derivePublicKeys(
|
repository.derivePublicKeys(
|
||||||
userWalletId = defaultUserWalletId,
|
userWalletId = defaultUserWalletId,
|
||||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
currencies = MockCryptoCurrencyFactory(userWallet).ethereum.let(::listOf),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onSuccess { Truth.assertThat(it) }
|
.onSuccess { Truth.assertThat(it) }
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.tangem.common.card.EllipticCurve
|
||||||
import com.tangem.common.extensions.ByteArrayKey
|
import com.tangem.common.extensions.ByteArrayKey
|
||||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
|
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||||
import com.tangem.crypto.hdWallet.DerivationPath
|
import com.tangem.crypto.hdWallet.DerivationPath
|
||||||
import com.tangem.domain.common.configs.GenericCardConfig
|
import com.tangem.domain.common.configs.GenericCardConfig
|
||||||
import com.tangem.domain.common.configs.MultiWalletCardConfig
|
import com.tangem.domain.common.configs.MultiWalletCardConfig
|
||||||
|
|
@ -34,9 +35,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
fun `empty derivations for non supported blockchains`() {
|
fun `empty derivations for non supported blockchains`() {
|
||||||
// Bls is not supported
|
// Bls is not supported
|
||||||
val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).chia.let(::listOf)
|
val currencies = MockCryptoCurrencyFactory(userWallet).chia.let(::listOf)
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).isEmpty()
|
Truth.assertThat(actual).isEmpty()
|
||||||
|
|
@ -55,9 +57,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).chiaAndEthereum
|
val currencies = MockCryptoCurrencyFactory(userWallet).chiaAndEthereum
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).containsExactly(
|
Truth.assertThat(actual).containsExactly(
|
||||||
|
|
@ -69,9 +72,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
@Test
|
@Test
|
||||||
fun `derivations for custom token`() {
|
fun `derivations for custom token`() {
|
||||||
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereumTokenWithBinanceDerivation
|
val currencies = MockCryptoCurrencyFactory(userWallet).ethereumTokenWithBinanceDerivation
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).containsExactly(
|
Truth.assertThat(actual).containsExactly(
|
||||||
|
|
@ -86,9 +90,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
@Test
|
@Test
|
||||||
fun `derivations for cardano`() {
|
fun `derivations for cardano`() {
|
||||||
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).cardano.let(::listOf)
|
val currencies = MockCryptoCurrencyFactory(userWallet).cardano.let(::listOf)
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).containsExactly(
|
Truth.assertThat(actual).containsExactly(
|
||||||
|
|
@ -111,9 +116,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
cardConfig = Wallet2CardConfig,
|
cardConfig = Wallet2CardConfig,
|
||||||
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
||||||
)
|
)
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereum.let(::listOf)
|
val currencies = MockCryptoCurrencyFactory(userWallet).ethereum.let(::listOf)
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).isEmpty()
|
Truth.assertThat(actual).isEmpty()
|
||||||
|
|
@ -125,9 +131,10 @@ internal class MissedDerivationsFinderTest {
|
||||||
cardConfig = MultiWalletCardConfig,
|
cardConfig = MultiWalletCardConfig,
|
||||||
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
||||||
)
|
)
|
||||||
|
val userWallet = MockUserWalletFactory.create(scanResponse)
|
||||||
val finder = MissedDerivationsFinder(scanResponse)
|
val finder = MissedDerivationsFinder(scanResponse)
|
||||||
|
|
||||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereumAndStellar
|
val currencies = MockCryptoCurrencyFactory(userWallet).ethereumAndStellar
|
||||||
val actual = finder.find(currencies)
|
val actual = finder.find(currencies)
|
||||||
|
|
||||||
Truth.assertThat(actual).containsExactly(
|
Truth.assertThat(actual).containsExactly(
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,19 @@ import com.tangem.blockchain.common.Token
|
||||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||||
|
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||||
import com.tangem.domain.common.DerivationStyleProvider
|
import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.configs.GenericCardConfig
|
import com.tangem.domain.common.configs.GenericCardConfig
|
||||||
import com.tangem.domain.common.util.derivationStyleProvider
|
import com.tangem.domain.common.util.derivationStyleProvider
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
class MockCryptoCurrencyFactory(private val scanResponse: ScanResponse = defaultScanResponse) {
|
class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaultUserWallet) {
|
||||||
|
|
||||||
private val factory = CryptoCurrencyFactory(excludedBlockchains = ExcludedBlockchains())
|
private val factory = CryptoCurrencyFactory(excludedBlockchains = ExcludedBlockchains())
|
||||||
|
|
||||||
|
|
@ -49,7 +50,7 @@ class MockCryptoCurrencyFactory(private val scanResponse: ScanResponse = default
|
||||||
val derivationPath = createDerivationPath(
|
val derivationPath = createDerivationPath(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
cardDerivationStyleProvider = scanResponse.derivationStyleProvider,
|
cardDerivationStyleProvider = userWallet.scanResponse.derivationStyleProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
val network = Network(
|
val network = Network(
|
||||||
|
|
@ -72,7 +73,7 @@ class MockCryptoCurrencyFactory(private val scanResponse: ScanResponse = default
|
||||||
fun createCustomToken(blockchain: Blockchain, derivationBlockchain: Blockchain): CryptoCurrency {
|
fun createCustomToken(blockchain: Blockchain, derivationBlockchain: Blockchain): CryptoCurrency {
|
||||||
val derivationPath = Network.DerivationPath.Custom(
|
val derivationPath = Network.DerivationPath.Custom(
|
||||||
value = derivationBlockchain.derivationPath(
|
value = derivationBlockchain.derivationPath(
|
||||||
scanResponse.derivationStyleProvider.getDerivationStyle(),
|
userWallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
|
||||||
)!!.rawPath,
|
)!!.rawPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -114,7 +115,7 @@ class MockCryptoCurrencyFactory(private val scanResponse: ScanResponse = default
|
||||||
),
|
),
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)!!
|
)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,9 +162,11 @@ class MockCryptoCurrencyFactory(private val scanResponse: ScanResponse = default
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|
||||||
val defaultScanResponse = MockScanResponseFactory.create(
|
val defaultUserWallet = MockUserWalletFactory.create(
|
||||||
|
scanResponse = MockScanResponseFactory.create(
|
||||||
cardConfig = GenericCardConfig(2),
|
cardConfig = GenericCardConfig(2),
|
||||||
derivedKeys = emptyMap(),
|
derivedKeys = emptyMap(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@ package com.tangem.data.common.currency
|
||||||
|
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
|
@ -57,23 +56,23 @@ interface CardCryptoCurrencyFactory {
|
||||||
/**
|
/**
|
||||||
* Create default coins for multi currency card
|
* Create default coins for multi currency card
|
||||||
*
|
*
|
||||||
* @param scanResponse scan response
|
* @param userWallet user wallet
|
||||||
*/
|
*/
|
||||||
fun createDefaultCoinsForMultiCurrencyCard(scanResponse: ScanResponse): List<CryptoCurrency.Coin>
|
fun createDefaultCoinsForMultiCurrencyWallet(userWallet: UserWallet): List<CryptoCurrency.Coin>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create primary currency for single currency card
|
* Create primary currency for single currency card
|
||||||
*
|
*
|
||||||
* @param scanResponse scan response
|
* @param userWallet user wallet
|
||||||
*/
|
*/
|
||||||
@Throws
|
@Throws
|
||||||
fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency
|
fun createPrimaryCurrencyForSingleCurrencyCard(userWallet: UserWallet.Cold): CryptoCurrency
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create currencies for single currency card with token (like, NODL)
|
* Create currencies for single currency card with token (like, NODL)
|
||||||
*
|
*
|
||||||
* @param scanResponse scan response
|
* @param userWallet user wallet
|
||||||
*/
|
*/
|
||||||
@Throws
|
@Throws
|
||||||
fun createCurrenciesForSingleCurrencyCardWithToken(scanResponse: ScanResponse): List<CryptoCurrency>
|
fun createCurrenciesForSingleCurrencyCardWithToken(userWallet: UserWallet.Cold): List<CryptoCurrency>
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import com.tangem.blockchainsdk.utils.toCoinId
|
||||||
import com.tangem.data.common.network.NetworkFactory
|
import com.tangem.data.common.network.NetworkFactory
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import com.tangem.blockchain.common.Token as SdkToken
|
import com.tangem.blockchain.common.Token as SdkToken
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ class CryptoCurrencyFactory(
|
||||||
sdkToken: SdkToken,
|
sdkToken: SdkToken,
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
extraDerivationPath: String?,
|
extraDerivationPath: String?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): CryptoCurrency.Token? {
|
): CryptoCurrency.Token? {
|
||||||
if (blockchain == Blockchain.Unknown) {
|
if (blockchain == Blockchain.Unknown) {
|
||||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||||
|
|
@ -56,7 +56,7 @@ class CryptoCurrencyFactory(
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
val id = getTokenId(network, sdkToken)
|
val id = getTokenId(network, sdkToken)
|
||||||
|
|
@ -76,7 +76,7 @@ class CryptoCurrencyFactory(
|
||||||
fun createCoin(
|
fun createCoin(
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
extraDerivationPath: String?,
|
extraDerivationPath: String?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): CryptoCurrency.Coin? {
|
): CryptoCurrency.Coin? {
|
||||||
if (blockchain == Blockchain.Unknown) {
|
if (blockchain == Blockchain.Unknown) {
|
||||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||||
|
|
@ -86,15 +86,15 @@ class CryptoCurrencyFactory(
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
return createCoin(network)
|
return createCoin(network)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCoin(networkId: String, extraDerivationPath: String?, scanResponse: ScanResponse): CryptoCurrency.Coin? {
|
fun createCoin(networkId: String, extraDerivationPath: String?, userWallet: UserWallet): CryptoCurrency.Coin? {
|
||||||
val blockchain = Blockchain.fromNetworkId(networkId) ?: Blockchain.Unknown
|
val blockchain = Blockchain.fromNetworkId(networkId) ?: Blockchain.Unknown
|
||||||
return createCoin(blockchain, extraDerivationPath, scanResponse)
|
return createCoin(blockchain, extraDerivationPath, userWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCoin(network: Network): CryptoCurrency.Coin {
|
fun createCoin(network: Network): CryptoCurrency.Coin {
|
||||||
|
|
@ -115,7 +115,7 @@ class CryptoCurrencyFactory(
|
||||||
token: Token,
|
token: Token,
|
||||||
networkId: String,
|
networkId: String,
|
||||||
extraDerivationPath: String?,
|
extraDerivationPath: String?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): CryptoCurrency.Token? {
|
): CryptoCurrency.Token? {
|
||||||
val sdkToken = SdkToken(
|
val sdkToken = SdkToken(
|
||||||
name = token.name,
|
name = token.name,
|
||||||
|
|
@ -129,7 +129,7 @@ class CryptoCurrencyFactory(
|
||||||
sdkToken = sdkToken,
|
sdkToken = sdkToken,
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +141,8 @@ class CryptoCurrencyFactory(
|
||||||
decimals = cryptoCurrency.decimals,
|
decimals = cryptoCurrency.decimals,
|
||||||
id = cryptoCurrency.id.rawCurrencyId?.value,
|
id = cryptoCurrency.id.rawCurrencyId?.value,
|
||||||
)
|
)
|
||||||
val blockchain = Blockchain.fromNetworkId(cryptoCurrency.network.backendId) ?: Blockchain.Unknown
|
val blockchain =
|
||||||
|
Blockchain.fromNetworkId(cryptoCurrency.network.backendId) ?: Blockchain.Unknown
|
||||||
val id = getTokenId(network, sdkToken)
|
val id = getTokenId(network, sdkToken)
|
||||||
return CryptoCurrency.Token(
|
return CryptoCurrency.Token(
|
||||||
id = id,
|
id = id,
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,9 @@ import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.demo.DemoConfig
|
import com.tangem.domain.demo.DemoConfig
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of factory for creating list of [CryptoCurrency] for selected card
|
* Default implementation of factory for creating list of [CryptoCurrency] for selected card
|
||||||
|
|
@ -54,12 +52,12 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
|
|
||||||
// single-currency wallet with token (NODL)
|
// single-currency wallet with token (NODL)
|
||||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
val currencies = createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse)
|
val currencies = createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||||
return mapOf(cardNetwork to currencies)
|
return mapOf(cardNetwork to currencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
// single-currency wallet
|
// single-currency wallet
|
||||||
val primaryCurrency = createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse)
|
val primaryCurrency = createPrimaryCurrencyForSingleCurrencyCard(userWallet)
|
||||||
return mapOf(cardNetwork to listOf(primaryCurrency))
|
return mapOf(cardNetwork to listOf(primaryCurrency))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,11 +80,11 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
|
|
||||||
// single-currency wallet with token (NODL)
|
// single-currency wallet with token (NODL)
|
||||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
return createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse)
|
return createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// single-currency wallet
|
// single-currency wallet
|
||||||
return createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf)
|
return createPrimaryCurrencyForSingleCurrencyCard(userWallet).let(::listOf)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createCurrenciesForMultiCurrencyCard(
|
override suspend fun createCurrenciesForMultiCurrencyCard(
|
||||||
|
|
@ -98,44 +96,54 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
return getMultiWalletCurrencies(userWallet = userWallet, networks = networks)
|
return getMultiWalletCurrencies(userWallet = userWallet, networks = networks)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createDefaultCoinsForMultiCurrencyCard(scanResponse: ScanResponse): List<CryptoCurrency.Coin> {
|
override fun createDefaultCoinsForMultiCurrencyWallet(userWallet: UserWallet): List<CryptoCurrency.Coin> {
|
||||||
require(scanResponse.cardTypesResolver.isMultiwalletAllowed()) { "It isn't multi-currency wallet" }
|
require(userWallet.isMultiCurrency) { "It isn't multi-currency wallet" }
|
||||||
|
|
||||||
val card = scanResponse.card
|
val blockchains = when (userWallet) {
|
||||||
|
is UserWallet.Cold -> {
|
||||||
|
val card = userWallet.scanResponse.card
|
||||||
|
|
||||||
var blockchains = if (demoConfig.isDemoCardId(card.cardId)) {
|
var blockchainsInternal = if (demoConfig.isDemoCardId(card.cardId)) {
|
||||||
demoConfig.demoBlockchains
|
demoConfig.demoBlockchains
|
||||||
} else {
|
} else {
|
||||||
listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.isTestCard) {
|
if (card.isTestCard) {
|
||||||
blockchains = blockchains.mapNotNull { it.getTestnetVersion() }
|
blockchainsInternal = blockchainsInternal.mapNotNull { it.getTestnetVersion() }
|
||||||
|
}
|
||||||
|
|
||||||
|
blockchainsInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
is UserWallet.Hot -> listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||||
}
|
}
|
||||||
|
|
||||||
return blockchains.mapNotNull {
|
return blockchains.mapNotNull {
|
||||||
cryptoCurrencyFactory.createCoin(
|
cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = it,
|
blockchain = it,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPrimaryCurrencyForSingleCurrencyCard(scanResponse: ScanResponse): CryptoCurrency {
|
override fun createPrimaryCurrencyForSingleCurrencyCard(userWallet: UserWallet.Cold): CryptoCurrency {
|
||||||
require(scanResponse.cardTypesResolver.isSingleWallet()) { "It isn't single-currency wallet" }
|
require(userWallet.scanResponse.cardTypesResolver.isSingleWallet()) {
|
||||||
|
"It isn't single-currency wallet"
|
||||||
|
}
|
||||||
|
|
||||||
return with(getSingleWalletCurrencies(scanResponse)) {
|
return with(getSingleWalletCurrencies(userWallet)) {
|
||||||
primaryToken ?: coin
|
primaryToken ?: coin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCurrenciesForSingleCurrencyCardWithToken(scanResponse: ScanResponse): List<CryptoCurrency> {
|
override fun createCurrenciesForSingleCurrencyCardWithToken(userWallet: UserWallet.Cold): List<CryptoCurrency> {
|
||||||
require(scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
require(userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
"It isn't single-currency wallet with token"
|
"It isn't single-currency wallet with token"
|
||||||
}
|
}
|
||||||
|
|
||||||
return with(getSingleWalletCurrencies(scanResponse)) {
|
return with(getSingleWalletCurrencies(userWallet)) {
|
||||||
listOfNotNull(coin, primaryToken)
|
listOfNotNull(coin, primaryToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +159,7 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
tokens = response.tokens.filter { token ->
|
tokens = response.tokens.filter { token ->
|
||||||
networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath }
|
networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath }
|
||||||
},
|
},
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
.groupBy(CryptoCurrency::network)
|
.groupBy(CryptoCurrency::network)
|
||||||
|
|
||||||
|
|
@ -169,19 +177,19 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
|
|
||||||
return responseCryptoCurrenciesFactory.createCurrencies(
|
return responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
tokens = response.tokens.filter { token -> token.networkId in networkIds },
|
tokens = response.tokens.filter { token -> token.networkId in networkIds },
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
.groupBy { it.network.id.rawId }
|
.groupBy { it.network.id.rawId }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSingleWalletCurrencies(scanResponse: ScanResponse): SingleWalletCurrencies {
|
private fun getSingleWalletCurrencies(userWallet: UserWallet.Cold): SingleWalletCurrencies {
|
||||||
val resolver = scanResponse.cardTypesResolver
|
val resolver = userWallet.cardTypesResolver
|
||||||
val blockchain = resolver.getBlockchain()
|
val blockchain = resolver.getBlockchain()
|
||||||
|
|
||||||
val coin = cryptoCurrencyFactory.createCoin(
|
val coin = cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
requireNotNull(coin) { "Coin for the single currency card cannot be null" }
|
requireNotNull(coin) { "Coin for the single currency card cannot be null" }
|
||||||
|
|
@ -191,12 +199,15 @@ internal class DefaultCardCryptoCurrencyFactory(
|
||||||
sdkToken = token,
|
sdkToken = token,
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return SingleWalletCurrencies(coin = coin, primaryToken = primaryToken)
|
return SingleWalletCurrencies(coin = coin, primaryToken = primaryToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class SingleWalletCurrencies(val coin: CryptoCurrency, val primaryToken: CryptoCurrency?)
|
private data class SingleWalletCurrencies(
|
||||||
|
val coin: CryptoCurrency,
|
||||||
|
val primaryToken: CryptoCurrency?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import com.tangem.data.common.network.NetworkFactory
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.tangem.blockchain.common.Token as SdkToken
|
import com.tangem.blockchain.common.Token as SdkToken
|
||||||
|
|
@ -17,41 +17,41 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
||||||
private val networkFactory: NetworkFactory,
|
private val networkFactory: NetworkFactory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun createCurrency(currencyId: String, response: UserTokensResponse, scanResponse: ScanResponse): CryptoCurrency {
|
fun createCurrency(currencyId: String, response: UserTokensResponse, userWallet: UserWallet): CryptoCurrency {
|
||||||
return response.tokens
|
return response.tokens
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.mapNotNull { createCurrency(it, scanResponse) }
|
.mapNotNull { createCurrency(it, userWallet) }
|
||||||
.first { it.id.value == currencyId }
|
.first { it.id.value == currencyId }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCurrencies(response: UserTokensResponse, scanResponse: ScanResponse): List<CryptoCurrency> {
|
fun createCurrencies(response: UserTokensResponse, userWallet: UserWallet): List<CryptoCurrency> {
|
||||||
return createCurrencies(tokens = response.tokens, scanResponse = scanResponse)
|
return createCurrencies(tokens = response.tokens, userWallet = userWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCurrencies(tokens: List<UserTokensResponse.Token>, scanResponse: ScanResponse): List<CryptoCurrency> {
|
fun createCurrencies(tokens: List<UserTokensResponse.Token>, userWallet: UserWallet): List<CryptoCurrency> {
|
||||||
return tokens
|
return tokens
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.mapNotNull { createCurrency(it, scanResponse) }
|
.mapNotNull { createCurrency(it, userWallet) }
|
||||||
.distinctBy(CryptoCurrency::id)
|
.distinctBy(CryptoCurrency::id)
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCurrency(responseToken: UserTokensResponse.Token, scanResponse: ScanResponse): CryptoCurrency? {
|
fun createCurrency(responseToken: UserTokensResponse.Token, userWallet: UserWallet): CryptoCurrency? {
|
||||||
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
|
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
|
||||||
if (blockchain == null || blockchain == Blockchain.Unknown) {
|
if (blockchain == null || blockchain == Blockchain.Unknown) {
|
||||||
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")
|
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scanResponse.cardTypesResolver.isTestCard()) {
|
if (userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isTestCard()) {
|
||||||
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
||||||
}
|
}
|
||||||
|
|
||||||
val sdkToken = createSdkToken(responseToken)
|
val sdkToken = createSdkToken(responseToken)
|
||||||
return if (sdkToken == null) {
|
return if (sdkToken == null) {
|
||||||
createCoin(blockchain, responseToken, scanResponse)
|
createCoin(blockchain, responseToken, userWallet)
|
||||||
} else {
|
} else {
|
||||||
createToken(blockchain, sdkToken, responseToken.derivationPath, scanResponse)
|
createToken(blockchain, sdkToken, responseToken.derivationPath, userWallet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,12 +70,12 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
||||||
private fun createCoin(
|
private fun createCoin(
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
responseToken: UserTokensResponse.Token,
|
responseToken: UserTokensResponse.Token,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): CryptoCurrency.Coin? {
|
): CryptoCurrency.Coin? {
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = responseToken.derivationPath,
|
extraDerivationPath = responseToken.derivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
return CryptoCurrency.Coin(
|
return CryptoCurrency.Coin(
|
||||||
|
|
@ -105,12 +105,12 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
sdkToken: Token,
|
sdkToken: Token,
|
||||||
responseDerivationPath: String?,
|
responseDerivationPath: String?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): CryptoCurrency.Token? {
|
): CryptoCurrency.Token? {
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = responseDerivationPath,
|
extraDerivationPath = responseDerivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
val id = getTokenId(network, sdkToken)
|
val id = getTokenId(network, sdkToken)
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,9 @@ import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||||
import com.tangem.domain.common.DerivationStyleProvider
|
import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.extensions.canHandleToken
|
import com.tangem.domain.common.extensions.canHandleToken
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
|
||||||
import com.tangem.domain.common.util.derivationStyleProvider
|
import com.tangem.domain.common.util.derivationStyleProvider
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -31,19 +30,18 @@ class NetworkFactory @Inject constructor(
|
||||||
*
|
*
|
||||||
* @param blockchain blockchain
|
* @param blockchain blockchain
|
||||||
* @param extraDerivationPath extra derivation path
|
* @param extraDerivationPath extra derivation path
|
||||||
* @param scanResponse scan response
|
* @param userWallet user wallet
|
||||||
*/
|
*/
|
||||||
fun create(blockchain: Blockchain, extraDerivationPath: String?, scanResponse: ScanResponse): Network? {
|
fun create(blockchain: Blockchain, extraDerivationPath: String?, userWallet: UserWallet): Network? {
|
||||||
return create(
|
return create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
derivationPath = createDerivationPath(
|
derivationPath = createDerivationPath(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
cardDerivationStyleProvider = scanResponse.derivationStyleProvider,
|
cardDerivationStyleProvider = userWallet.derivationStyleProvider,
|
||||||
),
|
),
|
||||||
canHandleTokens = scanResponse.card.canHandleToken(
|
canHandleTokens = userWallet.canHandleToken(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
|
||||||
excludedBlockchains = excludedBlockchains,
|
excludedBlockchains = excludedBlockchains,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -54,17 +52,16 @@ class NetworkFactory @Inject constructor(
|
||||||
*
|
*
|
||||||
* @param networkId network id
|
* @param networkId network id
|
||||||
* @param derivationPath derivation path
|
* @param derivationPath derivation path
|
||||||
* @param scanResponse scan response
|
* @param userWallet user wallet
|
||||||
*/
|
*/
|
||||||
fun create(networkId: Network.ID, derivationPath: Network.DerivationPath, scanResponse: ScanResponse): Network? {
|
fun create(networkId: Network.ID, derivationPath: Network.DerivationPath, userWallet: UserWallet): Network? {
|
||||||
val blockchain = networkId.toBlockchain()
|
val blockchain = networkId.toBlockchain()
|
||||||
|
|
||||||
return create(
|
return create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
canHandleTokens = scanResponse.card.canHandleToken(
|
canHandleTokens = userWallet.canHandleToken(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
|
||||||
excludedBlockchains = excludedBlockchains,
|
excludedBlockchains = excludedBlockchains,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
||||||
val multiWallet = model.multiWallet
|
val multiWallet = model.multiWallet
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
val actual = factory.createDefaultCoinsForMultiCurrencyCard(scanResponse = multiWallet.scanResponse)
|
val actual = factory.createDefaultCoinsForMultiCurrencyWallet(multiWallet)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
val expected = model.expected
|
val expected = model.expected
|
||||||
|
|
@ -355,7 +355,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
val actual = runCatching {
|
val actual = runCatching {
|
||||||
factory.createPrimaryCurrencyForSingleCurrencyCard(scanResponse = singleWallet.scanResponse)
|
factory.createPrimaryCurrencyForSingleCurrencyCard(singleWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -405,7 +405,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
val actual = runCatching {
|
val actual = runCatching {
|
||||||
factory.createCurrenciesForSingleCurrencyCardWithToken(scanResponse = userWallet.scanResponse)
|
factory.createCurrenciesForSingleCurrencyCardWithToken(userWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -554,7 +554,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
|
||||||
sdkToken = userWallet.scanResponse.cardTypesResolver.getPrimaryToken()!!,
|
sdkToken = userWallet.scanResponse.cardTypesResolver.getPrimaryToken()!!,
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)!!
|
)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
|
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||||
import com.tangem.common.test.utils.ProvideTestModels
|
import com.tangem.common.test.utils.ProvideTestModels
|
||||||
import com.tangem.domain.common.DerivationStyleProvider
|
import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.configs.GenericCardConfig
|
import com.tangem.domain.common.configs.GenericCardConfig
|
||||||
|
|
@ -12,6 +13,7 @@ import com.tangem.domain.common.configs.MultiWalletCardConfig
|
||||||
import com.tangem.domain.common.util.derivationStyleProvider
|
import com.tangem.domain.common.util.derivationStyleProvider
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
|
|
@ -43,7 +45,7 @@ class NetworkFactoryTest {
|
||||||
val actual = networkFactory.create(
|
val actual = networkFactory.create(
|
||||||
blockchain = Blockchain.Ethereum,
|
blockchain = Blockchain.Ethereum,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -59,14 +61,14 @@ class NetworkFactoryTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = model.blockchain,
|
blockchain = model.blockchain,
|
||||||
extraDerivationPath = model.extraDerivationPath,
|
extraDerivationPath = model.extraDerivationPath,
|
||||||
scanResponse = model.scanResponse,
|
userWallet = model.userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is CreateTestModel.Second -> {
|
is CreateTestModel.Second -> {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = model.networkId,
|
networkId = model.networkId,
|
||||||
derivationPath = model.derivationPath,
|
derivationPath = model.derivationPath,
|
||||||
scanResponse = model.scanResponse,
|
userWallet = model.userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is CreateTestModel.Third -> {
|
is CreateTestModel.Third -> {
|
||||||
|
|
@ -89,27 +91,27 @@ class NetworkFactoryTest {
|
||||||
CreateTestModel.First(
|
CreateTestModel.First(
|
||||||
blockchain = Blockchain.Unknown,
|
blockchain = Blockchain.Unknown,
|
||||||
extraDerivationPath = null, // never-mind
|
extraDerivationPath = null, // never-mind
|
||||||
scanResponse = createMultiWalletScanResponse(), // never-mind
|
userWallet = createUserWallet(),
|
||||||
expected = null,
|
expected = null,
|
||||||
),
|
),
|
||||||
createFirst(
|
createFirst(
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = createGenericScanResponse(), // default derivation path is null
|
userWallet = createUserWallet(createGenericScanResponse()), // default derivation path is null
|
||||||
expectedDerivationPath = Network.DerivationPath.None,
|
expectedDerivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
createFirst(
|
createFirst(
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"), // use default
|
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"), // use default
|
||||||
),
|
),
|
||||||
createFirst(
|
createFirst(
|
||||||
extraDerivationPath = "m/44'/60'/0'/0/0", // as default
|
extraDerivationPath = "m/44'/60'/0'/0/0", // as default
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
||||||
),
|
),
|
||||||
createFirst(
|
createFirst(
|
||||||
extraDerivationPath = "m/84'/0'/0'/0/0",
|
extraDerivationPath = "m/84'/0'/0'/0/0",
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
expectedDerivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
expectedDerivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
||||||
),
|
),
|
||||||
// endregion
|
// endregion
|
||||||
|
|
@ -118,23 +120,23 @@ class NetworkFactoryTest {
|
||||||
CreateTestModel.Second(
|
CreateTestModel.Second(
|
||||||
networkId = Network.ID(value = "1", derivationPath = Network.DerivationPath.None),
|
networkId = Network.ID(value = "1", derivationPath = Network.DerivationPath.None),
|
||||||
derivationPath = Network.DerivationPath.None, // never-mind
|
derivationPath = Network.DerivationPath.None, // never-mind
|
||||||
scanResponse = createMultiWalletScanResponse(), // never-mind
|
userWallet = createUserWallet(), // never-mind
|
||||||
expected = null,
|
expected = null,
|
||||||
),
|
),
|
||||||
createSecond(
|
createSecond(
|
||||||
scanResponse = createGenericScanResponse(), // default derivation path is null
|
userWallet = createUserWallet(createGenericScanResponse()), // default derivation path is null
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
createSecond(
|
createSecond(
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
createSecond(
|
createSecond(
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
|
||||||
),
|
),
|
||||||
createSecond(
|
createSecond(
|
||||||
scanResponse = createMultiWalletScanResponse(),
|
userWallet = createUserWallet(),
|
||||||
derivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
derivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
|
||||||
),
|
),
|
||||||
// endregion
|
// endregion
|
||||||
|
|
@ -176,13 +178,13 @@ class NetworkFactoryTest {
|
||||||
|
|
||||||
private fun createFirst(
|
private fun createFirst(
|
||||||
extraDerivationPath: String?,
|
extraDerivationPath: String?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
expectedDerivationPath: Network.DerivationPath,
|
expectedDerivationPath: Network.DerivationPath,
|
||||||
): CreateTestModel.First {
|
): CreateTestModel.First {
|
||||||
return CreateTestModel.First(
|
return CreateTestModel.First(
|
||||||
blockchain = Blockchain.Ethereum,
|
blockchain = Blockchain.Ethereum,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = Blockchain.Ethereum.id,
|
value = Blockchain.Ethereum.id,
|
||||||
|
|
@ -195,13 +197,13 @@ class NetworkFactoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSecond(
|
private fun createSecond(
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
derivationPath: Network.DerivationPath,
|
derivationPath: Network.DerivationPath,
|
||||||
): CreateTestModel.Second {
|
): CreateTestModel.Second {
|
||||||
return CreateTestModel.Second(
|
return CreateTestModel.Second(
|
||||||
networkId = Network.ID(value = Blockchain.Ethereum.id, derivationPath = derivationPath),
|
networkId = Network.ID(value = Blockchain.Ethereum.id, derivationPath = derivationPath),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = Blockchain.Ethereum.id,
|
value = Blockchain.Ethereum.id,
|
||||||
|
|
@ -232,6 +234,10 @@ class NetworkFactoryTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createUserWallet(scanResponse: ScanResponse = createMultiWalletScanResponse()): UserWallet.Cold {
|
||||||
|
return MockUserWalletFactory.create(scanResponse)
|
||||||
|
}
|
||||||
|
|
||||||
private fun createMultiWalletScanResponse(): ScanResponse {
|
private fun createMultiWalletScanResponse(): ScanResponse {
|
||||||
return MockScanResponseFactory.create(
|
return MockScanResponseFactory.create(
|
||||||
cardConfig = MultiWalletCardConfig,
|
cardConfig = MultiWalletCardConfig,
|
||||||
|
|
@ -254,14 +260,14 @@ class NetworkFactoryTest {
|
||||||
data class First(
|
data class First(
|
||||||
val blockchain: Blockchain,
|
val blockchain: Blockchain,
|
||||||
val extraDerivationPath: String?,
|
val extraDerivationPath: String?,
|
||||||
val scanResponse: ScanResponse,
|
val userWallet: UserWallet,
|
||||||
override val expected: Network?,
|
override val expected: Network?,
|
||||||
) : CreateTestModel
|
) : CreateTestModel
|
||||||
|
|
||||||
data class Second(
|
data class Second(
|
||||||
val networkId: Network.ID,
|
val networkId: Network.ID,
|
||||||
val derivationPath: Network.DerivationPath,
|
val derivationPath: Network.DerivationPath,
|
||||||
val scanResponse: ScanResponse,
|
val userWallet: UserWallet,
|
||||||
override val expected: Network?,
|
override val expected: Network?,
|
||||||
) : CreateTestModel
|
) : CreateTestModel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ internal class DefaultCustomTokensRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = networkId,
|
networkId = networkId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
"Network [$networkId] not found while finding token"
|
"Network [$networkId] not found while finding token"
|
||||||
|
|
@ -106,8 +106,8 @@ internal class DefaultCustomTokensRepository(
|
||||||
symbol = null,
|
symbol = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
val supportedTokenNetworkIds = userWallet.scanResponse.card
|
val supportedTokenNetworkIds = userWallet
|
||||||
.supportedBlockchains(userWallet.scanResponse.cardTypesResolver, excludedBlockchains)
|
.supportedBlockchains(excludedBlockchains = excludedBlockchains)
|
||||||
.filter(Blockchain::canHandleTokens)
|
.filter(Blockchain::canHandleTokens)
|
||||||
.map(Blockchain::toNetworkId)
|
.map(Blockchain::toNetworkId)
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ internal class DefaultCustomTokensRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = networkId,
|
networkId = networkId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
"Network [$networkId] not found while creating coin"
|
"Network [$networkId] not found while creating coin"
|
||||||
|
|
@ -188,7 +188,7 @@ internal class DefaultCustomTokensRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = networkId,
|
networkId = networkId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
"Network [$networkId] not found while creating custom token"
|
"Network [$networkId] not found while creating custom token"
|
||||||
|
|
@ -261,7 +261,7 @@ internal class DefaultCustomTokensRepository(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import com.tangem.domain.managetokens.repository.ManageTokensRepository
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.pagination.BatchFetchResult
|
import com.tangem.pagination.BatchFetchResult
|
||||||
import com.tangem.pagination.BatchListSource
|
import com.tangem.pagination.BatchListSource
|
||||||
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
|
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
|
||||||
|
|
@ -142,13 +141,13 @@ internal class DefaultManageTokensRepository(
|
||||||
managedCryptoCurrencyFactory.createWithCustomTokens(
|
managedCryptoCurrencyFactory.createWithCustomTokens(
|
||||||
coinsResponse = updatedCoinsResponse,
|
coinsResponse = updatedCoinsResponse,
|
||||||
tokensResponse = tokensResponse,
|
tokensResponse = tokensResponse,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
managedCryptoCurrencyFactory.create(
|
managedCryptoCurrencyFactory.create(
|
||||||
coinsResponse = updatedCoinsResponse,
|
coinsResponse = updatedCoinsResponse,
|
||||||
tokensResponse = tokensResponse,
|
tokensResponse = tokensResponse,
|
||||||
scanResponse = userWallet?.requireColdWallet()?.scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,7 +177,7 @@ internal class DefaultManageTokensRepository(
|
||||||
testnetTokensConfig
|
testnetTokensConfig
|
||||||
},
|
},
|
||||||
tokensResponse = getSavedUserTokensResponseSync(userWallet.walletId),
|
tokensResponse = getSavedUserTokensResponseSync(userWallet.walletId),
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
return BatchFetchResult.Success(
|
return BatchFetchResult.Success(
|
||||||
|
|
@ -190,8 +189,8 @@ internal class DefaultManageTokensRepository(
|
||||||
|
|
||||||
private fun createDefaultUserTokensResponse(userWallet: UserWallet) =
|
private fun createDefaultUserTokensResponse(userWallet: UserWallet) =
|
||||||
userTokensResponseFactory.createUserTokensResponse(
|
userTokensResponseFactory.createUserTokensResponse(
|
||||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(
|
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(
|
||||||
userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
),
|
),
|
||||||
isGroupedByNetwork = false,
|
isGroupedByNetwork = false,
|
||||||
isSortedByBalance = false,
|
isSortedByBalance = false,
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,12 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.local.config.testnet.models.TestnetTokensConfig
|
import com.tangem.datasource.local.config.testnet.models.TestnetTokensConfig
|
||||||
import com.tangem.domain.common.DerivationStyleProvider
|
import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.extensions.canHandleToken
|
import com.tangem.domain.common.extensions.canHandleToken
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
|
||||||
import com.tangem.domain.common.util.derivationStyleProvider
|
import com.tangem.domain.common.util.derivationStyleProvider
|
||||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency.SourceNetwork
|
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency.SourceNetwork
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class ManagedCryptoCurrencyFactory(
|
internal class ManagedCryptoCurrencyFactory(
|
||||||
|
|
@ -32,20 +31,20 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
fun create(
|
fun create(
|
||||||
coinsResponse: CoinsResponse,
|
coinsResponse: CoinsResponse,
|
||||||
tokensResponse: UserTokensResponse?,
|
tokensResponse: UserTokensResponse?,
|
||||||
scanResponse: ScanResponse?,
|
userWallet: UserWallet?,
|
||||||
): List<ManagedCryptoCurrency> {
|
): List<ManagedCryptoCurrency> {
|
||||||
return coinsResponse.coins.mapNotNull { coin ->
|
return coinsResponse.coins.mapNotNull { coin ->
|
||||||
createToken(coin, tokensResponse, coinsResponse.imageHost, scanResponse)
|
createToken(coin, tokensResponse, coinsResponse.imageHost, userWallet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createWithCustomTokens(
|
fun createWithCustomTokens(
|
||||||
coinsResponse: CoinsResponse,
|
coinsResponse: CoinsResponse,
|
||||||
tokensResponse: UserTokensResponse,
|
tokensResponse: UserTokensResponse,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): List<ManagedCryptoCurrency> {
|
): List<ManagedCryptoCurrency> {
|
||||||
val customTokens = createCustomTokens(tokensResponse, scanResponse)
|
val customTokens = createCustomTokens(tokensResponse, userWallet)
|
||||||
val tokens = create(coinsResponse, tokensResponse, scanResponse)
|
val tokens = create(coinsResponse, tokensResponse, userWallet)
|
||||||
|
|
||||||
return customTokens + tokens
|
return customTokens + tokens
|
||||||
}
|
}
|
||||||
|
|
@ -53,10 +52,10 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
fun createTestnetWithCustomTokens(
|
fun createTestnetWithCustomTokens(
|
||||||
testnetTokensConfig: TestnetTokensConfig,
|
testnetTokensConfig: TestnetTokensConfig,
|
||||||
tokensResponse: UserTokensResponse?,
|
tokensResponse: UserTokensResponse?,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): List<ManagedCryptoCurrency> {
|
): List<ManagedCryptoCurrency> {
|
||||||
val customTokens = tokensResponse
|
val customTokens = tokensResponse
|
||||||
?.let { createCustomTokens(it, scanResponse) }
|
?.let { createCustomTokens(it, userWallet) }
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
val testnetTokens = testnetTokensConfig.tokens.map { testnetToken ->
|
val testnetTokens = testnetTokensConfig.tokens.map { testnetToken ->
|
||||||
ManagedCryptoCurrency.Token(
|
ManagedCryptoCurrency.Token(
|
||||||
|
|
@ -69,10 +68,10 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
networkId = network.id,
|
networkId = network.id,
|
||||||
contractAddress = network.address,
|
contractAddress = network.address,
|
||||||
decimals = network.decimalCount,
|
decimals = network.decimalCount,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} ?: emptyList(),
|
} ?: emptyList(),
|
||||||
addedIn = findAddedInNetworks(testnetToken.id, tokensResponse, scanResponse),
|
addedIn = findAddedInNetworks(testnetToken.id, tokensResponse, userWallet),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,28 +80,28 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
|
|
||||||
private fun createCustomTokens(
|
private fun createCustomTokens(
|
||||||
tokensResponse: UserTokensResponse,
|
tokensResponse: UserTokensResponse,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): List<ManagedCryptoCurrency> = tokensResponse.tokens
|
): List<ManagedCryptoCurrency> = tokensResponse.tokens
|
||||||
.mapNotNull { token ->
|
.mapNotNull { token ->
|
||||||
maybeCreateCustomToken(token, scanResponse)
|
maybeCreateCustomToken(token, userWallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeCreateCustomToken(
|
private fun maybeCreateCustomToken(
|
||||||
token: UserTokensResponse.Token,
|
token: UserTokensResponse.Token,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
): ManagedCryptoCurrency? {
|
): ManagedCryptoCurrency? {
|
||||||
val blockchain = Blockchain.fromNetworkId(token.networkId)
|
val blockchain = Blockchain.fromNetworkId(token.networkId)
|
||||||
?.takeUnless { it in excludedBlockchains }
|
?.takeUnless { it in excludedBlockchains }
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
if (!checkIsCustomToken(token, blockchain, scanResponse.derivationStyleProvider)) {
|
if (!checkIsCustomToken(token, blockchain, userWallet.derivationStyleProvider)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = token.derivationPath,
|
extraDerivationPath = token.derivationPath,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
val contractAddress = token.contractAddress
|
val contractAddress = token.contractAddress
|
||||||
|
|
||||||
|
|
@ -135,7 +134,7 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
coinResponse: CoinsResponse.Coin,
|
coinResponse: CoinsResponse.Coin,
|
||||||
tokensResponse: UserTokensResponse?,
|
tokensResponse: UserTokensResponse?,
|
||||||
imageHost: String?,
|
imageHost: String?,
|
||||||
scanResponse: ScanResponse?,
|
userWallet: UserWallet?,
|
||||||
): ManagedCryptoCurrency? {
|
): ManagedCryptoCurrency? {
|
||||||
if (coinResponse.networks.isEmpty() || !coinResponse.active) return null
|
if (coinResponse.networks.isEmpty() || !coinResponse.active) return null
|
||||||
|
|
||||||
|
|
@ -146,7 +145,7 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
networkId = network.networkId,
|
networkId = network.networkId,
|
||||||
contractAddress = network.contractAddress,
|
contractAddress = network.contractAddress,
|
||||||
decimals = network.decimalCount?.toInt(),
|
decimals = network.decimalCount?.toInt(),
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.ifEmpty { return null }
|
.ifEmpty { return null }
|
||||||
|
|
@ -157,7 +156,7 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
symbol = coinResponse.symbol,
|
symbol = coinResponse.symbol,
|
||||||
iconUrl = getIconUrl(coinResponse.id, imageHost),
|
iconUrl = getIconUrl(coinResponse.id, imageHost),
|
||||||
availableNetworks = availableNetworks,
|
availableNetworks = availableNetworks,
|
||||||
addedIn = findAddedInNetworks(coinResponse.id, tokensResponse, scanResponse),
|
addedIn = findAddedInNetworks(coinResponse.id, tokensResponse, userWallet),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,7 +164,7 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
networkId: String,
|
networkId: String,
|
||||||
contractAddress: String?,
|
contractAddress: String?,
|
||||||
decimals: Int?,
|
decimals: Int?,
|
||||||
scanResponse: ScanResponse?,
|
userWallet: UserWallet?,
|
||||||
extraDerivationPath: String? = null,
|
extraDerivationPath: String? = null,
|
||||||
): SourceNetwork? {
|
): SourceNetwork? {
|
||||||
val blockchain = Blockchain.fromNetworkId(networkId)
|
val blockchain = Blockchain.fromNetworkId(networkId)
|
||||||
|
|
@ -175,10 +174,8 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = extraDerivationPath,
|
extraDerivationPath = extraDerivationPath,
|
||||||
derivationStyleProvider = scanResponse?.derivationStyleProvider,
|
derivationStyleProvider = userWallet?.derivationStyleProvider,
|
||||||
canHandleTokens = scanResponse?.let {
|
canHandleTokens = userWallet?.canHandleToken(blockchain, excludedBlockchains) ?: false,
|
||||||
it.card.canHandleToken(blockchain, it.cardTypesResolver, excludedBlockchains)
|
|
||||||
} ?: false, // use card specific check if available
|
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
|
|
@ -207,7 +204,7 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
private fun findAddedInNetworks(
|
private fun findAddedInNetworks(
|
||||||
currencyId: String,
|
currencyId: String,
|
||||||
tokensResponse: UserTokensResponse?,
|
tokensResponse: UserTokensResponse?,
|
||||||
scanResponse: ScanResponse?,
|
userWallet: UserWallet?,
|
||||||
): Set<Network> {
|
): Set<Network> {
|
||||||
if (tokensResponse == null) return emptySet()
|
if (tokensResponse == null) return emptySet()
|
||||||
|
|
||||||
|
|
@ -220,10 +217,8 @@ internal class ManagedCryptoCurrencyFactory(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = token.derivationPath,
|
extraDerivationPath = token.derivationPath,
|
||||||
derivationStyleProvider = scanResponse?.derivationStyleProvider,
|
derivationStyleProvider = userWallet?.derivationStyleProvider,
|
||||||
canHandleTokens = scanResponse?.let {
|
canHandleTokens = userWallet?.canHandleToken(blockchain, excludedBlockchains) ?: true,
|
||||||
it.card.canHandleToken(blockchain, it.cardTypesResolver, excludedBlockchains)
|
|
||||||
} ?: true,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import com.tangem.domain.markets.*
|
||||||
import com.tangem.domain.markets.repositories.MarketsTokenRepository
|
import com.tangem.domain.markets.repositories.MarketsTokenRepository
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.pagination.*
|
import com.tangem.pagination.*
|
||||||
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
|
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
|
@ -259,13 +258,13 @@ internal class DefaultMarketsTokenRepository(
|
||||||
cryptoCurrencyFactory.createCoin(
|
cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val currencyNetwork = networkFactory.create(
|
val currencyNetwork = networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
cryptoCurrencyFactory.createToken(
|
cryptoCurrencyFactory.createToken(
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import com.tangem.data.networks.store.NetworksStatusesStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.models.network.NetworkStatus
|
import com.tangem.domain.models.network.NetworkStatus
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
|
|
@ -48,7 +47,7 @@ internal class DefaultMultiNetworkStatusProducer @AssistedInject constructor(
|
||||||
val network = networkFactory.create(
|
val network = networkFactory.create(
|
||||||
networkId = status.id,
|
networkId = status.id,
|
||||||
derivationPath = status.id.derivationPath,
|
derivationPath = status.id.derivationPath,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return@mapNotNullTo null
|
) ?: return@mapNotNullTo null
|
||||||
|
|
||||||
NetworkStatus(network = network, value = status.value)
|
NetworkStatus(network = network, value = status.value)
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.first().network
|
} returns statuses.first().network
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.last().network
|
} returns statuses.last().network
|
||||||
|
|
||||||
|
|
@ -94,12 +94,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.first().network
|
} returns statuses.first().network
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.last().network
|
} returns statuses.last().network
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = updatedSimpleStatuses.first().id,
|
networkId = updatedSimpleStatuses.first().id,
|
||||||
derivationPath = updatedSimpleStatuses.first().id.derivationPath,
|
derivationPath = updatedSimpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns updatedStatuses.first().network
|
} returns updatedStatuses.first().network
|
||||||
|
|
||||||
|
|
@ -154,7 +154,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = updatedSimpleStatuses.last().id,
|
networkId = updatedSimpleStatuses.last().id,
|
||||||
derivationPath = updatedSimpleStatuses.last().id.derivationPath,
|
derivationPath = updatedSimpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns updatedStatuses.last().network
|
} returns updatedStatuses.last().network
|
||||||
// endregion
|
// endregion
|
||||||
|
|
@ -177,12 +177,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,12 +202,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = updatedSimpleStatuses.first().id,
|
networkId = updatedSimpleStatuses.first().id,
|
||||||
derivationPath = updatedSimpleStatuses.first().id.derivationPath,
|
derivationPath = updatedSimpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = updatedSimpleStatuses.last().id,
|
networkId = updatedSimpleStatuses.last().id,
|
||||||
derivationPath = updatedSimpleStatuses.last().id.derivationPath,
|
derivationPath = updatedSimpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +232,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.first().network
|
} returns statuses.first().network
|
||||||
|
|
||||||
|
|
@ -240,7 +240,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.last().network
|
} returns statuses.last().network
|
||||||
// endregion
|
// endregion
|
||||||
|
|
@ -263,12 +263,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,14 +312,14 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.first().network
|
} returns statuses.first().network
|
||||||
every {
|
every {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns statuses.last().network
|
} returns statuses.last().network
|
||||||
// endregion
|
// endregion
|
||||||
|
|
@ -336,7 +336,7 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
|
|
||||||
verifyOrder(inverse = true) {
|
verifyOrder(inverse = true) {
|
||||||
userWalletsStore.getSyncOrNull(any())
|
userWalletsStore.getSyncOrNull(any())
|
||||||
networkFactory.create(networkId = any(), derivationPath = any(), scanResponse = any())
|
networkFactory.create(networkId = any(), derivationPath = any(), userWallet = any())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Act 2 (emit)
|
// Act 2 (emit)
|
||||||
|
|
@ -353,12 +353,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -410,12 +410,12 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.first().id,
|
networkId = simpleStatuses.first().id,
|
||||||
derivationPath = simpleStatuses.first().id.derivationPath,
|
derivationPath = simpleStatuses.first().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
networkId = simpleStatuses.last().id,
|
networkId = simpleStatuses.last().id,
|
||||||
derivationPath = simpleStatuses.last().id.derivationPath,
|
derivationPath = simpleStatuses.last().id.derivationPath,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -429,10 +429,10 @@ internal class DefaultMultiNetworkStatusProducerTest {
|
||||||
|
|
||||||
val userWallet = MockUserWalletFactory.create(scanResponse = scanResponse)
|
val userWallet = MockUserWalletFactory.create(scanResponse = scanResponse)
|
||||||
|
|
||||||
val ethNetwork = MockCryptoCurrencyFactory(scanResponse = scanResponse).ethereum.network.copy(
|
val ethNetwork = MockCryptoCurrencyFactory(userWallet = userWallet).ethereum.network.copy(
|
||||||
canHandleTokens = true,
|
canHandleTokens = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
val cardanoNetwork = MockCryptoCurrencyFactory(scanResponse = scanResponse).cardano.network
|
val cardanoNetwork = MockCryptoCurrencyFactory(userWallet = userWallet).cardano.network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +208,7 @@ internal class DefaultNFTRepository @Inject constructor(
|
||||||
networkFactory.create(
|
networkFactory.create(
|
||||||
blockchain = it,
|
blockchain = it,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.filter { it.canHandleNFTs(userWalletId) }
|
.filter { it.canHandleNFTs(userWalletId) }
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||||
import com.tangem.domain.onramp.repositories.HotCryptoRepository
|
import com.tangem.domain.onramp.repositories.HotCryptoRepository
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.coroutines.JobHolder
|
import com.tangem.utils.coroutines.JobHolder
|
||||||
import com.tangem.utils.coroutines.runCatching
|
import com.tangem.utils.coroutines.runCatching
|
||||||
|
|
@ -93,7 +92,7 @@ internal class DefaultHotCryptoRepository(
|
||||||
?: error("UserWalletId [$userWalletId] not found")
|
?: error("UserWalletId [$userWalletId] not found")
|
||||||
|
|
||||||
HotCryptoCurrencyConverter(
|
HotCryptoCurrencyConverter(
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
imageHost = it.imageHost,
|
imageHost = it.imageHost,
|
||||||
excludedBlockchains = excludedBlockchains,
|
excludedBlockchains = excludedBlockchains,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,22 @@ import com.tangem.domain.models.StatusSource
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.quote.QuoteStatus
|
import com.tangem.domain.models.quote.QuoteStatus
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converter from [HotCryptoResponse.Token] to [HotCryptoCurrency]
|
* Converter from [HotCryptoResponse.Token] to [HotCryptoCurrency]
|
||||||
*
|
*
|
||||||
* @property scanResponse scan response
|
* @property userWallet scan response
|
||||||
* @property imageHost image host
|
* @property imageHost image host
|
||||||
* @param excludedBlockchains excluded blockchains
|
* @param excludedBlockchains excluded blockchains
|
||||||
*
|
*
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
internal class HotCryptoCurrencyConverter(
|
internal class HotCryptoCurrencyConverter(
|
||||||
private val scanResponse: ScanResponse,
|
private val userWallet: UserWallet,
|
||||||
private val imageHost: String?,
|
private val imageHost: String?,
|
||||||
excludedBlockchains: ExcludedBlockchains,
|
excludedBlockchains: ExcludedBlockchains,
|
||||||
) : Converter<HotCryptoResponse.Token, HotCryptoCurrency?> {
|
) : Converter<HotCryptoResponse.Token, HotCryptoCurrency?> {
|
||||||
|
|
@ -81,7 +81,7 @@ internal class HotCryptoCurrencyConverter(
|
||||||
return networkFactory.create(
|
return networkFactory.create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import com.tangem.domain.swap.models.SwapTransactionListModel
|
||||||
import com.tangem.domain.swap.models.SwapTransactionModel
|
import com.tangem.domain.swap.models.SwapTransactionModel
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.extensions.addOrReplace
|
import com.tangem.utils.extensions.addOrReplace
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
@ -119,7 +118,7 @@ internal class DefaultSwapTransactionRepository(
|
||||||
currencyTxs?.mapNotNull {
|
currencyTxs?.mapNotNull {
|
||||||
listConverter.convertBack(
|
listConverter.convertBack(
|
||||||
value = it,
|
value = it,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
txStatuses = txStatuses,
|
txStatuses = txStatuses,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ package com.tangem.data.swap.converter.transaction
|
||||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||||
import com.tangem.data.swap.models.SwapStatusDTO
|
import com.tangem.data.swap.models.SwapStatusDTO
|
||||||
import com.tangem.data.swap.models.SwapTransactionDTO
|
import com.tangem.data.swap.models.SwapTransactionDTO
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.swap.models.SwapTransactionModel
|
import com.tangem.domain.swap.models.SwapTransactionModel
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.utils.converter.TwoWayConverter
|
import com.tangem.utils.converter.TwoWayConverter
|
||||||
|
|
||||||
internal class SavedSwapTransactionConverter(
|
internal class SavedSwapTransactionConverter(
|
||||||
|
|
@ -35,14 +35,14 @@ internal class SavedSwapTransactionConverter(
|
||||||
|
|
||||||
fun convertBack(
|
fun convertBack(
|
||||||
value: SwapTransactionDTO,
|
value: SwapTransactionDTO,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
txStatuses: Map<String, SwapStatusDTO>,
|
txStatuses: Map<String, SwapStatusDTO>,
|
||||||
): SwapTransactionModel {
|
): SwapTransactionModel {
|
||||||
val status = txStatuses[value.txId]
|
val status = txStatuses[value.txId]
|
||||||
val refundCurrency = status?.refundTokensResponse?.let { id ->
|
val refundCurrency = status?.refundTokensResponse?.let { id ->
|
||||||
responseCryptoCurrenciesFactory.createCurrency(
|
responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = id,
|
responseToken = id,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)
|
val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import com.tangem.data.swap.models.SwapStatusDTO
|
||||||
import com.tangem.data.swap.models.SwapTransactionDTO
|
import com.tangem.data.swap.models.SwapTransactionDTO
|
||||||
import com.tangem.data.swap.models.SwapTransactionListDTO
|
import com.tangem.data.swap.models.SwapTransactionListDTO
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.swap.models.SwapTransactionListModel
|
import com.tangem.domain.swap.models.SwapTransactionListModel
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ internal class SavedSwapTransactionListConverter(
|
||||||
|
|
||||||
fun convertBack(
|
fun convertBack(
|
||||||
value: SwapTransactionListDTO,
|
value: SwapTransactionListDTO,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
txStatuses: Map<String, SwapStatusDTO>,
|
txStatuses: Map<String, SwapStatusDTO>,
|
||||||
): SwapTransactionListModel? {
|
): SwapTransactionListModel? {
|
||||||
val fromToken = value.fromTokensResponse
|
val fromToken = value.fromTokensResponse
|
||||||
|
|
@ -45,16 +45,16 @@ internal class SavedSwapTransactionListConverter(
|
||||||
} else {
|
} else {
|
||||||
val fromCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
val fromCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = fromToken,
|
responseToken = fromToken,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
val toCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
val toCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = toToken,
|
responseToken = toToken,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
return SwapTransactionListModel(
|
return SwapTransactionListModel(
|
||||||
transactions = value.transactions.map { tx ->
|
transactions = value.transactions.map { tx ->
|
||||||
savedSwapTransactionConverter.convertBack(tx, scanResponse, txStatuses)
|
savedSwapTransactionConverter.convertBack(tx, userWallet, txStatuses)
|
||||||
},
|
},
|
||||||
userWalletId = value.userWalletId,
|
userWalletId = value.userWalletId,
|
||||||
fromCryptoCurrencyId = value.fromCryptoCurrencyId,
|
fromCryptoCurrencyId = value.fromCryptoCurrencyId,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.core.utils.catchOn
|
import com.tangem.domain.core.utils.catchOn
|
||||||
import com.tangem.domain.demo.DemoConfig
|
import com.tangem.domain.demo.DemoConfig
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
|
||||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher
|
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher
|
||||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher.Params
|
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher.Params
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
|
@ -60,7 +59,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
|
||||||
if (!userWallet.isMultiCurrency) error("${this::class.simpleName} supports only multi-currency wallet")
|
if (!userWallet.isMultiCurrency) error("${this::class.simpleName} supports only multi-currency wallet")
|
||||||
|
|
||||||
val response = if (userWallet is UserWallet.Cold && userWallet.isDemoWalletWithoutSavedTokens()) {
|
val response = if (userWallet is UserWallet.Cold && userWallet.isDemoWalletWithoutSavedTokens()) {
|
||||||
createDefaultUserTokensResponse(scanResponse = userWallet.scanResponse)
|
createDefaultUserTokensResponse(userWallet = userWallet)
|
||||||
} else {
|
} else {
|
||||||
safeApiCall(
|
safeApiCall(
|
||||||
call = {
|
call = {
|
||||||
|
|
@ -99,7 +98,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
|
||||||
val userWalletId = userWallet.walletId
|
val userWalletId = userWallet.walletId
|
||||||
|
|
||||||
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||||
?: createDefaultUserTokensResponse(scanResponse = userWallet.requireColdWallet().scanResponse)
|
?: createDefaultUserTokensResponse(userWallet = userWallet)
|
||||||
|
|
||||||
if (error is ApiResponseError.HttpException && error.code == ApiResponseError.HttpException.Code.NOT_FOUND) {
|
if (error is ApiResponseError.HttpException && error.code == ApiResponseError.HttpException.Code.NOT_FOUND) {
|
||||||
Timber.w(error, "Requested currencies could not be found in the remote store for: $userWalletId")
|
Timber.w(error, "Requested currencies could not be found in the remote store for: $userWalletId")
|
||||||
|
|
@ -121,9 +120,9 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
|
||||||
expressServiceLoader.update(userWallet = userWallet, userTokens = tokens)
|
expressServiceLoader.update(userWallet = userWallet, userTokens = tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDefaultUserTokensResponse(scanResponse: ScanResponse): UserTokensResponse {
|
private fun createDefaultUserTokensResponse(userWallet: UserWallet): UserTokensResponse {
|
||||||
return userTokensResponseFactory.createUserTokensResponse(
|
return userTokensResponseFactory.createUserTokensResponse(
|
||||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse),
|
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet),
|
||||||
isGroupedByNetwork = false,
|
isGroupedByNetwork = false,
|
||||||
isSortedByBalance = false,
|
isSortedByBalance = false,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr
|
||||||
|
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = response,
|
response = response,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
).toSet()
|
).toSet()
|
||||||
}
|
}
|
||||||
.onEmpty { emit(fallback) }
|
.onEmpty { emit(fallback) }
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,8 @@ internal class DefaultCurrenciesRepository(
|
||||||
)
|
)
|
||||||
|
|
||||||
val token = userTokensResponseFactory.createResponseToken(currency)
|
val token = userTokensResponseFactory.createResponseToken(currency)
|
||||||
val updatedResponse = savedCurrencies.copy(tokens = savedCurrencies.tokens.filterNot { it == token })
|
val updatedResponse =
|
||||||
|
savedCurrencies.copy(tokens = savedCurrencies.tokens.filterNot { it == token })
|
||||||
userTokensSaver.storeAndPush(
|
userTokensSaver.storeAndPush(
|
||||||
userWalletId = userWalletId,
|
userWalletId = userWalletId,
|
||||||
response = updatedResponse,
|
response = updatedResponse,
|
||||||
|
|
@ -229,10 +230,11 @@ internal class DefaultCurrenciesRepository(
|
||||||
): CryptoCurrency {
|
): CryptoCurrency {
|
||||||
return withContext(dispatchers.io) {
|
return withContext(dispatchers.io) {
|
||||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||||
|
userWallet.requireColdWallet()
|
||||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
||||||
|
|
||||||
val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(
|
val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(
|
||||||
userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
fetchExpressAssetsByNetworkIds(
|
fetchExpressAssetsByNetworkIds(
|
||||||
|
|
@ -254,9 +256,10 @@ internal class DefaultCurrenciesRepository(
|
||||||
val scanResponse = userWallet.requireColdWallet().scanResponse
|
val scanResponse = userWallet.requireColdWallet().scanResponse
|
||||||
|
|
||||||
val currencies = if (scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
val currencies = if (scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(scanResponse = scanResponse)
|
cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(userWallet = userWallet)
|
||||||
} else {
|
} else {
|
||||||
cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(scanResponse = scanResponse).run {
|
cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(userWallet = userWallet)
|
||||||
|
.run {
|
||||||
listOf(this)
|
listOf(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -277,10 +280,11 @@ internal class DefaultCurrenciesRepository(
|
||||||
): CryptoCurrency {
|
): CryptoCurrency {
|
||||||
return withContext(dispatchers.io) {
|
return withContext(dispatchers.io) {
|
||||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||||
|
userWallet.requireColdWallet()
|
||||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
||||||
|
|
||||||
val currency = cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(
|
val currency = cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
.find { it.id == id }
|
.find { it.id == id }
|
||||||
requireNotNull(currency) { "Unable to find currency with provided ID: $id" }
|
requireNotNull(currency) { "Unable to find currency with provided ID: $id" }
|
||||||
|
|
@ -320,7 +324,10 @@ internal class DefaultCurrenciesRepository(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(storedTokens, userWallet.requireColdWallet().scanResponse)
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
|
storedTokens,
|
||||||
|
userWallet = userWallet,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getMultiCurrencyWalletCachedCurrenciesSync(userWalletId: UserWalletId) =
|
override suspend fun getMultiCurrencyWalletCachedCurrenciesSync(userWalletId: UserWalletId) =
|
||||||
|
|
@ -335,7 +342,10 @@ internal class DefaultCurrenciesRepository(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(storedTokens, userWallet.requireColdWallet().scanResponse)
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
|
storedTokens,
|
||||||
|
userWallet = userWallet,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getMultiCurrencyWalletCurrency(
|
override suspend fun getMultiCurrencyWalletCurrency(
|
||||||
|
|
@ -360,7 +370,7 @@ internal class DefaultCurrenciesRepository(
|
||||||
responseCryptoCurrenciesFactory.createCurrency(
|
responseCryptoCurrenciesFactory.createCurrency(
|
||||||
currencyId = id,
|
currencyId = id,
|
||||||
response = response,
|
response = response,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,7 +404,7 @@ internal class DefaultCurrenciesRepository(
|
||||||
|
|
||||||
val coin = responseCryptoCurrenciesFactory.createCurrency(
|
val coin = responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = storedCoin,
|
responseToken = storedCoin,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
coin as? CryptoCurrency.Coin ?: error("Unable to create currency")
|
coin as? CryptoCurrency.Coin ?: error("Unable to create currency")
|
||||||
|
|
@ -438,12 +448,15 @@ internal class DefaultCurrenciesRepository(
|
||||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val blockchain = cryptoCurrencyStatus.currency.network.toBlockchain()
|
val blockchain = cryptoCurrencyStatus.currency.network.toBlockchain()
|
||||||
val isBitcoinBlockchain = blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
val isBitcoinBlockchain =
|
||||||
|
blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
||||||
return when {
|
return when {
|
||||||
cryptoCurrencyStatus.currency is CryptoCurrency.Coin && isBitcoinBlockchain -> {
|
cryptoCurrencyStatus.currency is CryptoCurrency.Coin && isBitcoinBlockchain -> {
|
||||||
val outgoingTransactions = cryptoCurrencyStatus.value.pendingTransactions.filter { it.isOutgoing }
|
val outgoingTransactions =
|
||||||
|
cryptoCurrencyStatus.value.pendingTransactions.filter { it.isOutgoing }
|
||||||
outgoingTransactions.isNotEmpty()
|
outgoingTransactions.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
blockchain.isEvm() -> false
|
blockchain.isEvm() -> false
|
||||||
blockchain == Blockchain.Tron || blockchain == Blockchain.TronTestnet -> false
|
blockchain == Blockchain.Tron || blockchain == Blockchain.TronTestnet -> false
|
||||||
else -> {
|
else -> {
|
||||||
|
|
@ -481,6 +494,7 @@ internal class DefaultCurrenciesRepository(
|
||||||
balance = balance,
|
balance = balance,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeePaidSdkCurrency.FeeResource -> FeePaidCurrency.FeeResource(currency = feePaidCurrency.currency)
|
is FeePaidSdkCurrency.FeeResource -> FeePaidCurrency.FeeResource(currency = feePaidCurrency.currency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +522,8 @@ internal class DefaultCurrenciesRepository(
|
||||||
.coins
|
.coins
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?: error("Token not found")
|
?: error("Token not found")
|
||||||
val network = foundToken.networks.firstOrNull { it.networkId == networkId } ?: error("Network not found")
|
val network = foundToken.networks.firstOrNull { it.networkId == networkId }
|
||||||
|
?: error("Network not found")
|
||||||
CryptoCurrencyFactory.Token(
|
CryptoCurrencyFactory.Token(
|
||||||
symbol = foundToken.symbol,
|
symbol = foundToken.symbol,
|
||||||
name = foundToken.name,
|
name = foundToken.name,
|
||||||
|
|
@ -521,7 +536,7 @@ internal class DefaultCurrenciesRepository(
|
||||||
token = token,
|
token = token,
|
||||||
networkId = networkId,
|
networkId = networkId,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
) ?: error("Unable to create token")
|
) ?: error("Unable to create token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,12 +574,14 @@ internal class DefaultCurrenciesRepository(
|
||||||
|
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = storedTokens.copy(tokens = filterResponse),
|
response = storedTokens.copy(tokens = filterResponse),
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val currencies = if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
val currencies =
|
||||||
|
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
getSingleCurrencyWalletWithCardCurrencies(userWallet.walletId)
|
getSingleCurrencyWalletWithCardCurrencies(userWallet.walletId)
|
||||||
} else {
|
} else {
|
||||||
val currency =
|
val currency =
|
||||||
|
|
@ -603,14 +620,15 @@ internal class DefaultCurrenciesRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCardTypesResolver(userWalletId: UserWalletId): CardTypesResolver {
|
override fun getCardTypesResolver(userWalletId: UserWalletId): CardTypesResolver {
|
||||||
return userWalletsStore.getSyncStrict(userWalletId).requireColdWallet().cardTypesResolver // TODO [REDACTED_TASK_KEY]
|
return userWalletsStore.getSyncStrict(userWalletId)
|
||||||
|
.requireColdWallet().cardTypesResolver // TODO [REDACTED_TASK_KEY]
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow<List<CryptoCurrency>> {
|
private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow<List<CryptoCurrency>> {
|
||||||
return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
|
return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = storedTokens,
|
response = storedTokens,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -700,7 +718,10 @@ internal class DefaultCurrenciesRepository(
|
||||||
?: createDefaultUserTokensResponse(userWallet = userWallet)
|
?: createDefaultUserTokensResponse(userWallet = userWallet)
|
||||||
|
|
||||||
if (e is ApiResponseError.HttpException && e.code == ApiResponseError.HttpException.Code.NOT_FOUND) {
|
if (e is ApiResponseError.HttpException && e.code == ApiResponseError.HttpException.Code.NOT_FOUND) {
|
||||||
Timber.w(e, "Requested currencies could not be found in the remote store for: $userWalletId")
|
Timber.w(
|
||||||
|
e,
|
||||||
|
"Requested currencies could not be found in the remote store for: $userWalletId",
|
||||||
|
)
|
||||||
|
|
||||||
userTokensSaver.push(userWalletId, response)
|
userTokensSaver.push(userWalletId, response)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -712,8 +733,8 @@ internal class DefaultCurrenciesRepository(
|
||||||
|
|
||||||
private fun createDefaultUserTokensResponse(userWallet: UserWallet) =
|
private fun createDefaultUserTokensResponse(userWallet: UserWallet) =
|
||||||
userTokensResponseFactory.createUserTokensResponse(
|
userTokensResponseFactory.createUserTokensResponse(
|
||||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(
|
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(
|
||||||
userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
),
|
),
|
||||||
isGroupedByNetwork = false,
|
isGroupedByNetwork = false,
|
||||||
isSortedByBalance = false,
|
isSortedByBalance = false,
|
||||||
|
|
@ -732,9 +753,11 @@ internal class DefaultCurrenciesRepository(
|
||||||
!userWallet.isMultiCurrency && isMultiCurrencyWalletExpected -> {
|
!userWallet.isMultiCurrency && isMultiCurrencyWalletExpected -> {
|
||||||
"Multi currency wallet expected, but single currency wallet was found: $userWalletId"
|
"Multi currency wallet expected, but single currency wallet was found: $userWalletId"
|
||||||
}
|
}
|
||||||
|
|
||||||
userWallet.isMultiCurrency && !isMultiCurrencyWalletExpected -> {
|
userWallet.isMultiCurrency && !isMultiCurrencyWalletExpected -> {
|
||||||
"Single currency wallet expected, but multi currency wallet was found: $userWalletId"
|
"Single currency wallet expected, but multi currency wallet was found: $userWalletId"
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns mockUserWallet
|
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns mockUserWallet
|
||||||
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) } returns null
|
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) } returns null
|
||||||
every {
|
every {
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(mockUserWallet.scanResponse)
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||||
} returns defaultCoins
|
} returns defaultCoins
|
||||||
coEvery {
|
coEvery {
|
||||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
|
|
@ -141,7 +141,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
userWalletsStore.getSyncStrict(key = params.userWalletId)
|
userWalletsStore.getSyncStrict(key = params.userWalletId)
|
||||||
userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId)
|
userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId)
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse = mockUserWallet.scanResponse)
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = userTokensResponse.toLeastTokens())
|
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = userTokensResponse.toLeastTokens())
|
||||||
|
|
@ -187,7 +187,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
coVerify(inverse = true) {
|
coVerify(inverse = true) {
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse = any())
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +229,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
|
|
||||||
coVerify(inverse = true) {
|
coVerify(inverse = true) {
|
||||||
userTokensResponseStore.getSyncOrNull(userWalletId = any())
|
userTokensResponseStore.getSyncOrNull(userWalletId = any())
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse = any())
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse
|
coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse
|
||||||
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null
|
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null
|
||||||
coEvery {
|
coEvery {
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(mockUserWallet.scanResponse)
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||||
} returns defaultCoins
|
} returns defaultCoins
|
||||||
coEvery {
|
coEvery {
|
||||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
|
|
@ -335,7 +335,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
|
|
||||||
coVerify(inverse = true) {
|
coVerify(inverse = true) {
|
||||||
userTokensSaver.push(userWalletId = any(), response = any())
|
userTokensSaver.push(userWalletId = any(), response = any())
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse = any())
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,7 +377,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse
|
coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse
|
||||||
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null
|
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null
|
||||||
coEvery {
|
coEvery {
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(mockUserWallet.scanResponse)
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||||
} returns defaultCoins
|
} returns defaultCoins
|
||||||
coEvery {
|
coEvery {
|
||||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
|
|
@ -394,7 +394,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
userWalletsStore.getSyncStrict(key = params.userWalletId)
|
userWalletsStore.getSyncStrict(key = params.userWalletId)
|
||||||
tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue)
|
tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue)
|
||||||
userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(mockUserWallet.scanResponse)
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||||
userTokensSaver.push(userWalletId = params.userWalletId, response = userTokensResponse)
|
userTokensSaver.push(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||||
|
|
@ -447,7 +447,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
coVerify(inverse = true) {
|
coVerify(inverse = true) {
|
||||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(scanResponse = any())
|
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(inverse = true) {
|
verify(inverse = true) {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(response = any(), scanResponse = any())
|
responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,14 +114,14 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
every {
|
every {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns cryptoCurrencies.toList()
|
} returns cryptoCurrencies.toList()
|
||||||
|
|
||||||
every {
|
every {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = updatedUserTokensResponse,
|
response = updatedUserTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns updatedCryptoCurrencies.toList()
|
} returns updatedCryptoCurrencies.toList()
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
userTokensResponseStore.get(params.userWalletId)
|
userTokensResponseStore.get(params.userWalletId)
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
verifyOrder {
|
verifyOrder {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = updatedUserTokensResponse,
|
response = updatedUserTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +185,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
every {
|
every {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns cryptoCurrencies.toList()
|
} returns cryptoCurrencies.toList()
|
||||||
|
|
||||||
|
|
@ -207,7 +207,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
userTokensResponseStore.get(params.userWalletId)
|
userTokensResponseStore.get(params.userWalletId)
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +251,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
every {
|
every {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} returns cryptoCurrencies.toList()
|
} returns cryptoCurrencies.toList()
|
||||||
|
|
||||||
|
|
@ -282,7 +282,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
verifyOrder {
|
verifyOrder {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(
|
responseCryptoCurrenciesFactory.createCurrencies(
|
||||||
response = userTokensResponse,
|
response = userTokensResponse,
|
||||||
scanResponse = userWallet.scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(inverse = true) {
|
verify(inverse = true) {
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(response = any(), scanResponse = any())
|
responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,7 +335,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
|
||||||
|
|
||||||
verify(inverse = true) {
|
verify(inverse = true) {
|
||||||
userTokensResponseStore.get(any())
|
userTokensResponseStore.get(any())
|
||||||
responseCryptoCurrenciesFactory.createCurrencies(response = any(), scanResponse = any())
|
responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.data.walletconnect.model.CAIP2
|
||||||
import com.tangem.data.walletconnect.model.NamespaceKey
|
import com.tangem.data.walletconnect.model.NamespaceKey
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
|
|
||||||
internal interface WcNamespaceConverter {
|
internal interface WcNamespaceConverter {
|
||||||
|
|
||||||
|
|
@ -27,7 +26,7 @@ internal interface WcNamespaceConverter {
|
||||||
return NetworkFactory(excludedBlockchains).create(
|
return NetworkFactory(excludedBlockchains).create(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = wallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = wallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,3 +24,7 @@ internal class TangemDerivationStyleProvider(
|
||||||
return card.batchId == "AC01" || card.batchId == "AC02" || card.batchId == "CB95"
|
return card.batchId == "AC01" || card.batchId == "AC02" || card.batchId == "CB95"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class TangemHotDerivationStyleProvider : DerivationStyleProvider {
|
||||||
|
override fun getDerivationStyle(): DerivationStyle? = DerivationStyle.V3
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,9 @@ import com.tangem.common.card.FirmwareVersion
|
||||||
import com.tangem.domain.common.CardTypesResolver
|
import com.tangem.domain.common.CardTypesResolver
|
||||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||||
import com.tangem.domain.common.configs.CardConfig
|
import com.tangem.domain.common.configs.CardConfig
|
||||||
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.models.scan.CardDTO
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
|
||||||
// TODO: refactor [REDACTED_JIRA]
|
// TODO: refactor [REDACTED_JIRA]
|
||||||
|
|
||||||
|
|
@ -17,6 +19,20 @@ import com.tangem.domain.models.scan.CardDTO
|
||||||
val FirmwareVersion.Companion.SolanaTokensAvailable
|
val FirmwareVersion.Companion.SolanaTokensAvailable
|
||||||
get() = FirmwareVersion(4, 52)
|
get() = FirmwareVersion(4, 52)
|
||||||
|
|
||||||
|
fun UserWallet.supportedBlockchains(excludedBlockchains: ExcludedBlockchains): List<Blockchain> {
|
||||||
|
return when (this) {
|
||||||
|
is UserWallet.Cold -> {
|
||||||
|
scanResponse.card.supportedBlockchains(
|
||||||
|
excludedBlockchains = excludedBlockchains,
|
||||||
|
cardTypesResolver = this.cardTypesResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is UserWallet.Hot -> {
|
||||||
|
Blockchain.entries.filter { it !in excludedBlockchains }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun CardDTO.supportedBlockchains(
|
fun CardDTO.supportedBlockchains(
|
||||||
cardTypesResolver: CardTypesResolver,
|
cardTypesResolver: CardTypesResolver,
|
||||||
excludedBlockchains: ExcludedBlockchains,
|
excludedBlockchains: ExcludedBlockchains,
|
||||||
|
|
@ -55,6 +71,33 @@ fun CardDTO.supportedTokens(
|
||||||
return tokensSupportedByCard.filter { isTestCard == it.isTestnet() }
|
return tokensSupportedByCard.filter { isTestCard == it.isTestnet() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun UserWallet.canHandleToken(supportedTokens: List<Blockchain>, blockchain: Blockchain): Boolean {
|
||||||
|
return when (this) {
|
||||||
|
is UserWallet.Cold -> {
|
||||||
|
scanResponse.card.canHandleToken(
|
||||||
|
supportedTokens = supportedTokens,
|
||||||
|
blockchain = blockchain,
|
||||||
|
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is UserWallet.Hot -> blockchain in supportedTokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun UserWallet.canHandleToken(blockchain: Blockchain, excludedBlockchains: ExcludedBlockchains): Boolean {
|
||||||
|
return when (this) {
|
||||||
|
is UserWallet.Cold -> {
|
||||||
|
scanResponse.card.canHandleToken(
|
||||||
|
blockchain = blockchain,
|
||||||
|
excludedBlockchains = excludedBlockchains,
|
||||||
|
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is UserWallet.Hot -> blockchain !in excludedBlockchains
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The same as [CardDTO.supportedTokens] but with supportedTokens input, if previously calculated
|
* The same as [CardDTO.supportedTokens] but with supportedTokens input, if previously calculated
|
||||||
*/
|
*/
|
||||||
|
|
@ -101,7 +144,8 @@ fun CardDTO.canHandleBlockchain(
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val cardConfig = CardConfig.createConfig(this)
|
val cardConfig = CardConfig.createConfig(this)
|
||||||
val primaryCurveForBlockchain = cardConfig.primaryCurve(blockchain)
|
val primaryCurveForBlockchain = cardConfig.primaryCurve(blockchain)
|
||||||
val isContainsBlockchain = blockchain in supportedBlockchains(cardTypesResolver, excludedBlockchains)
|
val isContainsBlockchain =
|
||||||
|
blockchain in supportedBlockchains(cardTypesResolver, excludedBlockchains)
|
||||||
val isWalletForCurveExists = wallets.any { it.curve == primaryCurveForBlockchain }
|
val isWalletForCurveExists = wallets.any { it.curve == primaryCurveForBlockchain }
|
||||||
// fixme: check for first wallets with 1 curve and remove condition
|
// fixme: check for first wallets with 1 curve and remove condition
|
||||||
return if (cardTypesResolver.isTangemWallet() || cardTypesResolver.isWallet2()) {
|
return if (cardTypesResolver.isTangemWallet() || cardTypesResolver.isWallet2()) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.common.CardTypesResolver
|
||||||
import com.tangem.domain.common.DerivationStyleProvider
|
import com.tangem.domain.common.DerivationStyleProvider
|
||||||
import com.tangem.domain.common.TangemCardTypesResolver
|
import com.tangem.domain.common.TangemCardTypesResolver
|
||||||
import com.tangem.domain.common.TangemDerivationStyleProvider
|
import com.tangem.domain.common.TangemDerivationStyleProvider
|
||||||
|
import com.tangem.domain.common.TangemHotDerivationStyleProvider
|
||||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||||
import com.tangem.domain.common.configs.CardConfig
|
import com.tangem.domain.common.configs.CardConfig
|
||||||
|
|
@ -23,6 +24,12 @@ val ScanResponse.cardTypesResolver: CardTypesResolver
|
||||||
walletData = walletData,
|
walletData = walletData,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val UserWallet.derivationStyleProvider: DerivationStyleProvider
|
||||||
|
get() = when (this) {
|
||||||
|
is UserWallet.Cold -> this.scanResponse.derivationStyleProvider
|
||||||
|
is UserWallet.Hot -> TangemHotDerivationStyleProvider()
|
||||||
|
}
|
||||||
|
|
||||||
val ScanResponse.derivationStyleProvider: DerivationStyleProvider
|
val ScanResponse.derivationStyleProvider: DerivationStyleProvider
|
||||||
get() = card.derivationStyleProvider
|
get() = card.derivationStyleProvider
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable(with = MobileWalletAsStringSerializer::class)
|
@Serializable(with = MobileWalletAsStringSerializer::class)
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
class MobileWallet(
|
data class MobileWallet(
|
||||||
@Json(name = "publicKey")
|
@Json(name = "publicKey")
|
||||||
val publicKey: ByteArray,
|
val publicKey: ByteArray,
|
||||||
@Json(name = "chainCode")
|
@Json(name = "chainCode")
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import com.tangem.domain.tokens.operations.BaseCurrencyStatusOperations
|
||||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
|
|
@ -44,11 +44,10 @@ class GetNetworkCoinStatusUseCase(
|
||||||
derivationPath: Network.DerivationPath,
|
derivationPath: Network.DerivationPath,
|
||||||
): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
||||||
val userWalletId = userWallet.walletId
|
val userWalletId = userWallet.walletId
|
||||||
val cardTypesResolver = userWallet.requireColdWallet().cardTypesResolver // TODO [REDACTED_TASK_KEY]
|
|
||||||
|
|
||||||
val maybeCurrency = if (userWallet.isMultiCurrency) {
|
val maybeCurrency = if (userWallet.isMultiCurrency) {
|
||||||
currencyStatusOperations.getNetworkCoinSync(userWalletId, networkId, derivationPath)
|
currencyStatusOperations.getNetworkCoinSync(userWalletId, networkId, derivationPath)
|
||||||
} else if (cardTypesResolver.isSingleWalletWithToken()) {
|
} else if (userWallet is UserWallet.Cold && userWallet.cardTypesResolver.isSingleWalletWithToken()) {
|
||||||
currencyStatusOperations.getNetworkCoinForSingleWalletWithTokenSync(userWalletId, networkId)
|
currencyStatusOperations.getNetworkCoinForSingleWalletWithTokenSync(userWalletId, networkId)
|
||||||
} else {
|
} else {
|
||||||
currencyStatusOperations.getPrimaryCurrencyStatusSync(userWalletId)
|
currencyStatusOperations.getPrimaryCurrencyStatusSync(userWalletId)
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ sealed interface UserWallet {
|
||||||
override val walletId: UserWalletId,
|
override val walletId: UserWalletId,
|
||||||
val hotWalletId: HotWalletId,
|
val hotWalletId: HotWalletId,
|
||||||
val wallets: List<MobileWallet>?,
|
val wallets: List<MobileWallet>?,
|
||||||
|
val backedUp: Boolean,
|
||||||
) : UserWallet {
|
) : UserWallet {
|
||||||
|
|
||||||
val isLocked: Boolean get() = wallets == null
|
val isLocked: Boolean get() = wallets == null
|
||||||
|
|
|
||||||
|
|
@ -11,29 +11,31 @@ import com.tangem.hot.sdk.model.DeriveWalletRequest
|
||||||
import com.tangem.hot.sdk.model.HotAuth
|
import com.tangem.hot.sdk.model.HotAuth
|
||||||
import com.tangem.hot.sdk.model.HotWalletId
|
import com.tangem.hot.sdk.model.HotWalletId
|
||||||
import com.tangem.hot.sdk.model.UnlockHotWallet
|
import com.tangem.hot.sdk.model.UnlockHotWallet
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class HotUserWalletBuilder @AssistedInject constructor(
|
class HotUserWalletBuilder @AssistedInject constructor(
|
||||||
@Assisted private val hotWalletId: HotWalletId,
|
@Assisted private val hotWalletId: HotWalletId,
|
||||||
private val hotSdk: TangemHotSdk,
|
private val hotSdk: TangemHotSdk,
|
||||||
private val generateWalletNameUseCase: GenerateWalletNameUseCase,
|
private val generateWalletNameUseCase: GenerateWalletNameUseCase,
|
||||||
|
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun build(): UserWallet.Hot {
|
suspend fun build(): UserWallet.Hot = withContext(dispatcherProvider.default) {
|
||||||
val allNetworks = Blockchain.entries // TODO use HotDerivationsRepository to get supported networks
|
val allNetworks = Blockchain.entries // TODO use HotDerivationsRepository to get supported networks
|
||||||
val requests = allNetworks.map {
|
val curves = allNetworks.map { it.getSupportedCurves() }.flatten().toSet()
|
||||||
val curves = it.getSupportedCurves()
|
val requests = curves.sortedBy { it.ordinal }.map { curve ->
|
||||||
val derivationPath = it.derivationPath(DerivationStyle.V3)
|
val derivationPaths = allNetworks.filter { curve in it.getSupportedCurves() }
|
||||||
|
.mapNotNull { it.derivationPath(DerivationStyle.V3) }
|
||||||
|
|
||||||
curves.map {
|
|
||||||
DeriveWalletRequest.Request(
|
DeriveWalletRequest.Request(
|
||||||
curve = it,
|
curve = curve,
|
||||||
paths = listOfNotNull(derivationPath),
|
paths = derivationPaths,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.flatten()
|
|
||||||
|
|
||||||
val derivationResult = hotSdk.derivePublicKey(
|
val derivationResult = hotSdk.derivePublicKey(
|
||||||
unlockHotWallet = UnlockHotWallet(
|
unlockHotWallet = UnlockHotWallet(
|
||||||
|
|
@ -54,11 +56,12 @@ class HotUserWalletBuilder @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserWallet.Hot(
|
UserWallet.Hot(
|
||||||
name = generateWalletNameUseCase.invokeForHot(),
|
name = generateWalletNameUseCase.invokeForHot(),
|
||||||
walletId = UserWalletId(wallets.first().publicKey),
|
walletId = UserWalletId(wallets.first().publicKey),
|
||||||
hotWalletId = hotWalletId,
|
hotWalletId = hotWalletId,
|
||||||
wallets = wallets,
|
wallets = wallets,
|
||||||
|
backedUp = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class GenerateWalletNameUseCase(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun invokeForHot(): String {
|
fun invokeForHot(): String {
|
||||||
val defaultName = "Mobile Wallet"
|
val defaultName = "Wallet"
|
||||||
val existingNames = userWalletsListManager.userWalletsSync.map { it.name }.toSet()
|
val existingNames = userWalletsListManager.userWalletsSync.map { it.name }.toSet()
|
||||||
return suggestedWalletName(defaultName, existingNames)
|
return suggestedWalletName(defaultName, existingNames)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
|
|
@ -49,6 +50,8 @@ internal class CreateMobileWalletModel @Inject constructor(
|
||||||
)
|
)
|
||||||
router.push(AppRoute.Wallet)
|
router.push(AppRoute.Wallet)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
|
Timber.e(it)
|
||||||
|
|
||||||
uiState.update {
|
uiState.update {
|
||||||
it.copy(createButtonLoading = false)
|
it.copy(createButtonLoading = false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,30 +7,18 @@ import com.tangem.features.hotwallet.createmobilewallet.DefaultCreateMobileWalle
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.components.ActivityComponent
|
|
||||||
import dagger.hilt.android.scopes.ActivityScoped
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import dagger.multibindings.ClassKey
|
import dagger.multibindings.ClassKey
|
||||||
import dagger.multibindings.IntoMap
|
import dagger.multibindings.IntoMap
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
internal object CreateMobileWalletModule
|
internal interface CreateMobileWalletModuleBinds {
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(ActivityComponent::class)
|
|
||||||
internal interface CreateMobileWalletModuleActivityBinds {
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@ActivityScoped
|
|
||||||
fun bindCreateMobileWalletComponentFactory(
|
fun bindCreateMobileWalletComponentFactory(
|
||||||
impl: DefaultCreateMobileWalletComponent.Factory,
|
impl: DefaultCreateMobileWalletComponent.Factory,
|
||||||
): CreateMobileWalletComponent.Factory
|
): CreateMobileWalletComponent.Factory
|
||||||
}
|
|
||||||
|
|
||||||
@Module
|
|
||||||
@InstallIn(SingletonComponent::class)
|
|
||||||
internal interface CreateMobileWalletModuleBinds {
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
|
|
@ -11,7 +11,6 @@ import com.tangem.datasource.api.tangemTech.models.StartReferralBody
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.referral.converters.ReferralConverter
|
import com.tangem.feature.referral.converters.ReferralConverter
|
||||||
import com.tangem.feature.referral.domain.ReferralRepository
|
import com.tangem.feature.referral.domain.ReferralRepository
|
||||||
import com.tangem.feature.referral.domain.models.ReferralData
|
import com.tangem.feature.referral.domain.models.ReferralData
|
||||||
|
|
@ -97,13 +96,13 @@ internal class ReferralRepositoryImpl @Inject constructor(
|
||||||
sdkToken = sdkToken,
|
sdkToken = sdkToken,
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
cryptoCurrencyFactory.createCoin(
|
cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.swap.converters.*
|
import com.tangem.feature.swap.converters.*
|
||||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||||
import com.tangem.feature.swap.domain.models.ExpressDataError
|
import com.tangem.feature.swap.domain.models.ExpressDataError
|
||||||
|
|
@ -404,12 +403,7 @@ internal class DefaultSwapRepository(
|
||||||
cryptoCurrencyFactory.createCoin(
|
cryptoCurrencyFactory.createCoin(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
extraDerivationPath = null,
|
extraDerivationPath = null,
|
||||||
scanResponse = requireNotNull(
|
userWallet = requireNotNull(userWalletsListManager.selectedUserWalletSync),
|
||||||
userWalletsListManager
|
|
||||||
.selectedUserWalletSync
|
|
||||||
?.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
|
||||||
?.scanResponse,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import com.tangem.datasource.local.preferences.utils.getObjectMap
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.swap.converters.SavedSwapTransactionListConverter
|
import com.tangem.feature.swap.converters.SavedSwapTransactionListConverter
|
||||||
import com.tangem.feature.swap.domain.SwapTransactionRepository
|
import com.tangem.feature.swap.domain.SwapTransactionRepository
|
||||||
import com.tangem.feature.swap.domain.models.domain.*
|
import com.tangem.feature.swap.domain.models.domain.*
|
||||||
|
|
@ -104,7 +103,7 @@ internal class DefaultSwapTransactionRepository(
|
||||||
currencyTxs?.mapNotNull {
|
currencyTxs?.mapNotNull {
|
||||||
converter.convertBack(
|
converter.convertBack(
|
||||||
value = it,
|
value = it,
|
||||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
userWallet = userWallet,
|
||||||
txStatuses = txStatuses,
|
txStatuses = txStatuses,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.tangem.feature.swap.converters
|
||||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||||
import com.tangem.data.common.currency.UserTokensResponseFactory
|
import com.tangem.data.common.currency.UserTokensResponseFactory
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.feature.swap.domain.models.domain.ExchangeStatusModel
|
import com.tangem.feature.swap.domain.models.domain.ExchangeStatusModel
|
||||||
import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModel
|
import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModel
|
||||||
|
|
@ -32,7 +32,7 @@ internal class SavedSwapTransactionListConverter(
|
||||||
|
|
||||||
fun convertBack(
|
fun convertBack(
|
||||||
value: SavedSwapTransactionListModelInner,
|
value: SavedSwapTransactionListModelInner,
|
||||||
scanResponse: ScanResponse,
|
userWallet: UserWallet,
|
||||||
txStatuses: Map<String, ExchangeStatusModel>,
|
txStatuses: Map<String, ExchangeStatusModel>,
|
||||||
): SavedSwapTransactionListModel? {
|
): SavedSwapTransactionListModel? {
|
||||||
val fromToken = value.fromTokensResponse
|
val fromToken = value.fromTokensResponse
|
||||||
|
|
@ -42,11 +42,11 @@ internal class SavedSwapTransactionListConverter(
|
||||||
} else {
|
} else {
|
||||||
val fromCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
val fromCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = fromToken,
|
responseToken = fromToken,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
val toCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
val toCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = toToken,
|
responseToken = toToken,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
) ?: return null
|
) ?: return null
|
||||||
|
|
||||||
return SavedSwapTransactionListModel(
|
return SavedSwapTransactionListModel(
|
||||||
|
|
@ -55,7 +55,7 @@ internal class SavedSwapTransactionListConverter(
|
||||||
val refundCurrency = status?.refundTokensResponse?.let { id ->
|
val refundCurrency = status?.refundTokensResponse?.let { id ->
|
||||||
responseCryptoCurrenciesFactory.createCurrency(
|
responseCryptoCurrenciesFactory.createCurrency(
|
||||||
responseToken = id,
|
responseToken = id,
|
||||||
scanResponse = scanResponse,
|
userWallet = userWallet,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)
|
val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,22 @@ internal object WalletAdditionalInfoFactory {
|
||||||
wallet.resolveSingleCurrencyInfo(currencyAmount)
|
wallet.resolveSingleCurrencyInfo(currencyAmount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserWallet.Hot -> TODO("[REDACTED_TASK_KEY]")
|
is UserWallet.Hot -> wallet.resolveAdditionalInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun UserWallet.Hot.resolveAdditionalInfo(): WalletAdditionalInfo {
|
||||||
|
return WalletAdditionalInfo(
|
||||||
|
hideable = false,
|
||||||
|
content = TextReference.Res(R.string.hw_mobile_wallet) +
|
||||||
|
when {
|
||||||
|
isLocked -> DIVIDER + TextReference.Res(R.string.common_locked)
|
||||||
|
backedUp.not() -> DIVIDER + TextReference.Res(R.string.hw_backup_no_backup)
|
||||||
|
else -> TextReference.Str("")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun UserWallet.Cold.resolveMultiCurrencyInfo(): WalletAdditionalInfo {
|
private fun UserWallet.Cold.resolveMultiCurrencyInfo(): WalletAdditionalInfo {
|
||||||
return if (isLocked) {
|
return if (isLocked) {
|
||||||
WalletAdditionalInfo(
|
WalletAdditionalInfo(
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,11 @@ internal class WalletImageResolver @Inject constructor(
|
||||||
/** Get a specified wallet [userWallet] image */
|
/** Get a specified wallet [userWallet] image */
|
||||||
@Suppress("CyclomaticComplexMethod")
|
@Suppress("CyclomaticComplexMethod")
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
fun resolve(userWallet: UserWallet.Cold): Int? {
|
fun resolve(userWallet: UserWallet): Int? {
|
||||||
|
if (userWallet !is UserWallet.Cold) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
||||||
|
|
||||||
val cobrandImage = Wallet2CobrandImage.entries.firstOrNull {
|
val cobrandImage = Wallet2CobrandImage.entries.firstOrNull {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ internal class WalletContentLoaderFactory @Inject constructor(
|
||||||
userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isVisaWallet() -> {
|
userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isVisaWallet() -> {
|
||||||
visaWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh)
|
visaWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh)
|
||||||
}
|
}
|
||||||
!userWallet.isMultiCurrency -> {
|
userWallet is UserWallet.Cold && !userWallet.isMultiCurrency -> {
|
||||||
singleWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh)
|
singleWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal class SingleWalletContentLoader(
|
internal class SingleWalletContentLoader(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
private val isRefresh: Boolean,
|
private val isRefresh: Boolean,
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ internal class SingleWalletContentLoaderFactory @Inject constructor(
|
||||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader {
|
fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader {
|
||||||
return SingleWalletContentLoader(
|
return SingleWalletContentLoader(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal class SingleWalletWithTokenContentLoader(
|
internal class SingleWalletWithTokenContentLoader(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
private val tokenListAnalyticsSender: TokenListAnalyticsSender,
|
private val tokenListAnalyticsSender: TokenListAnalyticsSender,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
||||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): SingleWalletWithTokenContentLoader {
|
fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents): SingleWalletWithTokenContentLoader {
|
||||||
return SingleWalletWithTokenContentLoader(
|
return SingleWalletWithTokenContentLoader(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscribe
|
||||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||||
|
|
||||||
internal class VisaWalletContentLoader(
|
internal class VisaWalletContentLoader(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
private val isRefresh: Boolean,
|
private val isRefresh: Boolean,
|
||||||
private val stateController: WalletStateController,
|
private val stateController: WalletStateController,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ internal class VisaWalletContentLoaderFactory @Inject constructor(
|
||||||
private val getVisaTxHistoryUseCase: GetVisaTxHistoryUseCase,
|
private val getVisaTxHistoryUseCase: GetVisaTxHistoryUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader {
|
fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader {
|
||||||
return VisaWalletContentLoader(
|
return VisaWalletContentLoader(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.isLocked
|
import com.tangem.domain.wallets.models.isLocked
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
||||||
|
|
@ -55,8 +54,6 @@ internal class InitializeWalletsTransformer(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLockedState(userWallet: UserWallet): WalletState {
|
private fun createLockedState(userWallet: UserWallet): WalletState {
|
||||||
userWallet.requireColdWallet()
|
|
||||||
|
|
||||||
return userWallet.createStateByWalletType(
|
return userWallet.createStateByWalletType(
|
||||||
multiCurrencyCreator = {
|
multiCurrencyCreator = {
|
||||||
WalletState.MultiCurrency.Locked(
|
WalletState.MultiCurrency.Locked(
|
||||||
|
|
@ -87,7 +84,7 @@ internal class InitializeWalletsTransformer(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun UserWallet.Cold.toLockedWalletCardState(): WalletCardState {
|
private fun UserWallet.toLockedWalletCardState(): WalletCardState {
|
||||||
return WalletCardState.LockedContent(
|
return WalletCardState.LockedContent(
|
||||||
id = walletId,
|
id = walletId,
|
||||||
title = name,
|
title = name,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.common.util.getCardsCount
|
import com.tangem.domain.common.util.getCardsCount
|
||||||
import com.tangem.domain.tokens.error.TokenListError
|
import com.tangem.domain.tokens.error.TokenListError
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||||
|
|
@ -57,8 +56,6 @@ internal class SetTokenListErrorTransformer(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun WalletCardState.toLoadedState(): WalletCardState {
|
private fun WalletCardState.toLoadedState(): WalletCardState {
|
||||||
selectedWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
|
||||||
|
|
||||||
return WalletCardState.Content(
|
return WalletCardState.Content(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
|
|
@ -68,7 +65,10 @@ internal class SetTokenListErrorTransformer(
|
||||||
balance = BigDecimal.ZERO.format {
|
balance = BigDecimal.ZERO.format {
|
||||||
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||||
},
|
},
|
||||||
cardCount = selectedWallet.getCardsCount(),
|
cardCount = when (selectedWallet) {
|
||||||
|
is UserWallet.Cold -> selectedWallet.getCardsCount()
|
||||||
|
is UserWallet.Hot -> null
|
||||||
|
},
|
||||||
isZeroBalance = true,
|
isZeroBalance = true,
|
||||||
isBalanceFlickering = false,
|
isBalanceFlickering = false,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.visa.exception.RefreshTokenExpiredException
|
import com.tangem.domain.visa.exception.RefreshTokenExpiredException
|
||||||
import com.tangem.domain.visa.model.VisaCurrency
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.BalancesAndLimitsBlockState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.BalancesAndLimitsBlockState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||||
|
|
@ -27,7 +26,7 @@ import org.joda.time.DateTime
|
||||||
import org.joda.time.Days
|
import org.joda.time.Days
|
||||||
|
|
||||||
internal class SetVisaInfoTransformer(
|
internal class SetVisaInfoTransformer(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val maybeVisaCurrency: Either<Throwable, VisaCurrency>,
|
private val maybeVisaCurrency: Either<Throwable, VisaCurrency>,
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
) : TypedWalletStateTransformer<WalletState.Visa.Content>(
|
) : TypedWalletStateTransformer<WalletState.Visa.Content>(
|
||||||
|
|
@ -76,8 +75,6 @@ internal class SetVisaInfoTransformer(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getContentWalletCardState(prevState: WalletCardState, visaCurrency: VisaCurrency): WalletCardState {
|
private fun getContentWalletCardState(prevState: WalletCardState, visaCurrency: VisaCurrency): WalletCardState {
|
||||||
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
|
|
||||||
|
|
||||||
return with(prevState) {
|
return with(prevState) {
|
||||||
WalletCardState.Content(
|
WalletCardState.Content(
|
||||||
id = id,
|
id = id,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.common.util.getCardsCount
|
||||||
import com.tangem.domain.models.StatusSource
|
import com.tangem.domain.models.StatusSource
|
||||||
import com.tangem.domain.tokens.model.TotalFiatBalance
|
import com.tangem.domain.tokens.model.TotalFiatBalance
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
|
|
@ -48,8 +47,6 @@ internal class MultiWalletCardStateConverter(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun WalletCardState.toWalletCardState(fiatBalance: TotalFiatBalance.Loaded): WalletCardState {
|
private fun WalletCardState.toWalletCardState(fiatBalance: TotalFiatBalance.Loaded): WalletCardState {
|
||||||
selectedWallet.requireColdWallet()
|
|
||||||
|
|
||||||
return WalletCardState.Content(
|
return WalletCardState.Content(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
|
|
@ -60,7 +57,10 @@ internal class MultiWalletCardStateConverter(
|
||||||
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||||
},
|
},
|
||||||
isZeroBalance = fiatBalance.amount.isZero(),
|
isZeroBalance = fiatBalance.amount.isZero(),
|
||||||
cardCount = selectedWallet.getCardsCount(),
|
cardCount = when (selectedWallet) {
|
||||||
|
is UserWallet.Cold -> selectedWallet.getCardsCount()
|
||||||
|
is UserWallet.Hot -> null
|
||||||
|
},
|
||||||
isBalanceFlickering = fiatBalance.source == StatusSource.CACHE,
|
isBalanceFlickering = fiatBalance.source == StatusSource.CACHE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.common.util.getCardsCount
|
||||||
import com.tangem.domain.models.StatusSource
|
import com.tangem.domain.models.StatusSource
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||||
|
|
@ -64,7 +63,10 @@ internal class SingleWalletCardStateConverter(
|
||||||
imageResId = imageResId,
|
imageResId = imageResId,
|
||||||
dropDownItems = dropDownItems,
|
dropDownItems = dropDownItems,
|
||||||
balance = formatFiatAmount(status = status, appCurrency = appCurrency),
|
balance = formatFiatAmount(status = status, appCurrency = appCurrency),
|
||||||
cardCount = selectedWallet.requireColdWallet().getCardsCount(), // TODO [REDACTED_TASK_KEY]
|
cardCount = when (selectedWallet) {
|
||||||
|
is UserWallet.Cold -> selectedWallet.getCardsCount()
|
||||||
|
is UserWallet.Hot -> null
|
||||||
|
},
|
||||||
isZeroBalance = status.fiatAmount?.isZero(),
|
isZeroBalance = status.fiatAmount?.isZero(),
|
||||||
isBalanceFlickering = (status as? CryptoCurrencyStatus.Loaded)?.sources?.total == StatusSource.CACHE,
|
isBalanceFlickering = (status as? CryptoCurrencyStatus.Loaded)?.sources?.total == StatusSource.CACHE,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,18 @@ import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||||
|
|
||||||
internal inline fun UserWallet.Cold.createStateByWalletType(
|
internal inline fun UserWallet.createStateByWalletType(
|
||||||
multiCurrencyCreator: () -> WalletState.MultiCurrency,
|
multiCurrencyCreator: () -> WalletState.MultiCurrency,
|
||||||
singleCurrencyCreator: () -> WalletState.SingleCurrency,
|
singleCurrencyCreator: () -> WalletState.SingleCurrency,
|
||||||
visaWalletCreator: () -> WalletState.Visa,
|
visaWalletCreator: () -> WalletState.Visa,
|
||||||
): WalletState = when {
|
): WalletState = when (this) {
|
||||||
|
is UserWallet.Cold -> when {
|
||||||
isVisaWallet() -> visaWalletCreator()
|
isVisaWallet() -> visaWalletCreator()
|
||||||
isWalletWithTokens() -> multiCurrencyCreator()
|
isWalletWithTokens() -> multiCurrencyCreator()
|
||||||
else -> singleCurrencyCreator()
|
else -> singleCurrencyCreator()
|
||||||
}
|
}
|
||||||
|
is UserWallet.Hot -> multiCurrencyCreator()
|
||||||
|
}
|
||||||
|
|
||||||
private fun UserWallet.Cold.isWalletWithTokens(): Boolean {
|
private fun UserWallet.Cold.isWalletWithTokens(): Boolean {
|
||||||
return isMultiCurrency || scanResponse.cardTypesResolver.isSingleWalletWithToken()
|
return isMultiCurrency || scanResponse.cardTypesResolver.isSingleWalletWithToken()
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal class SingleWalletWithTokenListSubscriber(
|
internal class SingleWalletWithTokenListSubscriber(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val tokenListStore: MultiWalletTokenListStore,
|
private val tokenListStore: MultiWalletTokenListStore,
|
||||||
stateHolder: WalletStateController,
|
stateHolder: WalletStateController,
|
||||||
clickIntents: WalletClickIntents,
|
clickIntents: WalletClickIntents,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.txhistory.models.TxHistoryStateError
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.collectLatest
|
import com.tangem.feature.wallet.presentation.wallet.domain.collectLatest
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||||
|
|
@ -32,7 +31,7 @@ typealias MaybeTxHistoryItems = Either<TxHistoryListError, Flow<PagingData<TxInf
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal class TxHistorySubscriber(
|
internal class TxHistorySubscriber(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val isRefresh: Boolean,
|
private val isRefresh: Boolean,
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
|
|
@ -97,7 +96,7 @@ internal class TxHistorySubscriber(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
ifRight = { itemsFlow ->
|
ifRight = { itemsFlow ->
|
||||||
val blockchain = userWallet.requireColdWallet().scanResponse.cardTypesResolver.getBlockchain()
|
val blockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain()
|
||||||
val itemConverter = TxHistoryItemStateConverter(
|
val itemConverter = TxHistoryItemStateConverter(
|
||||||
symbol = blockchain.currency,
|
symbol = blockchain.currency,
|
||||||
decimals = blockchain.decimals(),
|
decimals = blockchain.decimals(),
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.map
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class VisaWalletSubscriber(
|
internal class VisaWalletSubscriber(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet.Cold,
|
||||||
private val stateController: WalletStateController,
|
private val stateController: WalletStateController,
|
||||||
private val isRefresh: Boolean,
|
private val isRefresh: Boolean,
|
||||||
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import com.tangem.domain.tokens.model.TotalFiatBalance
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||||
import com.tangem.domain.wallets.models.requireColdWallet
|
|
||||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
|
|
@ -88,8 +87,7 @@ internal class DefaultUserWalletsFetcher @AssistedInject constructor(
|
||||||
private fun loadArtworks(wallets: List<UserWallet>): Flow<HashMap<UserWalletId, ArtworkModel>> {
|
private fun loadArtworks(wallets: List<UserWallet>): Flow<HashMap<UserWalletId, ArtworkModel>> {
|
||||||
return flow {
|
return flow {
|
||||||
emit(hashMapOf()) // emits right away so the transform doesn't wait for the images' loading to finish
|
emit(hashMapOf()) // emits right away so the transform doesn't wait for the images' loading to finish
|
||||||
wallets.forEach { wallet ->
|
wallets.filterIsInstance<UserWallet.Cold>().forEach { wallet ->
|
||||||
wallet.requireColdWallet()
|
|
||||||
val artwork = getCardImageUseCase(
|
val artwork = getCardImageUseCase(
|
||||||
cardId = wallet.cardId,
|
cardId = wallet.cardId,
|
||||||
manufacturerName = wallet.scanResponse.card.manufacturer.name,
|
manufacturerName = wallet.scanResponse.card.manufacturer.name,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue