Updated on 2026-08-14

This commit is contained in:
Tangem 2022-12-07 16:45:43 +03:00
parent 3d8aba391f
commit 922b302cb1
14 changed files with 159 additions and 55 deletions

View file

@ -10,8 +10,8 @@ import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.Address
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.util.userWalletId
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.domain.extensions.getUserWalletId
class AdditionalFeedbackInfo {
class EmailWalletInfo(
@ -54,7 +54,7 @@ class AdditionalFeedbackInfo {
cardFirmwareVersion = data.card.firmwareVersion.stringValue
cardIssuer = data.card.issuer.name
signedHashesCount = formatSignedHashes(data.card.wallets)
userWalletId = data.card.getUserWalletId()
userWalletId = data.card.userWalletId.stringValue
}
fun setWalletsInfo(walletManagers: List<WalletManager>) {

View file

@ -11,15 +11,15 @@ sealed class TotalFiatBalance {
object Loading : TotalFiatBalance()
class Refreshing(
data class Refreshing(
override val amount: BigDecimal,
) : TotalFiatBalance()
class Error(
data class Error(
override val amount: BigDecimal,
) : TotalFiatBalance()
class Loaded(
data class Loaded(
override val amount: BigDecimal,
) : TotalFiatBalance()
}

View file

@ -10,7 +10,7 @@ class UserWalletBuilder(
) {
private var backupCardsIds: Set<String> = emptySet()
fun setBackupCardsIds(backupCardsIds: Set<String>?) = this.apply {
fun backupCardsIds(backupCardsIds: Set<String>?) = this.apply {
if (backupCardsIds != null) {
this.backupCardsIds = backupCardsIds
}

View file

@ -10,25 +10,70 @@ import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.reducers.createAddressesData
import java.math.BigDecimal
class WalletStoreBuilder(
private val userWallet: UserWallet,
) {
private var walletManager: WalletManager? = null
private var blockchainNetwork: BlockchainNetwork? = null
interface WalletStoreBuilder {
fun build(): WalletStoreModel
fun setWalletManager(walletManager: WalletManager?) = this.apply {
interface BlockchainNetworkWalletStoreBuilder : WalletStoreBuilder {
fun walletManager(walletManager: WalletManager?): WalletStoreBuilder
}
interface WalletMangerWalletStoreBuilder : WalletStoreBuilder {
fun blockchainNetwork(blockchainNetwork: BlockchainNetwork?): WalletStoreBuilder
}
companion object {
operator fun invoke(
userWallet: UserWallet,
blockchainNetwork: BlockchainNetwork,
): BlockchainNetworkWalletStoreBuilder {
return BlockchainNetworkWalletStoreBuilderImpl(userWallet, blockchainNetwork)
}
operator fun invoke(
userWallet: UserWallet,
walletManager: WalletManager,
): WalletMangerWalletStoreBuilder {
return WalletMangerWalletStoreBuilderImpl(userWallet, walletManager)
}
}
}
private class BlockchainNetworkWalletStoreBuilderImpl(
private val userWallet: UserWallet,
private val blockchainNetwork: BlockchainNetwork,
) : WalletStoreBuilder.BlockchainNetworkWalletStoreBuilder {
private var walletManager: WalletManager? = null
override fun walletManager(walletManager: WalletManager?) = this.apply {
this.walletManager = walletManager
}
fun setBlockchainNetwork(blockchainNetwork: BlockchainNetwork?) = this.apply {
override fun build(): WalletStoreModel {
val blockchainWalletData = blockchainNetwork.getBlockchainWalletData(walletManager)
val tokensWalletsData = blockchainNetwork.getTokensWalletsData(walletManager)
return WalletStoreModel(
userWalletId = userWallet.walletId,
blockchainNetwork = blockchainNetwork,
walletManager = walletManager,
walletsData = (listOf(blockchainWalletData) + tokensWalletsData),
walletRent = null,
)
}
}
private class WalletMangerWalletStoreBuilderImpl(
private val userWallet: UserWallet,
private val walletManager: WalletManager,
) : WalletStoreBuilder.WalletMangerWalletStoreBuilder {
private var blockchainNetwork: BlockchainNetwork? = null
override fun blockchainNetwork(blockchainNetwork: BlockchainNetwork?) = this.apply {
this.blockchainNetwork = blockchainNetwork
}
fun build(): WalletStoreModel {
val blockchainNetwork = this.blockchainNetwork
?: walletManager?.let(BlockchainNetwork::fromWalletManager)
?: error("Blockchain network and wallet manager must not be null")
override fun build(): WalletStoreModel {
val blockchainNetwork = this.blockchainNetwork ?: BlockchainNetwork.fromWalletManager(walletManager)
val blockchainWalletData = blockchainNetwork.getBlockchainWalletData(walletManager)
val tokensWalletsData = blockchainNetwork.getTokensWalletsData(walletManager)

View file

@ -187,9 +187,8 @@ internal class DefaultWalletCurrenciesManager(
.flatMap { walletManager ->
walletStoresRepository.storeOrUpdate(
userWalletId = userWalletId,
walletStore = WalletStoreBuilder(userWallet)
.setWalletManager(walletManager)
.setBlockchainNetwork(blockchainNetwork)
walletStore = WalletStoreBuilder(userWallet, walletManager)
.blockchainNetwork(blockchainNetwork)
.build(),
)
}

View file

@ -122,9 +122,8 @@ internal class DefaultWalletStoresManager(
{ walletManager ->
walletStoresRepository.storeOrUpdate(
userWalletId = userWalletId,
walletStore = WalletStoreBuilder(userWallet)
.setWalletManager(walletManager)
.setBlockchainNetwork(blockchainNetwork)
walletStore = WalletStoreBuilder(userWallet, blockchainNetwork)
.walletManager(walletManager)
.build(),
)
}
@ -161,8 +160,7 @@ internal class DefaultWalletStoresManager(
.flatMap { walletManager ->
walletStoresRepository.storeOrUpdate(
userWalletId = userWallet.walletId,
walletStore = WalletStoreBuilder(userWallet)
.setWalletManager(walletManager)
walletStore = WalletStoreBuilder(userWallet, walletManager)
.build(),
)
}

View file

@ -9,7 +9,6 @@ import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
@ -67,7 +66,7 @@ internal class SaveWalletMiddleware {
scope.launch {
val userWallet = UserWalletBuilder(scanResponse)
.setBackupCardsIds(backupCardsIds = state.backupInfo?.backupCardsIds)
.backupCardsIds(state.backupInfo?.backupCardsIds)
.build()
saveAccessCodeIfNeeded(state.backupInfo?.accessCode, userWallet.cardsInWallet)

View file

@ -11,12 +11,12 @@ data class UserWalletModel(
) {
sealed interface Type {
data class SingleCurrency(
val blockchainName: String?,
val blockchainName: String? = null,
) : Type
data class MultiCurrency(
val tokensCount: Int,
val cardsInWallet: Int,
val tokensCount: Int = 0,
) : Type
}
}

View file

@ -6,7 +6,6 @@ import com.tangem.common.flatMap
import com.tangem.common.map
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.util.UserWalletId
import com.tangem.tap.*
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
@ -16,6 +15,12 @@ import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.totalFiatBalanceCalculator
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.walletStoresManager
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
@ -86,26 +91,7 @@ internal class WalletSelectorMiddleware {
scope.launch {
val updatedWallet = state.wallets
.find { it.id == walletId.stringValue }
?.let { wallet ->
wallet.copy(
type = when (val type = wallet.type) {
is UserWalletModel.Type.MultiCurrency -> type.copy(
tokensCount = walletStores.flatMap { it.walletsData }.size,
)
is UserWalletModel.Type.SingleCurrency -> type.copy(
blockchainName = walletStores
.firstOrNull()
?.blockchainNetwork
?.blockchain
?.fullName,
)
},
fiatBalance = totalFiatBalanceCalculator.calculate(
prevAmount = wallet.fiatBalance.amount,
walletStores = walletStores,
),
)
}
?.updateWalletStoresAndCalculateFiatBalance(walletStores)
if (updatedWallet != null) {
store.dispatchOnMain(WalletSelectorAction.BalanceLoaded(updatedWallet))
@ -138,6 +124,7 @@ internal class WalletSelectorMiddleware {
val selectedWallet = userWalletsListManager.selectedUserWallet.first()
val isSavedWalletSelected = userWallet == selectedWallet
store.dispatchOnMain(WalletSelectorAction.AddWallet.Success)
if (isSavedWalletSelected) {
store.dispatchOnMain(NavigationAction.PopBackTo())
store.onUserWalletSelected(selectedWallet)
@ -209,4 +196,27 @@ internal class WalletSelectorMiddleware {
},
)
}
private suspend fun UserWalletModel.updateWalletStoresAndCalculateFiatBalance(
walletStores: List<WalletStoreModel>,
): UserWalletModel {
return this.copy(
type = when (type) {
is UserWalletModel.Type.MultiCurrency -> type.copy(
tokensCount = walletStores.flatMap { it.walletsData }.size,
)
is UserWalletModel.Type.SingleCurrency -> type.copy(
blockchainName = walletStores
.firstOrNull()
?.blockchainNetwork
?.blockchain
?.fullName,
)
},
fiatBalance = totalFiatBalanceCalculator.calculate(
prevAmount = fiatBalance.amount,
walletStores = walletStores,
),
)
}
}

View file

@ -93,15 +93,12 @@ internal object WalletSelectorReducer {
private fun UserWallet.getType(): UserWalletModel.Type {
return if (scanResponse.card.isMultiwalletAllowed) {
UserWalletModel.Type.MultiCurrency(
tokensCount = 0,
cardsInWallet = (scanResponse.card.backupStatus as? CardDTO.BackupStatus.Active)
?.cardCount?.inc()
?: 1,
)
} else {
UserWalletModel.Type.SingleCurrency(
blockchainName = null,
)
UserWalletModel.Type.SingleCurrency()
}
}
}

View file

@ -21,6 +21,20 @@ android {
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = false
}
buildTypes {
create("debug_beta") {
initWith(getByName("release"))
BuildConfigFieldFactory(
fields = listOf(
Field.Environment("release"),
Field.TestActionEnabled(true),
Field.LogEnabled(true),
),
builder = ::buildConfigField,
).create()
}
}
}
dependencies {

View file

@ -27,6 +27,20 @@ android {
composeOptions {
kotlinCompilerExtensionVersion = Versions.compose
}
buildTypes {
create("debug_beta") {
initWith(getByName("release"))
BuildConfigFieldFactory(
fields = listOf(
Field.Environment("release"),
Field.TestActionEnabled(true),
Field.LogEnabled(true),
),
builder = ::buildConfigField,
).create()
}
}
}
dependencies {

View file

@ -22,6 +22,20 @@ android {
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = false
}
buildTypes {
create("debug_beta") {
initWith(getByName("release"))
BuildConfigFieldFactory(
fields = listOf(
Field.Environment("release"),
Field.TestActionEnabled(true),
Field.LogEnabled(true),
),
builder = ::buildConfigField,
).create()
}
}
}
dependencies {

View file

@ -30,6 +30,20 @@ android {
composeOptions {
kotlinCompilerExtensionVersion = Versions.compose
}
buildTypes {
create("debug_beta") {
initWith(getByName("release"))
BuildConfigFieldFactory(
fields = listOf(
Field.Environment("release"),
Field.TestActionEnabled(true),
Field.LogEnabled(true),
),
builder = ::buildConfigField,
).create()
}
}
}
dependencies {