Updated on 2026-08-14
This commit is contained in:
parent
23d73ac0fa
commit
9db902b25c
7 changed files with 20 additions and 372 deletions
|
|
@ -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<Wallet> = 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<WalletDataModel.AddressData> {
|
||||
val listOfAddressData = mutableListOf<WalletDataModel.AddressData>()
|
||||
private fun Wallet.createAddressesData(): List<WalletAddressData> {
|
||||
val listOfAddressData = mutableListOf<WalletAddressData>()
|
||||
// put a defaultAddress at the first place
|
||||
addresses.forEach {
|
||||
val addressData = WalletDataModel.AddressData(
|
||||
val addressData = WalletAddressData(
|
||||
it.value,
|
||||
it.type,
|
||||
getShareUri(it.value),
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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<AddressData>,
|
||||
)
|
||||
|
||||
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<PendingTransaction> = 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<PendingTransaction>,
|
||||
) : Status()
|
||||
|
||||
data class SameCurrencyTransactionInProgress(
|
||||
override val amount: BigDecimal,
|
||||
override val pendingTransactions: List<PendingTransaction>,
|
||||
) : 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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WalletDataModel>,
|
||||
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
|
||||
}
|
||||
|
|
@ -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<WalletDataModel> {
|
||||
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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue