Updated on 2026-08-14
This commit is contained in:
parent
1fb40cdf6e
commit
210889da9b
22 changed files with 240 additions and 153 deletions
|
|
@ -14,6 +14,7 @@ import com.tangem.domain.common.extensions.toNetworkId
|
|||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
import com.tangem.feature.swap.presentation.SwapFragment
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
|
|
@ -123,7 +124,10 @@ class TradeCryptoMiddleware {
|
|||
}
|
||||
|
||||
private fun proceedNewBuyAction(state: () -> AppState?, action: TradeCryptoAction.New.Buy) {
|
||||
val networkAddress = action.cryptoCurrencyStatus.value.networkAddress?.defaultAddress ?: return
|
||||
val networkAddress = action.cryptoCurrencyStatus.value.networkAddress
|
||||
?.defaultAddress
|
||||
?.let(NetworkAddress.Address::value)
|
||||
?: return
|
||||
|
||||
val status = action.cryptoCurrencyStatus
|
||||
val currency = status.currency
|
||||
|
|
@ -206,7 +210,10 @@ class TradeCryptoMiddleware {
|
|||
}
|
||||
|
||||
private fun proceedNewSellAction(action: TradeCryptoAction.New.Sell) {
|
||||
val networkAddress = action.cryptoCurrencyStatus.value.networkAddress?.defaultAddress ?: return
|
||||
val networkAddress = action.cryptoCurrencyStatus.value.networkAddress
|
||||
?.defaultAddress
|
||||
?.let(NetworkAddress.Address::value)
|
||||
?: return
|
||||
val currency = action.cryptoCurrencyStatus.currency
|
||||
|
||||
store.state.globalState.exchangeManager.getUrl(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.components.SimpleSettingsRow
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
|
|
@ -24,7 +25,7 @@ private fun ChooseAddressBottomSheetContent(content: ChooseAddressBottomSheetCon
|
|||
) {
|
||||
content.addressModels.forEach { addressModel ->
|
||||
SimpleSettingsRow(
|
||||
title = addressModel.type.name,
|
||||
title = addressModel.displayName.resolveReference(),
|
||||
icon = R.drawable.ic_arrow_top_right_24,
|
||||
onItemsClick = { content.onClick(addressModel) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
|
||||
private const val DSC_ADDRESS_NAME = "DSC"
|
||||
private const val DEL_ADDRESS_NAME = "Main"
|
||||
|
||||
private const val LEGACY_ADDRESS_NAME = "Legacy"
|
||||
private const val DEFAULT_ADDRESS_NAME = "Default"
|
||||
|
||||
fun Set<NetworkAddress.Address>.mapToAddressModels(currency: CryptoCurrency): List<AddressModel> = this
|
||||
.sortedBy { it.type.ordinal }
|
||||
.map { address ->
|
||||
AddressModel(
|
||||
displayName = currency.network.getAddressDisplayName(address.type),
|
||||
value = address.value,
|
||||
type = when (address.type) {
|
||||
NetworkAddress.Address.Type.Primary -> AddressModel.Type.Default
|
||||
NetworkAddress.Address.Type.Secondary -> AddressModel.Type.Legacy
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun Network.getAddressDisplayName(addressType: NetworkAddress.Address.Type): TextReference {
|
||||
return when (id.value) {
|
||||
"decimal", "decimal/test" -> {
|
||||
when (addressType) {
|
||||
NetworkAddress.Address.Type.Primary -> stringReference(value = DEL_ADDRESS_NAME)
|
||||
NetworkAddress.Address.Type.Secondary -> stringReference(value = DSC_ADDRESS_NAME)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
when (addressType) {
|
||||
NetworkAddress.Address.Type.Primary -> stringReference(value = DEFAULT_ADDRESS_NAME)
|
||||
NetworkAddress.Address.Type.Secondary -> stringReference(value = LEGACY_ADDRESS_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
data class AddressModel(
|
||||
val displayName: TextReference,
|
||||
val value: String,
|
||||
val type: Type = Type.Default,
|
||||
val type: Type,
|
||||
) {
|
||||
enum class Type {
|
||||
Legacy, Default
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -26,6 +26,7 @@ import com.tangem.core.ui.components.SecondaryButtonIconStart
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.rememberQrPainters
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.shareText
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
|
|
@ -181,13 +182,6 @@ private fun getName(content: TokenReceiveBottomSheetConfig, index: Int): String
|
|||
return if (content.addresses.size < 2) {
|
||||
content.name
|
||||
} else {
|
||||
"${
|
||||
stringResource(
|
||||
id = when (content.addresses[index].type) {
|
||||
AddressModel.Type.Default -> R.string.address_type_default
|
||||
AddressModel.Type.Legacy -> R.string.address_type_legacy
|
||||
},
|
||||
)
|
||||
} ${content.name}"
|
||||
"${content.addresses[index].displayName.resolveReference()} ${content.name}"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
class TokenReceiveBottomSheetConfig(
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val network: String,
|
||||
val addresses: List<AddressModel>,
|
||||
val addresses: ImmutableList<AddressModel>,
|
||||
val onCopyClick: () -> Unit,
|
||||
val onShareClick: () -> Unit,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -28,7 +28,6 @@ fun getActiveIconRes(blockchainId: String): Int {
|
|||
"GNO" -> R.drawable.img_gnosis_22
|
||||
"ETH-Pow", "ETH-Pow/test" -> R.drawable.img_eth_pow_22
|
||||
"ETH-Fair" -> R.drawable.img_eth_fair_22
|
||||
"NEAR", "NEAR/test" -> R.drawable.img_near_22
|
||||
"Polkadot", "Polkadot/test" -> R.drawable.img_polkadot_22
|
||||
"Kusama" -> R.drawable.img_kusama_22
|
||||
"OPTIMISM", "OPTIMISM/test" -> R.drawable.img_optimism_22
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.tokens.utils
|
|||
|
||||
import com.tangem.domain.tokens.model.*
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.walletmanager.model.Address
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction
|
||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
||||
|
|
@ -20,12 +21,12 @@ internal class NetworkStatusFactory {
|
|||
is UpdateWalletManagerResult.MissedDerivation -> NetworkStatus.MissedDerivation
|
||||
is UpdateWalletManagerResult.Unreachable -> NetworkStatus.Unreachable
|
||||
is UpdateWalletManagerResult.NoAccount -> NetworkStatus.NoAccount(
|
||||
address = getNetworkAddress(result.defaultAddress, result.addresses),
|
||||
address = getNetworkAddress(result.selectedAddress, result.addresses),
|
||||
amountToCreateAccount = result.amountToCreateAccount,
|
||||
errorMessage = result.errorMessage,
|
||||
)
|
||||
is UpdateWalletManagerResult.Verified -> NetworkStatus.Verified(
|
||||
address = getNetworkAddress(result.defaultAddress, result.addresses),
|
||||
address = getNetworkAddress(result.selectedAddress, result.addresses),
|
||||
amounts = formatAmounts(result.currenciesAmounts, currencies),
|
||||
pendingTransactions = formatTransactions(
|
||||
transactions = result.currentTransactions,
|
||||
|
|
@ -92,11 +93,26 @@ internal class NetworkStatusFactory {
|
|||
return transactions.mapTo(hashSetOf()) { it.txHistoryItem }
|
||||
}
|
||||
|
||||
private fun getNetworkAddress(defaultAddress: String, availableAddresses: Set<String>): NetworkAddress {
|
||||
private fun getNetworkAddress(selectedAddress: String, availableAddresses: Set<Address>): NetworkAddress {
|
||||
val defaultAddress = availableAddresses
|
||||
.firstOrNull { it.value == selectedAddress }
|
||||
?.let(::mapToDomainAddress)
|
||||
|
||||
requireNotNull(defaultAddress) { "Selected address must not be null" }
|
||||
|
||||
return if (availableAddresses.size != 1) {
|
||||
NetworkAddress.Selectable(defaultAddress, availableAddresses)
|
||||
NetworkAddress.Selectable(defaultAddress, availableAddresses.mapTo(hashSetOf(), ::mapToDomainAddress))
|
||||
} else {
|
||||
NetworkAddress.Single(defaultAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapToDomainAddress(address: Address): NetworkAddress.Address {
|
||||
val type = when (address.type) {
|
||||
Address.Type.Primary -> NetworkAddress.Address.Type.Primary
|
||||
Address.Type.Secondary -> NetworkAddress.Address.Type.Secondary
|
||||
}
|
||||
|
||||
return NetworkAddress.Address(address.value, type)
|
||||
}
|
||||
}
|
||||
|
|
@ -195,8 +195,7 @@ fun Blockchain.toCoinId(): String {
|
|||
Blockchain.Chia, Blockchain.ChiaTestnet -> "chia"
|
||||
Blockchain.Near -> "near"
|
||||
Blockchain.NearTestnet -> "near/test"
|
||||
Blockchain.Decimal -> "decimal"
|
||||
Blockchain.DecimalTestnet -> "decimal/test"
|
||||
Blockchain.Decimal, Blockchain.DecimalTestnet -> "decimal"
|
||||
Blockchain.Unknown -> "unknown"
|
||||
}
|
||||
}
|
||||
|
|
@ -224,6 +223,4 @@ private const val NODL_AMOUNT_TO_CREATE_ACCOUNT = 1.5
|
|||
private val excludedBlockchains = listOf(
|
||||
Blockchain.Unknown,
|
||||
Blockchain.Ducatus,
|
||||
Blockchain.Decimal,
|
||||
Blockchain.DecimalTestnet,
|
||||
)
|
||||
|
|
@ -115,6 +115,7 @@ interface WalletManagersFacade {
|
|||
* @param userWalletId selected wallet id
|
||||
* @param network network of currency
|
||||
*/
|
||||
@Deprecated("Use NetworkAddress from CryptoCurrencyStatus")
|
||||
suspend fun getAddress(userWalletId: UserWalletId, network: Network): List<Address>
|
||||
|
||||
/** Returns list of all addresses for all currencies in selected wallet
|
||||
|
|
@ -122,6 +123,7 @@ interface WalletManagersFacade {
|
|||
* @param userWalletId selected wallet id
|
||||
* @param network required to create wallet manager
|
||||
*/
|
||||
@Deprecated("Use NetworkAddress from CryptoCurrencyStatus")
|
||||
suspend fun getAddresses(userWalletId: UserWalletId, network: Network): Set<Address>
|
||||
|
||||
/**
|
||||
|
|
@ -155,6 +157,7 @@ interface WalletManagersFacade {
|
|||
* @param userWalletId selected wallet id
|
||||
* @param network network of currency
|
||||
*/
|
||||
@Deprecated("Will be removed in future")
|
||||
suspend fun getFee(
|
||||
amount: Amount,
|
||||
destination: String,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.walletmanager.model
|
||||
|
||||
data class Address(
|
||||
val value: String,
|
||||
val type: Type,
|
||||
) {
|
||||
|
||||
enum class Type {
|
||||
Primary, Secondary,
|
||||
}
|
||||
}
|
||||
|
|
@ -9,15 +9,15 @@ sealed class UpdateWalletManagerResult {
|
|||
object Unreachable : UpdateWalletManagerResult()
|
||||
|
||||
data class Verified(
|
||||
val defaultAddress: String,
|
||||
val addresses: Set<String>,
|
||||
val selectedAddress: String,
|
||||
val addresses: Set<Address>,
|
||||
val currenciesAmounts: Set<CryptoCurrencyAmount>,
|
||||
val currentTransactions: Set<CryptoCurrencyTransaction>,
|
||||
) : UpdateWalletManagerResult()
|
||||
|
||||
data class NoAccount(
|
||||
val defaultAddress: String,
|
||||
val addresses: Set<String>,
|
||||
val selectedAddress: String,
|
||||
val addresses: Set<Address>,
|
||||
val amountToCreateAccount: BigDecimal,
|
||||
val errorMessage: String,
|
||||
) : UpdateWalletManagerResult()
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
package com.tangem.domain.walletmanager.utils
|
||||
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.domain.common.extensions.amountToCreateAccount
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.walletmanager.model.Address
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction
|
||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.tangem.blockchain.common.address.Address as SdkAddress
|
||||
|
||||
internal class UpdateWalletManagerResultFactory {
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
val addresses = getAvailableAddresses(wallet.addresses)
|
||||
|
||||
return UpdateWalletManagerResult.Verified(
|
||||
defaultAddress = wallet.address,
|
||||
selectedAddress = wallet.address,
|
||||
addresses = addresses,
|
||||
currenciesAmounts = getTokensAmounts(wallet.amounts.values.toSet()),
|
||||
currentTransactions = getCurrentTransactions(addresses, wallet.recentTransactions.toSet()),
|
||||
|
|
@ -30,7 +32,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
val addresses = getAvailableAddresses(wallet.addresses)
|
||||
|
||||
return UpdateWalletManagerResult.Verified(
|
||||
defaultAddress = wallet.address,
|
||||
selectedAddress = wallet.address,
|
||||
addresses = addresses,
|
||||
currenciesAmounts = getDemoTokensAmounts(demoAmount, walletManager.cardTokens),
|
||||
currentTransactions = getCurrentTransactions(addresses, wallet.recentTransactions.toSet()),
|
||||
|
|
@ -48,7 +50,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
UpdateWalletManagerResult.Unreachable
|
||||
} else {
|
||||
UpdateWalletManagerResult.NoAccount(
|
||||
defaultAddress = wallet.address,
|
||||
selectedAddress = wallet.address,
|
||||
addresses = getAvailableAddresses(wallet.addresses),
|
||||
amountToCreateAccount = amountToCreateAccount,
|
||||
errorMessage = customMessage,
|
||||
|
|
@ -70,7 +72,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
}
|
||||
|
||||
private fun getCurrentTransactions(
|
||||
walletAddresses: Set<String>,
|
||||
walletAddresses: Set<Address>,
|
||||
recentTransactions: Set<TransactionData>,
|
||||
): Set<CryptoCurrencyTransaction> {
|
||||
val unconfirmedTransactions = recentTransactions.filter {
|
||||
|
|
@ -95,7 +97,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
}
|
||||
|
||||
private fun createCurrencyTransaction(
|
||||
walletAddresses: Set<String>,
|
||||
walletAddresses: Set<Address>,
|
||||
data: TransactionData,
|
||||
): CryptoCurrencyTransaction? {
|
||||
return when (val type = data.amount.type) {
|
||||
|
|
@ -115,11 +117,11 @@ internal class UpdateWalletManagerResultFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createTxHistoryItem(walletAddresses: Set<String>, data: TransactionData): TxHistoryItem? {
|
||||
private fun createTxHistoryItem(walletAddresses: Set<Address>, data: TransactionData): TxHistoryItem? {
|
||||
val hash = data.hash ?: return null
|
||||
val millis = data.date?.timeInMillis ?: return null
|
||||
val amount = getTransactionAmountValue(data.amount) ?: return null
|
||||
val isOutgoing = data.sourceAddress in walletAddresses
|
||||
val isOutgoing = data.sourceAddress in walletAddresses.map { it.value }
|
||||
|
||||
return TxHistoryItem(
|
||||
txHash = hash,
|
||||
|
|
@ -141,8 +143,16 @@ internal class UpdateWalletManagerResultFactory {
|
|||
)
|
||||
}
|
||||
|
||||
private fun getAvailableAddresses(addresses: Set<Address>): Set<String> {
|
||||
return addresses.mapTo(hashSetOf()) { it.value }
|
||||
private fun getAvailableAddresses(addresses: Set<SdkAddress>): Set<Address> {
|
||||
return addresses.mapTo(hashSetOf()) { sdkAddress ->
|
||||
Address(
|
||||
value = sdkAddress.value,
|
||||
type = when (sdkAddress.type) {
|
||||
AddressType.Default -> Address.Type.Primary
|
||||
AddressType.Legacy -> Address.Type.Secondary
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCurrencyAmountValue(amount: Amount): BigDecimal? {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ data class CryptoCurrencyStatus(
|
|||
override val fiatAmount: BigDecimal?,
|
||||
override val priceChange: BigDecimal?,
|
||||
override val fiatRate: BigDecimal?,
|
||||
override val networkAddress: NetworkAddress?,
|
||||
override val networkAddress: NetworkAddress,
|
||||
) : Status(isError = false) {
|
||||
|
||||
override val amount: BigDecimal = BigDecimal.ZERO
|
||||
|
|
@ -102,7 +102,7 @@ data class CryptoCurrencyStatus(
|
|||
override val priceChange: BigDecimal,
|
||||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress?,
|
||||
override val networkAddress: NetworkAddress,
|
||||
) : Status(isError = false)
|
||||
|
||||
/**
|
||||
|
|
@ -123,7 +123,7 @@ data class CryptoCurrencyStatus(
|
|||
override val priceChange: BigDecimal?,
|
||||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress?,
|
||||
override val networkAddress: NetworkAddress,
|
||||
) : Status(isError = false)
|
||||
|
||||
/**
|
||||
|
|
@ -138,6 +138,6 @@ data class CryptoCurrencyStatus(
|
|||
override val amount: BigDecimal,
|
||||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress?,
|
||||
override val networkAddress: NetworkAddress,
|
||||
) : Status(isError = false)
|
||||
}
|
||||
|
|
@ -6,18 +6,19 @@ package com.tangem.domain.tokens.model
|
|||
sealed class NetworkAddress {
|
||||
|
||||
/** The default or currently selected network address. */
|
||||
abstract val defaultAddress: String
|
||||
abstract val defaultAddress: Address
|
||||
|
||||
/** The set of available network addresses to choose from. */
|
||||
abstract val availableAddresses: Set<Address>
|
||||
|
||||
/**
|
||||
* Represents a single static network address.
|
||||
*
|
||||
* @property defaultAddress The static network address.
|
||||
*/
|
||||
data class Single(override val defaultAddress: String) : NetworkAddress() {
|
||||
data class Single(override val defaultAddress: Address) : NetworkAddress() {
|
||||
|
||||
init {
|
||||
checkDefaultAddress()
|
||||
}
|
||||
override val availableAddresses: Set<Address> = setOf(defaultAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -27,17 +28,26 @@ sealed class NetworkAddress {
|
|||
* @property availableAddresses The set of available network addresses to choose from.
|
||||
*/
|
||||
data class Selectable(
|
||||
override val defaultAddress: String,
|
||||
val availableAddresses: Set<String>,
|
||||
override val defaultAddress: Address,
|
||||
override val availableAddresses: Set<Address>,
|
||||
) : NetworkAddress() {
|
||||
|
||||
init {
|
||||
checkDefaultAddress()
|
||||
require(availableAddresses.isNotEmpty()) { "Available network addresses must not be empty" }
|
||||
}
|
||||
}
|
||||
|
||||
protected fun checkDefaultAddress() {
|
||||
require(defaultAddress.isNotBlank()) { "Selected network address must not be blank" }
|
||||
data class Address(
|
||||
val value: String,
|
||||
val type: Type,
|
||||
) {
|
||||
|
||||
enum class Type {
|
||||
Primary, Secondary,
|
||||
}
|
||||
|
||||
init {
|
||||
require(value.isNotBlank()) { "Address value must not be blank" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +118,9 @@ internal class GetPrimaryCurrencyStatusUpdatesUseCaseTest {
|
|||
amount = BigDecimal.TEN,
|
||||
hasCurrentNetworkTransactions = false,
|
||||
pendingTransactions = emptySet(),
|
||||
networkAddress = NetworkAddress.Single(defaultAddress = "mock"),
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ internal object MockNetworks {
|
|||
network = network3,
|
||||
value = NetworkStatus.NoAccount(
|
||||
amountToCreateAccount = amountToCreateAccount,
|
||||
address = NetworkAddress.Single(defaultAddress = "mock"),
|
||||
address = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
errorMessage = "",
|
||||
),
|
||||
)
|
||||
|
|
@ -67,7 +69,9 @@ internal object MockNetworks {
|
|||
MockTokens.token3.id to CryptoCurrencyAmountStatus.Loaded(BigDecimal.TEN),
|
||||
),
|
||||
pendingTransactions = emptyMap(),
|
||||
address = NetworkAddress.Single(defaultAddress = "mock"),
|
||||
address = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -80,7 +84,9 @@ internal object MockNetworks {
|
|||
MockTokens.token6.id to CryptoCurrencyAmountStatus.Loaded(BigDecimal.TEN),
|
||||
),
|
||||
pendingTransactions = emptyMap(),
|
||||
address = NetworkAddress.Single(defaultAddress = "mock"),
|
||||
address = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -94,7 +100,9 @@ internal object MockNetworks {
|
|||
MockTokens.token10.id to CryptoCurrencyAmountStatus.Loaded(BigDecimal.TEN),
|
||||
),
|
||||
pendingTransactions = emptyMap(),
|
||||
address = NetworkAddress.Single(defaultAddress = "mock"),
|
||||
address = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.tokens.mock
|
|||
import arrow.core.nonEmptyListOf
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -64,7 +65,9 @@ internal object MockTokensStates {
|
|||
priceChange = MockQuotes.quote7.priceChange,
|
||||
fiatRate = MockQuotes.quote7.fiatRate,
|
||||
amountToCreateAccount = MockNetworks.amountToCreateAccount,
|
||||
networkAddress = null,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -75,7 +78,9 @@ internal object MockTokensStates {
|
|||
priceChange = MockQuotes.quote8.priceChange,
|
||||
fiatRate = MockQuotes.quote8.fiatRate,
|
||||
amountToCreateAccount = MockNetworks.amountToCreateAccount,
|
||||
networkAddress = null,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -86,7 +91,9 @@ internal object MockTokensStates {
|
|||
priceChange = MockQuotes.quote9.priceChange,
|
||||
fiatRate = MockQuotes.quote9.fiatRate,
|
||||
amountToCreateAccount = MockNetworks.amountToCreateAccount,
|
||||
networkAddress = null,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -97,7 +104,9 @@ internal object MockTokensStates {
|
|||
priceChange = MockQuotes.quote10.priceChange,
|
||||
fiatRate = MockQuotes.quote10.fiatRate,
|
||||
amountToCreateAccount = MockNetworks.amountToCreateAccount,
|
||||
networkAddress = null,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
|||
|
||||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.mapToAddressModels
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
|
|
@ -17,6 +16,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
|||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
|
|
@ -174,7 +174,7 @@ internal class TokenDetailsStateFactory(
|
|||
|
||||
fun getStateWithReceiveBottomSheet(
|
||||
currency: CryptoCurrency,
|
||||
addresses: List<Address>,
|
||||
networkAddress: NetworkAddress,
|
||||
sendCopyAnalyticsEvent: () -> Unit,
|
||||
sendShareAnalyticsEvent: () -> Unit,
|
||||
): TokenDetailsState {
|
||||
|
|
@ -186,12 +186,7 @@ internal class TokenDetailsStateFactory(
|
|||
name = currency.name,
|
||||
symbol = currency.symbol,
|
||||
network = currency.network.name,
|
||||
addresses = addresses.map {
|
||||
AddressModel(
|
||||
value = it.value,
|
||||
type = AddressModel.Type.valueOf(it.type.name),
|
||||
)
|
||||
},
|
||||
addresses = networkAddress.availableAddresses.mapToAddressModels(currency).toImmutableList(),
|
||||
onCopyClick = sendCopyAnalyticsEvent,
|
||||
onShareClick = sendShareAnalyticsEvent,
|
||||
),
|
||||
|
|
@ -199,20 +194,16 @@ internal class TokenDetailsStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getStateWithChooseAddressBottomSheet(addresses: List<Address>): TokenDetailsState {
|
||||
fun getStateWithChooseAddressBottomSheet(
|
||||
currency: CryptoCurrency,
|
||||
networkAddress: NetworkAddress,
|
||||
): TokenDetailsState {
|
||||
return currentStateProvider().copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
content = ChooseAddressBottomSheetConfig(
|
||||
addressModels = addresses
|
||||
.map { address ->
|
||||
AddressModel(
|
||||
value = address.value,
|
||||
type = AddressModel.Type.valueOf(address.type.name),
|
||||
)
|
||||
}
|
||||
.toImmutableList(),
|
||||
addressModels = networkAddress.availableAddresses.mapToAddressModels(currency).toImmutableList(),
|
||||
onClick = clickIntents::onAddressTypeSelected,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ import com.tangem.domain.tokens.*
|
|||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
import com.tangem.domain.tokens.models.analytics.TokenReceiveAnalyticsEvent
|
||||
import com.tangem.domain.tokens.models.analytics.TokenScreenAnalyticsEvent
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
@ -67,7 +67,6 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getCurrencyWarningsUseCase: GetCurrencyWarningsUseCase,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
|
|
@ -303,19 +302,15 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onReceiveClick() {
|
||||
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReceive(cryptoCurrency.symbol))
|
||||
val networkAddress = cryptoCurrencyStatus?.value?.networkAddress ?: return
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val addresses = walletManagersFacade.getAddress(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
|
||||
analyticsEventsHandler.send(event = TokenReceiveAnalyticsEvent.ReceiveScreenOpened)
|
||||
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReceive(cryptoCurrency.symbol))
|
||||
analyticsEventsHandler.send(TokenReceiveAnalyticsEvent.ReceiveScreenOpened)
|
||||
|
||||
uiState = stateFactory.getStateWithReceiveBottomSheet(
|
||||
currency = cryptoCurrency,
|
||||
addresses = addresses,
|
||||
networkAddress = networkAddress,
|
||||
sendCopyAnalyticsEvent = {
|
||||
analyticsEventsHandler.send(TokenReceiveAnalyticsEvent.ButtonCopyAddress(cryptoCurrency.symbol))
|
||||
},
|
||||
|
|
@ -378,22 +373,23 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun openExplorer() {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val addresses = walletManagersFacade.getAddress(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
val currencyStatus = cryptoCurrencyStatus ?: return
|
||||
|
||||
if (addresses.size == 1) {
|
||||
router.openUrl(
|
||||
url = getExploreUrlUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currency = cryptoCurrency,
|
||||
addressType = AddressType.Default,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
uiState = stateFactory.getStateWithChooseAddressBottomSheet(addresses = addresses)
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
when (val addresses = currencyStatus.value.networkAddress) {
|
||||
is NetworkAddress.Selectable -> {
|
||||
uiState = stateFactory.getStateWithChooseAddressBottomSheet(cryptoCurrency, addresses)
|
||||
}
|
||||
is NetworkAddress.Single -> {
|
||||
router.openUrl(
|
||||
url = getExploreUrlUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currency = cryptoCurrency,
|
||||
addressType = AddressType.Default,
|
||||
),
|
||||
)
|
||||
}
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.core.navigation.AppScreen
|
|||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.mapToAddressModels
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
|
|
@ -42,10 +43,7 @@ import com.tangem.domain.settings.*
|
|||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.NetworkGroup
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.tokens.model.*
|
||||
import com.tangem.domain.tokens.models.analytics.TokenReceiveAnalyticsEvent
|
||||
import com.tangem.domain.tokens.models.analytics.TokenScreenAnalyticsEvent
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
|
|
@ -688,20 +686,11 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onReceiveClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
|
||||
analyticsEventsHandler.send(
|
||||
event = TokenScreenAnalyticsEvent.ButtonReceive(cryptoCurrencyStatus.currency.symbol),
|
||||
)
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
|
||||
|
||||
val addresses = walletManagersFacade.getAddress(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
)
|
||||
|
||||
analyticsEventsHandler.send(event = TokenReceiveAnalyticsEvent.ReceiveScreenOpened)
|
||||
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
|
|
@ -710,12 +699,11 @@ internal class WalletViewModel @Inject constructor(
|
|||
name = currency.name,
|
||||
symbol = currency.symbol,
|
||||
network = currency.network.name,
|
||||
addresses = addresses.map {
|
||||
AddressModel(
|
||||
value = it.value,
|
||||
type = AddressModel.Type.valueOf(it.type.name),
|
||||
)
|
||||
},
|
||||
addresses = cryptoCurrencyStatus.value.networkAddress
|
||||
?.availableAddresses
|
||||
?.mapToAddressModels(currency)
|
||||
.orEmpty()
|
||||
.toImmutableList(),
|
||||
onCopyClick = {
|
||||
analyticsEventsHandler.send(TokenReceiveAnalyticsEvent.ButtonCopyAddress(currency.symbol))
|
||||
},
|
||||
|
|
@ -820,41 +808,39 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
private fun openExplorer() {
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
val currency = singleWalletCryptoCurrencyStatus?.currency ?: return
|
||||
val currencyStatus = singleWalletCryptoCurrencyStatus ?: return
|
||||
val currency = currencyStatus.currency
|
||||
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
val userWalletId = getWallet(state.walletsListConfig.selectedWalletIndex).walletId
|
||||
|
||||
val addresses = walletManagersFacade.getAddress(userWalletId = userWalletId, network = currency.network)
|
||||
|
||||
if (addresses.size == 1) {
|
||||
router.openUrl(
|
||||
url = getExploreUrlUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currency = currency,
|
||||
addressType = AddressType.Default,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
|
||||
ChooseAddressBottomSheetConfig(
|
||||
addressModels = addresses
|
||||
.map { address ->
|
||||
AddressModel(
|
||||
value = address.value,
|
||||
type = AddressModel.Type.valueOf(address.type.name),
|
||||
when (val addresses = currencyStatus.value.networkAddress) {
|
||||
is NetworkAddress.Selectable -> {
|
||||
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
|
||||
ChooseAddressBottomSheetConfig(
|
||||
addressModels = addresses.availableAddresses
|
||||
.mapToAddressModels(currency)
|
||||
.toImmutableList(),
|
||||
onClick = {
|
||||
onAddressTypeSelected(
|
||||
userWalletId = userWalletId,
|
||||
currency = currency,
|
||||
addressModel = it,
|
||||
)
|
||||
}
|
||||
.toImmutableList(),
|
||||
onClick = {
|
||||
onAddressTypeSelected(
|
||||
userWalletId = userWalletId,
|
||||
currency = currency,
|
||||
addressModel = it,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
is NetworkAddress.Single -> {
|
||||
router.openUrl(
|
||||
url = getExploreUrlUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currency = currency,
|
||||
addressType = AddressType.Default,
|
||||
),
|
||||
)
|
||||
}
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ spr-client = "3.6.2"
|
|||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
tangemBlockchainSdk = "release-app_5.3-404"
|
||||
tangemBlockchainSdk = "release-app_5.3-405"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "release-app_5.3-313"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue