diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/CardCryptoCurrencyFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/CardCryptoCurrencyFactory.kt index d4a94d6ea7..83d76a648e 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/CardCryptoCurrencyFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/CardCryptoCurrencyFactory.kt @@ -22,6 +22,15 @@ interface CardCryptoCurrencyFactory { @Throws suspend fun create(userWalletId: UserWalletId, network: Network): List + /** + * Universal method for creating list of [CryptoCurrency] in [network] for any card + * + * @param userWalletId user wallet id that determines type of card + * @param network network + */ + @Throws + suspend fun createByRawId(userWalletId: UserWalletId, network: Network.RawID): List + /** * Create currencies for multi currency card * diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt index 1a0267508a..397f26a256 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt @@ -3,6 +3,8 @@ package com.tangem.data.common.currency import com.tangem.blockchain.common.Blockchain import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.blockchainsdk.utils.toBlockchain +import com.tangem.blockchainsdk.utils.toNetworkId import com.tangem.datasource.local.token.UserTokensResponseStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.common.TapWorkarounds.isTestCard @@ -54,6 +56,32 @@ internal class DefaultCardCryptoCurrencyFactory( return createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf) } + override suspend fun createByRawId(userWalletId: UserWalletId, networkRawId: Network.RawID): List { + val userWallet = userWalletsStore.getSyncStrict(key = userWalletId) + + val blockchain = networkRawId.toBlockchain() + + // multi-currency wallet + if (userWallet.isMultiCurrency) { + return getMultiWalletCurrenciesByRawId( + userWallet = userWallet, + rawIds = setOf(networkRawId), + )[networkRawId].orEmpty() + } + + // check if the blockchain of single-currency wallet is the same as network + val cardBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain() + if (cardBlockchain != blockchain) return emptyList() + + // single-currency wallet with token (NODL) + if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) { + return createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse) + } + + // single-currency wallet + return createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf) + } + override suspend fun createCurrenciesForMultiCurrencyCard( userWallet: UserWallet, networks: Set, @@ -123,6 +151,24 @@ internal class DefaultCardCryptoCurrencyFactory( .groupBy(CryptoCurrency::network) } + private suspend fun getMultiWalletCurrenciesByRawId( + userWallet: UserWallet, + rawIds: Set, + ): Map> { + val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId) + ?: return emptyMap() + + val responseCurrenciesFactory = ResponseCryptoCurrenciesFactory(excludedBlockchains) + + val networkIds = rawIds.map { it.toBlockchain().toNetworkId() } + + return responseCurrenciesFactory.createCurrencies( + tokens = response.tokens.filter { token -> token.networkId in networkIds }, + scanResponse = userWallet.scanResponse, + ) + .groupBy { it.network.id.rawId } + } + private fun getSingleWalletCurrencies(scanResponse: ScanResponse): SingleWalletCurrencies { val resolver = scanResponse.cardTypesResolver val blockchain = resolver.getBlockchain() diff --git a/data/networks/src/main/java/com/tangem/data/networks/repository/DefaultNetworksRepository.kt b/data/networks/src/main/java/com/tangem/data/networks/repository/DefaultNetworksRepository.kt index 8f44fb43e5..a0076f8352 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/repository/DefaultNetworksRepository.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/repository/DefaultNetworksRepository.kt @@ -62,6 +62,23 @@ internal class DefaultNetworksRepository( } } + override suspend fun getNetworkAddresses( + userWalletId: UserWalletId, + network: Network.RawID, + ): List { + return runCatching { cardCryptoCurrencyFactory.createByRawId(userWalletId = userWalletId, network = network) } + .getOrElse { + Timber.e(it, "Unable to create wallet currencies") + return emptyList() + } + .map { currency -> + CryptoCurrencyAddress( + cryptoCurrency = currency, + address = getDefaultAddress(userWalletId, currency.network), + ) + } + } + private suspend fun fetchPendingTransactions( userWalletId: UserWalletId, network: Network, diff --git a/domain/networks/src/main/java/com/tangem/domain/networks/repository/NetworksRepository.kt b/domain/networks/src/main/java/com/tangem/domain/networks/repository/NetworksRepository.kt index 43cc7b6554..416fe8d8af 100644 --- a/domain/networks/src/main/java/com/tangem/domain/networks/repository/NetworksRepository.kt +++ b/domain/networks/src/main/java/com/tangem/domain/networks/repository/NetworksRepository.kt @@ -21,4 +21,6 @@ interface NetworksRepository { * @param network network */ suspend fun getNetworkAddresses(userWalletId: UserWalletId, network: Network): List + + suspend fun getNetworkAddresses(userWalletId: UserWalletId, network: Network.RawID): List } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNetworkAddressesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNetworkAddressesUseCase.kt index 8bce462ec2..a397b2464e 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNetworkAddressesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetNetworkAddressesUseCase.kt @@ -9,6 +9,10 @@ class GetNetworkAddressesUseCase( private val networksRepository: NetworksRepository, ) { + suspend fun invokeSync(userWalletId: UserWalletId, networkRawId: Network.RawID): List { + return networksRepository.getNetworkAddresses(userWalletId, networkRawId) + } + suspend fun invokeSync(userWalletId: UserWalletId, network: Network): List { return networksRepository.getNetworkAddresses(userWalletId, network) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt index e61b03c0c3..9f86aa9c34 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt @@ -142,8 +142,10 @@ internal class SendDestinationModel @Inject constructor( private fun initSenderAddress() { modelScope.launch { - senderAddresses.value = getNetworkAddressesUseCase.invokeSync(userWalletId, cryptoCurrency.network) - .filter { cryptoCurrency.id == it.cryptoCurrency.id } + senderAddresses.value = getNetworkAddressesUseCase.invokeSync( + userWalletId = userWalletId, + networkRawId = cryptoCurrency.network.id.rawId, + ).filter { cryptoCurrency.id == it.cryptoCurrency.id } } senderAddresses.onEach { getWalletsAndRecent() @@ -212,13 +214,19 @@ internal class SendDestinationModel @Inject constructor( val addresses = if (!wallet.isMultiCurrency) { getCryptoCurrencyUseCase(wallet.walletId).getOrNull()?.let { if (it.network.id == cryptoCurrencyNetwork.id) { - getNetworkAddressesUseCase.invokeSync(wallet.walletId, it.network) + getNetworkAddressesUseCase.invokeSync( + userWalletId = wallet.walletId, + networkRawId = it.network.id.rawId, + ) } else { null } } } else { - getNetworkAddressesUseCase.invokeSync(wallet.walletId, cryptoCurrencyNetwork) + getNetworkAddressesUseCase.invokeSync( + userWalletId = wallet.walletId, + networkRawId = cryptoCurrencyNetwork.id.rawId, + ) } wallet to addresses } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt index f4ff8144d3..bee4fd13bd 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/model/SendModel.kt @@ -430,13 +430,19 @@ internal class SendModel @Inject constructor( cryptoCurrencyId = cryptoCurrency.id.value, ).getOrNull()?.let { if (it.network.id == cryptoCurrency.network.id) { - getNetworkAddressesUseCase.invokeSync(wallet.walletId, it.network) + getNetworkAddressesUseCase.invokeSync( + userWalletId = wallet.walletId, + networkRawId = it.network.id.rawId, + ) } else { null } } } else { - getNetworkAddressesUseCase.invokeSync(wallet.walletId, cryptoCurrency.network) + getNetworkAddressesUseCase.invokeSync( + userWalletId = wallet.walletId, + networkRawId = cryptoCurrency.network.id.rawId, + ) } addresses?.map { (cryptoCurrency, address) -> AvailableWallet( diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/NetworkExt.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/NetworkExt.kt index 61d715f180..e6534bcb53 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/NetworkExt.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/NetworkExt.kt @@ -7,4 +7,6 @@ import com.tangem.domain.models.network.Network fun Network.toBlockchain(): Blockchain = id.toBlockchain() /** Converts [Network.ID] to [Blockchain] */ -fun Network.ID.toBlockchain(): Blockchain = Blockchain.fromId(id = rawId.value) \ No newline at end of file +fun Network.ID.toBlockchain(): Blockchain = rawId.toBlockchain() + +fun Network.RawID.toBlockchain(): Blockchain = Blockchain.fromId(id = value) \ No newline at end of file