diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index f17e141216..91fbcf1881 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -391,6 +391,13 @@ internal class DefaultCurrenciesRepository( } } + override fun createTokenCurrency(cryptoCurrency: CryptoCurrency.Token, network: Network): CryptoCurrency.Token { + return CryptoCurrencyFactory().createToken( + cryptoCurrency = cryptoCurrency, + network = network, + ) + } + private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow> { return userTokensStore.get(userWallet.walletId).map { storedTokens -> responseCurrenciesFactory.createCurrencies( diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CryptoCurrencyFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CryptoCurrencyFactory.kt index 3b4bfb61e0..55b2b0b161 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CryptoCurrencyFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/CryptoCurrencyFactory.kt @@ -5,6 +5,7 @@ import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.blockchainsdk.utils.toCoinId import com.tangem.domain.common.DerivationStyleProvider import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.tokens.model.Network import timber.log.Timber import com.tangem.blockchain.common.Token as SdkToken @@ -90,6 +91,28 @@ class CryptoCurrencyFactory { ) } + fun createToken(cryptoCurrency: CryptoCurrency.Token, network: Network): CryptoCurrency.Token { + val sdkToken = SdkToken( + name = cryptoCurrency.name, + symbol = cryptoCurrency.symbol, + contractAddress = cryptoCurrency.contractAddress, + decimals = cryptoCurrency.decimals, + id = cryptoCurrency.id.rawCurrencyId, + ) + val blockchain = Blockchain.fromNetworkId(cryptoCurrency.network.id.value) ?: Blockchain.Unknown + val id = getTokenId(network, sdkToken) + return CryptoCurrency.Token( + id = id, + network = network, + name = sdkToken.name, + symbol = sdkToken.symbol, + iconUrl = getTokenIconUrl(blockchain, sdkToken), + decimals = sdkToken.decimals, + isCustom = isCustomToken(id, network), + contractAddress = sdkToken.contractAddress, + ) + } + data class Token( val name: String, val symbol: String, diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt index 21613763a1..9febf735fe 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/AddCryptoCurrenciesUseCase.kt @@ -7,6 +7,7 @@ import arrow.core.raise.either import arrow.core.toNonEmptyListOrNull import com.tangem.domain.tokens.error.AddCurrencyError import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.tokens.model.Network import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.wallets.models.UserWalletId @@ -37,6 +38,26 @@ class AddCryptoCurrenciesUseCase( return invoke(userWalletId, listOf(currency)) } + /** + * Adds a [cryptoCurrency] token with specific [network] and derivation to the wallet identified by [userWalletId]. + * + * After successfully adding a currency, it also refreshes the networks for tokens + * that are being added and have corresponding coins in the existing currencies list. + * + * @param userWalletId The ID of the user's wallet. + * @param cryptoCurrency Token to add. + * @param network Network where we add + * @return Either an [AddCurrencyError] or [Unit] indicating the success of the operation. + */ + suspend operator fun invoke( + userWalletId: UserWalletId, + cryptoCurrency: CryptoCurrency.Token, + network: Network, + ): Either = either { + val tokenToAdd = currenciesRepository.createTokenCurrency(cryptoCurrency = cryptoCurrency, network = network) + invoke(userWalletId = userWalletId, currencies = listOf(tokenToAdd)) + } + /** * Adds a list of [currencies] to the wallet identified by [userWalletId]. * diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt index 61cc6f66ee..e21dfac83c 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt @@ -194,4 +194,9 @@ interface CurrenciesRepository { * Retrieves fee paid currency for specific [currency]. */ suspend fun getFeePaidCurrency(userWalletId: UserWalletId, currency: CryptoCurrency): FeePaidCurrency + + /** + * Creates token [cryptoCurrency] based on current token and [network] it`s will be added + */ + fun createTokenCurrency(cryptoCurrency: CryptoCurrency.Token, network: Network): CryptoCurrency.Token } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt index 2603914a46..a2033bb707 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/NetworksRepository.kt @@ -62,5 +62,8 @@ interface NetworksRepository { fun isNeedToCreateAccountWithoutReserve(network: Network): Boolean + /** + * Returns list of addresses and crypto currency info of added currencies of [network] in selected wallet [userWalletId] + */ suspend fun getNetworkAddresses(userWalletId: UserWalletId, network: Network): List } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt index e3233d8474..30d41cb47e 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt @@ -128,4 +128,8 @@ internal class MockCurrenciesRepository( override suspend fun getFeePaidCurrency(userWalletId: UserWalletId, currency: CryptoCurrency): FeePaidCurrency { return FeePaidCurrency.Coin } + + override fun createTokenCurrency(cryptoCurrency: CryptoCurrency.Token, network: Network): CryptoCurrency.Token { + return cryptoCurrency + } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 9f2109e070..d07fa04c51 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -4,7 +4,6 @@ import android.os.SystemClock import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.compose.ui.util.fastDistinctBy import androidx.lifecycle.* import arrow.core.Either import arrow.core.getOrElse @@ -442,7 +441,7 @@ internal class SendViewModel @Inject constructor( getNetworkAddressesUseCase.invokeSync(wallet.walletId, cryptoCurrency.network) } addresses - ?.filter { it.address != currentAddress } + ?.filter { it.address != currentAddress && it.cryptoCurrency is CryptoCurrency.Coin } ?.map { (cryptoCurrency, address) -> AvailableWallet( name = wallet.name, @@ -450,7 +449,7 @@ internal class SendViewModel @Inject constructor( cryptoCurrency = cryptoCurrency, userWalletId = wallet.walletId, ) - }?.fastDistinctBy { it.address } + } }.flatten() } @@ -898,10 +897,14 @@ internal class SendViewModel @Inject constructor( val recipientState = uiState.getRecipientState(stateRouter.isEditState) ?: return val destinationAddress = recipientState.addressTextField.value - val maybeUserWallet = userWallets.firstOrNull { it.address == destinationAddress } ?: return + val receivingUserWallet = userWallets.firstOrNull { it.address == destinationAddress } ?: return viewModelScope.launch(dispatchers.io) { - addCryptoCurrenciesUseCase(userWalletId = maybeUserWallet.userWalletId, currency = cryptoCurrency) + addCryptoCurrenciesUseCase( + userWalletId = receivingUserWallet.userWalletId, + cryptoCurrency = cryptoCurrency, + network = receivingUserWallet.cryptoCurrency.network, + ) } }