Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-28 13:18:35 +05:00
parent f540156e3d
commit 7457d4de1a
7 changed files with 71 additions and 5 deletions

View file

@ -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<List<CryptoCurrency>> {
return userTokensStore.get(userWallet.walletId).map { storedTokens ->
responseCurrenciesFactory.createCurrencies(

View file

@ -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,

View file

@ -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<AddCurrencyError, Unit> = 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].
*

View file

@ -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
}

View file

@ -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<CryptoCurrencyAddress>
}

View file

@ -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
}
}

View file

@ -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,
)
}
}