diff --git a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt index ebf3739714..9f6ba786f0 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt @@ -10,7 +10,7 @@ import com.tangem.tap.common.TestActions import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder import com.tangem.tap.domain.TapError import com.tangem.tap.domain.getFirstToken -import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.domain.model.WalletAddressData import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.store @@ -58,7 +58,7 @@ suspend fun WalletManager.safeUpdate(isDemoCard: Boolean): Result = try } } -fun WalletManager.getTopUpUrl(): String? { +internal fun WalletManager.getTopUpUrl(): String? { val globalState = store.state.globalState val defaultAddress = wallet.address @@ -72,18 +72,18 @@ fun WalletManager.getTopUpUrl(): String? { ) } -fun WalletManager?.getAddressData(): WalletDataModel.AddressData? { +internal fun WalletManager?.getAddressData(): WalletAddressData? { val wallet = this?.wallet ?: return null val addressDataList = wallet.createAddressesData() return if (addressDataList.isEmpty()) null else addressDataList[0] } -fun Wallet.createAddressesData(): List { - val listOfAddressData = mutableListOf() +private fun Wallet.createAddressesData(): List { + val listOfAddressData = mutableListOf() // put a defaultAddress at the first place addresses.forEach { - val addressData = WalletDataModel.AddressData( + val addressData = WalletAddressData( it.value, it.type, getShareUri(it.value), diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt b/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt index 30f9136eed..5ff36d0606 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt @@ -3,7 +3,7 @@ package com.tangem.tap.common.redux import com.tangem.common.extensions.VoidCallback import com.tangem.core.navigation.StateDialog import com.tangem.tap.common.TestAction -import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.domain.model.WalletAddressData import com.tangem.tap.features.wallet.models.Currency import com.tangem.wallet.R @@ -20,7 +20,7 @@ sealed class AppDialog : StateDialog { internal data class AddressInfoDialog( val currency: Currency, - val addressData: WalletDataModel.AddressData, + val addressData: WalletAddressData, ) : AppDialog() data class TestActionsDialog( diff --git a/app/src/main/java/com/tangem/tap/common/ui/AddressInfoBottomSheetDialog.kt b/app/src/main/java/com/tangem/tap/common/ui/AddressInfoBottomSheetDialog.kt index 72264ab263..6a2a14d073 100644 --- a/app/src/main/java/com/tangem/tap/common/ui/AddressInfoBottomSheetDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/ui/AddressInfoBottomSheetDialog.kt @@ -9,7 +9,7 @@ import com.tangem.core.analytics.Analytics import com.tangem.tap.common.analytics.events.Token import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.AppDialog -import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.domain.model.WalletAddressData import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.DialogOnboardingAddressInfoBinding @@ -42,7 +42,7 @@ internal class AddressInfoBottomSheetDialog( showData(data = stateDialog.addressData) } - private fun showData(data: WalletDataModel.AddressData) = with(binding!!) { + private fun showData(data: WalletAddressData) = with(binding!!) { pseudoToolbar.imvClose.setOnClickListener { dismissWithAnimation = true cancel() diff --git a/app/src/main/java/com/tangem/tap/domain/model/WalletAddressData.kt b/app/src/main/java/com/tangem/tap/domain/model/WalletAddressData.kt new file mode 100644 index 0000000000..a24fe98346 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/model/WalletAddressData.kt @@ -0,0 +1,10 @@ +package com.tangem.tap.domain.model + +import com.tangem.blockchain.common.address.AddressType + +internal data class WalletAddressData( + val address: String, + val type: AddressType, + val shareUrl: String, + val exploreUrl: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/model/WalletDataModel.kt b/app/src/main/java/com/tangem/tap/domain/model/WalletDataModel.kt deleted file mode 100644 index fc0acca07c..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/model/WalletDataModel.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.tangem.tap.domain.model - -import com.tangem.blockchain.common.address.AddressType -import com.tangem.tap.domain.model.WalletDataModel.AddressData -import com.tangem.tap.domain.model.WalletDataModel.Status -import com.tangem.tap.features.wallet.models.Currency -import com.tangem.tap.features.wallet.models.PendingTransaction -import java.math.BigDecimal - -/** - * Contains info about wallet store currency - * @param currency Wallet's [Currency] - * @param status Wallet's [Status], represents current status of that currency - * @param walletAddresses List of wallet data [AddressData] - * @param existentialDeposit Amount that must be held on currency's balance, if balance is below that amount all - * founds will be destroyed. Null if currency don't have existential deposit - * @param fiatRate Wallet's fiat rate, used to calculate fiat balance. Null if not provided - * @param isCardSingleToken shows that [Currency] is a card token - * @param isCustom shows that currency is a custom - * */ -data class WalletDataModel( - val currency: Currency, - val status: Status, - // FIXME: Left only selected wallet address here and move list of wallet addresses to WalletStoreModel - val walletAddresses: WalletAddresses?, - val existentialDeposit: BigDecimal?, - val fiatRate: BigDecimal?, - val isCardSingleToken: Boolean, - val isCustom: Boolean, -) { - - data class WalletAddresses( - val selectedAddress: AddressData, - val list: List, - ) - - data class AddressData( - val address: String, - val type: AddressType, - val shareUrl: String, - val exploreUrl: String, - ) - - /** - * Represent current status of currency - * @property amount Currency amount - * @property pendingTransactions List of currency [PendingTransaction] sent in currency's blockchain - * @property errorMessage Status error message, null if not provided - * @property isErrorStatus true if current status is error status, false otherwise - * */ - sealed class Status { - open val amount: BigDecimal = BigDecimal.ZERO - open val pendingTransactions: List = emptyList() - open val errorMessage: String? = null - open val isErrorStatus: Boolean = false - } - - object Loading : Status() - - data class VerifiedOnline( - override val amount: BigDecimal, - ) : Status() - - data class TransactionInProgress( - override val amount: BigDecimal, - override val pendingTransactions: List, - ) : Status() - - data class SameCurrencyTransactionInProgress( - override val amount: BigDecimal, - override val pendingTransactions: List, - ) : Status() - - data class NoAccount( - val amountToCreateAccount: BigDecimal?, - ) : Status() - - data class Unreachable( - override val errorMessage: String?, - override val amount: BigDecimal = BigDecimal.ZERO, - ) : Status() { - override val isErrorStatus: Boolean = true - } - - object MissedDerivation : Status() { - override val isErrorStatus: Boolean = true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt b/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt deleted file mode 100644 index 99282954dc..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.tangem.tap.domain.model - -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.WalletManager -import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.common.BlockchainNetwork -import com.tangem.domain.wallets.models.UserWalletId -import com.tangem.tap.domain.model.WalletStoreModel.WalletRent -import com.tangem.tap.features.wallet.models.Currency -import java.math.BigDecimal - -// FIXME: Move list of wallet addresses from WalletDataModel to this class -/** - * Contains info about the blockchain and its currencies - * - * @param userWalletId ID of the associated [UserWallet] - * @param blockchain [Blockchain] of this WalletStore - * @param derivationPath [DerivationPath] of this store, null if the card does not support the - * [HD Wallet](https://coinsutra.com/hd-wallets-deterministic-wallet/) - * @param walletsData List of [WalletDataModel] which represents store's blockchain currency and tokens currencies - * @param walletRent [WalletRent], null if store has no rent or currency balance is greater then - * [WalletRent.exemptionAmount] - * @param blockchainNetwork [BlockchainNetwork]. - * TODO: Remove after WalletMiddleware refactoring - * @param walletManager [WalletManager], may be null if it fails to create this manager. - * TODO: Remove after WalletMiddleware refactoring - * - * @property blockchainWalletData Returns the [WalletDataModel] of the blockchain of this wallet store - * or throw [NoSuchElementException] if this wallet store not contains [WalletDataModel] of the blockchain - * */ -data class WalletStoreModel( - val userWalletId: UserWalletId, - val blockchain: Blockchain, - val derivationPath: DerivationPath?, - val walletsData: List, - val walletRent: WalletRent?, - @Deprecated("Don't use it, will be removed") - val blockchainNetwork: BlockchainNetwork, - @Deprecated("Don't use it, will be removed") - val walletManager: WalletManager?, -) { - - val blockchainWalletData: WalletDataModel - get() = walletsData.first { it.currency is Currency.Blockchain } - - /** - * Represents wallet blockchain rent - * @param rent Amount that will be charged in overtime if the blockchain does not have an amount greater than - * the [WalletRent.exemptionAmount] - * @param exemptionAmount Amount that should be on the blockchain balance not to pay rent - * */ - data class WalletRent( - val rent: BigDecimal, - val exemptionAmount: BigDecimal, - ) - - // TODO: Remove the generated methods after blockchainNetwork and walletManager are removed from the model - // region Generated - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is WalletStoreModel) return false - - if (userWalletId != other.userWalletId) return false - if (blockchain != other.blockchain) return false - if (derivationPath != other.derivationPath) return false - if (walletsData != other.walletsData) return false - if (walletRent != other.walletRent) return false - - return true - } - - override fun hashCode(): Int { - var result = userWalletId.hashCode() - result = 31 * result + blockchain.hashCode() - result = 31 * result + (derivationPath?.hashCode() ?: 0) - result = 31 * result + walletsData.hashCode() - result = 31 * result + (walletRent?.hashCode() ?: 0) - return result - } - - override fun toString(): String { - return "WalletStoreModel(userWalletId=$userWalletId, blockchain=$blockchain, derivationPath=$derivationPath, " + - "walletsData=$walletsData, walletRent=$walletRent)" - } - // endregion Generated -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt b/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt deleted file mode 100644 index 9dfe9c24a9..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt +++ /dev/null @@ -1,188 +0,0 @@ -package com.tangem.tap.domain.model.builders - -import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.blockchain.common.Wallet -import com.tangem.blockchain.common.WalletManager -import com.tangem.blockchain.common.derivation.DerivationStyle -import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.domain.common.BlockchainNetwork -import com.tangem.domain.common.util.cardTypesResolver -import com.tangem.domain.common.util.derivationStyleProvider -import com.tangem.domain.wallets.models.UserWallet -import com.tangem.tap.common.extensions.createAddressesData -import com.tangem.tap.domain.model.WalletDataModel -import com.tangem.tap.domain.model.WalletStoreModel -import com.tangem.tap.features.wallet.models.Currency -import java.math.BigDecimal - -interface WalletStoreBuilder { - fun build(): WalletStoreModel - - interface BlockchainNetworkWalletStoreBuilder : WalletStoreBuilder { - fun walletManager(walletManager: WalletManager?): WalletStoreBuilder - } - - interface WalletMangerWalletStoreBuilder : 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 - } - - override fun build(): WalletStoreModel { - val cardDerivationStyle = userWallet.scanResponse.derivationStyleProvider.getDerivationStyle() - val blockchainWalletData = blockchainNetwork.getBlockchainWalletData(walletManager, cardDerivationStyle) - val tokensWalletsData = blockchainNetwork.getTokensWalletsData( - walletManager = walletManager, - cardDerivationStyle = cardDerivationStyle, - primaryToken = userWallet.scanResponse.cardTypesResolver.getPrimaryToken(), - ) - - return WalletStoreModel( - userWalletId = userWallet.walletId, - blockchain = blockchainNetwork.blockchain, - derivationPath = blockchainNetwork.derivationPath?.let { DerivationPath(it) }, - walletsData = listOf(blockchainWalletData) + tokensWalletsData, - walletRent = null, - walletManager = walletManager, - blockchainNetwork = blockchainNetwork, - ) - } -} - -private class WalletMangerWalletStoreBuilderImpl( - private val userWallet: UserWallet, - private val walletManager: WalletManager, -) : WalletStoreBuilder.WalletMangerWalletStoreBuilder { - - override fun build(): WalletStoreModel { - val wallet = walletManager.wallet - val blockchainWalletData = wallet.blockchain.toBlockchainWalletData(walletManager) - val tokenWalletsData = wallet.getTokens().firstOrNull()?.toTokenWalletData( - walletManager = walletManager, - primaryToken = userWallet.scanResponse.cardTypesResolver.getPrimaryToken(), - ) - - return WalletStoreModel( - userWalletId = userWallet.walletId, - blockchain = wallet.blockchain, - derivationPath = wallet.publicKey.derivationPath, - walletsData = listOf(blockchainWalletData) + listOfNotNull(tokenWalletsData), - walletRent = null, - walletManager = walletManager, - blockchainNetwork = BlockchainNetwork.fromWalletManager(walletManager), - ) - } -} - -private fun BlockchainNetwork.getBlockchainWalletData( - walletManager: WalletManager?, - cardDerivationStyle: DerivationStyle?, -): WalletDataModel { - val currency = Currency.Blockchain( - blockchain = blockchain, - derivationPath = derivationPath, - ) - return WalletDataModel( - currency = currency, - status = WalletDataModel.Loading, - walletAddresses = walletManager?.wallet?.getWalletAddresses(), - existentialDeposit = getExistentialDeposit(walletManager), - fiatRate = null, - isCardSingleToken = false, - isCustom = currency.isCustomCurrency(cardDerivationStyle), - ) -} - -private fun BlockchainNetwork.getTokensWalletsData( - walletManager: WalletManager?, - cardDerivationStyle: DerivationStyle?, - primaryToken: Token?, -): List { - return this.tokens - .map { token -> - val currency = Currency.Token( - token = token, - blockchain = blockchain, - derivationPath = derivationPath, - ) - WalletDataModel( - currency = currency, - status = WalletDataModel.Loading, - walletAddresses = walletManager?.wallet?.getWalletAddresses(), - existentialDeposit = getExistentialDeposit(walletManager), - fiatRate = null, - isCardSingleToken = token == primaryToken, - isCustom = currency.isCustomCurrency(cardDerivationStyle), - ) - } -} - -private fun Blockchain.toBlockchainWalletData(walletManager: WalletManager): WalletDataModel { - val wallet = walletManager.wallet - return WalletDataModel( - currency = Currency.Blockchain( - blockchain = this, - derivationPath = wallet.publicKey.derivationPath?.rawPath, - ), - status = WalletDataModel.Loading, - walletAddresses = wallet.getWalletAddresses(), - existentialDeposit = getExistentialDeposit(walletManager), - fiatRate = null, - isCardSingleToken = false, - isCustom = false, - ) -} - -private fun Token.toTokenWalletData(walletManager: WalletManager, primaryToken: Token?): WalletDataModel { - val wallet = walletManager.wallet - return WalletDataModel( - currency = Currency.Token( - token = this, - blockchain = wallet.blockchain, - derivationPath = wallet.publicKey.derivationPath?.rawPath, - ), - status = WalletDataModel.Loading, - walletAddresses = wallet.getWalletAddresses(), - existentialDeposit = getExistentialDeposit(walletManager), - fiatRate = null, - isCardSingleToken = this == primaryToken, - isCustom = false, - ) -} - -private fun getExistentialDeposit(walletManager: WalletManager?): BigDecimal? { - return (walletManager as? ExistentialDepositProvider)?.getExistentialDeposit() -} - -private fun Wallet.getWalletAddresses(): WalletDataModel.WalletAddresses? { - return this.createAddressesData() - .takeIf { it.isNotEmpty() } - ?.let { addresses -> - WalletDataModel.WalletAddresses( - list = addresses, - selectedAddress = addresses.first(), - ) - } -} \ No newline at end of file