From d47433ee6cd1faefc6ad31b4676f20ad9efc4728 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 2 Dec 2025 13:23:56 +0400 Subject: [PATCH] Updated on 2026-08-14 --- data/account/detekt-baseline-debug.xml | 2 - .../AccountListCryptoCurrenciesProducer.kt | 8 ++- ...aultMultiWalletCryptoCurrenciesProducer.kt | 4 +- ...MultiWalletCryptoCurrenciesProducerTest.kt | 15 ++++-- .../DefaultCardCryptoCurrencyFactory.kt | 12 ++++- .../ResponseCryptoCurrenciesFactory.kt | 10 ++-- data/manage-tokens/detekt-baseline-debug.xml | 8 --- .../DefaultManageTokensRepository.kt | 33 ++++++++----- .../utils/ManagedCryptoCurrencyFactory.kt | 49 +++++++++++++------ data/swap/build.gradle.kts | 1 + .../SavedSwapTransactionConverter.kt | 18 +++++++ .../SavedSwapTransactionListConverter.kt | 6 ++- data/tokens/detekt-baseline-debug.xml | 3 -- .../repository/DefaultCurrenciesRepository.kt | 19 ++++--- data/wallets/detekt-baseline-debug.xml | 4 -- .../DefaultDerivationsRepository.kt | 24 +++++---- .../hot/DefaultHotMapDerivationsRepository.kt | 9 ++-- detekt_baseline_report.txt | 18 +++---- domain/markets/detekt-baseline-debug.xml | 1 - .../domain/markets/SaveMarketTokensUseCase.kt | 11 +++-- .../derivations/DerivationsRepository.kt | 7 ++- .../HotMapDerivationsRepository.kt | 2 + features/swap/data/build.gradle.kts | 4 +- .../SavedSwapTransactionListConverter.kt | 15 ++++++ 24 files changed, 193 insertions(+), 90 deletions(-) diff --git a/data/account/detekt-baseline-debug.xml b/data/account/detekt-baseline-debug.xml index f0b34d22a4..014cb3a866 100644 --- a/data/account/detekt-baseline-debug.xml +++ b/data/account/detekt-baseline-debug.xml @@ -6,8 +6,6 @@ MultilineLambdaItParameter:DefaultAccountsCRUDRepository.kt$DefaultAccountsCRUDRepository${ if (it is HttpException && it.code == HttpException.Code.NOT_MODIFIED) { null } else { throw it } } MultilineLambdaItParameter:GetWalletAccountsResponseExt.kt${ enrichedTokensByAccountId[it].orEmpty().map { token -> // Tokens from unexisting accounts should be copied to the main account token.copy(accountId = accountDTO.id) } } NoNameShadowing:GetWalletAccountsResponseExt.kt$tokens - NullableToStringCall:AccountListCryptoCurrenciesProducer.kt$AccountListCryptoCurrenciesProducer$${this::class.simpleName} - NullableToStringCall:DefaultMultiWalletCryptoCurrenciesProducer.kt$DefaultMultiWalletCryptoCurrenciesProducer$${this::class.simpleName} UnnecessaryLet:DefaultAccountsCRUDRepository.kt$DefaultAccountsCRUDRepository$let(AccountName::invoke) diff --git a/data/account/src/main/kotlin/com/tangem/data/account/producer/AccountListCryptoCurrenciesProducer.kt b/data/account/src/main/kotlin/com/tangem/data/account/producer/AccountListCryptoCurrenciesProducer.kt index 9722001f29..4cd149ae75 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/producer/AccountListCryptoCurrenciesProducer.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/producer/AccountListCryptoCurrenciesProducer.kt @@ -36,11 +36,12 @@ internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor( override val fallback: Option> = emptySet().some() + @Suppress("NullableToStringCall") override fun produce(): Flow> { val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId) if (!userWallet.isMultiCurrency) { - error("${this::class.simpleName} supports only multi-currency wallet") + error("${this::class.simpleName ?: this::class.toString()} supports only multi-currency wallet") } return accountsResponseStoreFactory.create(userWalletId = userWallet.walletId).data @@ -49,10 +50,13 @@ internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor( if (response == null) return@map emptySet() response.accounts.flatMapTo(hashSetOf()) { accountDTO -> + val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() + ?: return@map emptySet() + responseCryptoCurrenciesFactory.createCurrencies( tokens = accountDTO.tokens.orEmpty(), userWallet = userWallet, - accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull(), + accountIndex = accountIndex, ) } } diff --git a/data/account/src/main/kotlin/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducer.kt b/data/account/src/main/kotlin/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducer.kt index 8c46088747..25255d60b4 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducer.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducer.kt @@ -5,6 +5,7 @@ import arrow.core.some import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory import com.tangem.datasource.local.token.UserTokensResponseStore import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.isMultiCurrency import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer @@ -39,7 +40,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId) if (!userWallet.isMultiCurrency) { - error("${this::class.simpleName} supports only multi-currency wallet") + error("${this::class.simpleName ?: this::class.toString()} supports only multi-currency wallet") } return userTokensResponseStore.get(userWalletId = params.userWalletId) @@ -50,6 +51,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr responseCryptoCurrenciesFactory.createCurrencies( response = response, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ).toSet() } .onEmpty { emit(emptySet()) } diff --git a/data/account/src/test/java/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducerTest.kt b/data/account/src/test/java/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducerTest.kt index 983ba0706e..c622f073a4 100644 --- a/data/account/src/test/java/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducerTest.kt +++ b/data/account/src/test/java/com/tangem/data/account/producer/DefaultMultiWalletCryptoCurrenciesProducerTest.kt @@ -10,6 +10,7 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.datasource.local.token.UserTokensResponseStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.card.configs.GenericCardConfig +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.isMultiCurrency @@ -72,7 +73,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { } verify(inverse = true) { - responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any()) + responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any(), accountIndex = any()) } } @@ -115,6 +116,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } returns cryptoCurrencies.toList() @@ -122,6 +124,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = updatedUserTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } returns updatedCryptoCurrencies.toList() @@ -144,6 +147,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } @@ -162,6 +166,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = updatedUserTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } } @@ -186,6 +191,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } returns cryptoCurrencies.toList() @@ -208,6 +214,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } @@ -252,6 +259,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } returns cryptoCurrencies.toList() @@ -283,6 +291,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { responseCryptoCurrenciesFactory.createCurrencies( response = userTokensResponse, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } } @@ -307,7 +316,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { } verify(inverse = true) { - responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any()) + responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any(), accountIndex = any()) } } @@ -335,7 +344,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest { verify(inverse = true) { userTokensResponseStore.get(any()) - responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any()) + responseCryptoCurrenciesFactory.createCurrencies(response = any(), userWallet = any(), accountIndex = any()) } } 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 626f998bfb..2d7a8855d7 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 @@ -144,6 +144,9 @@ internal class DefaultCardCryptoCurrencyFactory( ?: return emptyMap() response.accounts.flatMapTo(hashSetOf()) { accountDTO -> + val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() + ?: return@flatMapTo emptySet() + responseCryptoCurrenciesFactory.createCurrencies( tokens = accountDTO.tokens.orEmpty().filter { token -> networks.any { @@ -151,7 +154,7 @@ internal class DefaultCardCryptoCurrencyFactory( } }, userWallet = userWallet, - accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull(), + accountIndex = accountIndex, ) } } else { @@ -163,6 +166,7 @@ internal class DefaultCardCryptoCurrencyFactory( networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath } }, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } .groupBy(CryptoCurrency::network) @@ -181,10 +185,13 @@ internal class DefaultCardCryptoCurrencyFactory( ?: return emptyMap() response.accounts.flatMapTo(hashSetOf()) { accountDTO -> + val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() + ?: return@flatMapTo emptySet() + responseCryptoCurrenciesFactory.createCurrencies( tokens = accountDTO.tokens.orEmpty().filter { token -> token.networkId in networkIds }, userWallet = userWallet, - accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull(), + accountIndex = accountIndex, ) } } else { @@ -194,6 +201,7 @@ internal class DefaultCardCryptoCurrencyFactory( responseCryptoCurrenciesFactory.createCurrencies( tokens = response.tokens.filter { token -> token.networkId in networkIds }, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } .groupBy { it.network.id.rawId } diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/ResponseCryptoCurrenciesFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/ResponseCryptoCurrenciesFactory.kt index 66faea0a74..eccf6e4952 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/ResponseCryptoCurrenciesFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/ResponseCryptoCurrenciesFactory.kt @@ -22,7 +22,7 @@ class ResponseCryptoCurrenciesFactory @Inject constructor( fun createCurrencies( response: UserTokensResponse, userWallet: UserWallet, - accountIndex: DerivationIndex? = null, + accountIndex: DerivationIndex, ): List { return createCurrencies(tokens = response.tokens, userWallet = userWallet, accountIndex = accountIndex) } @@ -30,7 +30,7 @@ class ResponseCryptoCurrenciesFactory @Inject constructor( fun createCurrencies( tokens: List, userWallet: UserWallet, - accountIndex: DerivationIndex? = null, + accountIndex: DerivationIndex, ): List { return tokens .asSequence() @@ -42,7 +42,7 @@ class ResponseCryptoCurrenciesFactory @Inject constructor( fun createCurrency( responseToken: UserTokensResponse.Token, userWallet: UserWallet, - accountIndex: DerivationIndex? = null, + accountIndex: DerivationIndex, ): CryptoCurrency? { var blockchain = Blockchain.fromNetworkId(responseToken.networkId) if (blockchain == null || blockchain == Blockchain.Unknown) { @@ -103,7 +103,7 @@ class ResponseCryptoCurrenciesFactory @Inject constructor( blockchain: Blockchain, responseToken: UserTokensResponse.Token, network: Network, - ): CryptoCurrency.Coin? { + ): CryptoCurrency.Coin { return CryptoCurrency.Coin( id = getCoinId(network, blockchain.toCoinId()), network = network, @@ -127,7 +127,7 @@ class ResponseCryptoCurrenciesFactory @Inject constructor( } } - private fun createToken(blockchain: Blockchain, sdkToken: Token, network: Network): CryptoCurrency.Token? { + private fun createToken(blockchain: Blockchain, sdkToken: Token, network: Network): CryptoCurrency.Token { val id = getTokenId(network, sdkToken) return CryptoCurrency.Token( diff --git a/data/manage-tokens/detekt-baseline-debug.xml b/data/manage-tokens/detekt-baseline-debug.xml index d384bf15ce..a9b6d430bb 100644 --- a/data/manage-tokens/detekt-baseline-debug.xml +++ b/data/manage-tokens/detekt-baseline-debug.xml @@ -3,15 +3,7 @@ MultilineLambdaItParameter:DefaultCustomTokensRepository.kt$DefaultCustomTokensRepository${ // TODO: refactor https://tangem.atlassian.net/browse/AND-10006\ if (it.isTestnet() || it in excludedBlockchains || it in hotWalletExcludedBlockchains) { return@mapNotNull null } networkFactory.create( blockchain = it, extraDerivationPath = null, userWallet = userWallet, ) } - MultilineLambdaItParameter:DefaultManageTokensRepository.kt$DefaultManageTokensRepository${ it.contractAddress != null && it.networkId == network.backendId && it.derivationPath == network.derivationPath.value } MultilineLambdaItParameter:ManageTokensUpdateFetcher.kt$ManageTokensUpdateFetcher${ if (it.key == toUpdate[index].key) { Batch(it.key, updatedItems) } else { null } } - NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$create(coinsResponse, tokensResponse, userWallet, accountIndex) - NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$createToken(coin, tokensResponse, coinsResponse.imageHost, userWallet, accountIndex) - NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$findAddedInNetworks(coinResponse.id, tokensResponse, userWallet, accountIndex) - NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$findAddedInNetworks(testnetToken.id, tokensResponse, userWallet, accountIndex) - SuspendFunSwallowedCancellation:DefaultManageTokensRepository.kt$DefaultManageTokensRepository$runCatching UnsafeCallOnNullableType:DefaultCustomTokensRepository.kt$DefaultCustomTokensRepository$coinNetwork.decimalCount!! - UseOrEmpty:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$testnetToken.networks?.mapNotNull { network -> createSource( networkId = network.id, contractAddress = network.address, decimals = network.decimalCount, userWallet = userWallet, accountIndex = accountIndex, ) } ?: emptyList() - UseOrEmpty:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$tokensResponse ?.let { createCustomTokens(it, userWallet, accountIndex) } ?: emptyList() diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt index ed2887e114..84eea67a90 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultManageTokensRepository.kt @@ -41,6 +41,7 @@ import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher.Request import com.tangem.pagination.toBatchFlow import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.coroutines.runSuspendCatching @Suppress("LongParameterList", "LargeClass") internal class DefaultManageTokensRepository( @@ -176,7 +177,7 @@ internal class DefaultManageTokensRepository( val shouldFetch = loadUserTokensFromRemote && userWallet != null val fetchedResponse = if (shouldFetch) { - runCatching { walletAccountsFetcher.fetch(userWalletId = userWallet.walletId) }.getOrNull() + runSuspendCatching { walletAccountsFetcher.fetch(userWalletId = userWallet.walletId) }.getOrNull() } else { null } @@ -214,19 +215,22 @@ internal class DefaultManageTokensRepository( userWallet != null && query == null + val accountIndex = accountDTO?.derivationIndex?.let(DerivationIndex::invoke)?.getOrNull() + ?: return emptyList() + val items = if (isCreateWithCustom) { managedCryptoCurrencyFactory.createWithCustomTokens( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, userWallet = userWallet, - accountIndex = accountDTO?.derivationIndex?.let(DerivationIndex::invoke)?.getOrNull(), + accountIndex = accountIndex, ) } else { managedCryptoCurrencyFactory.create( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, userWallet = userWallet, - accountIndex = accountDTO?.derivationIndex?.let(DerivationIndex::invoke)?.getOrNull(), + accountIndex = accountIndex, ) } @@ -262,14 +266,14 @@ internal class DefaultManageTokensRepository( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, userWallet = userWallet, - accountIndex = null, + accountIndex = DerivationIndex.Main, ) } else { managedCryptoCurrencyFactory.create( coinsResponse = updatedCoinsResponse, tokensResponse = tokensResponse, userWallet = userWallet, - accountIndex = null, + accountIndex = DerivationIndex.Main, ) } } @@ -307,6 +311,13 @@ internal class DefaultManageTokensRepository( ) } + val accountIndex = accountDTO?.derivationIndex?.let(DerivationIndex::invoke)?.getOrNull() + ?: return BatchFetchResult.Success( + data = emptyList(), + empty = true, + last = true, + ) + val items = managedCryptoCurrencyFactory.createTestnetWithCustomTokens( testnetTokensConfig = if (!searchText.isNullOrBlank()) { testnetTokensConfig.copy( @@ -320,7 +331,7 @@ internal class DefaultManageTokensRepository( }, tokensResponse = tokensResponse, userWallet = userWallet, - accountIndex = accountDTO?.derivationIndex?.let(DerivationIndex::invoke)?.getOrNull(), + accountIndex = accountIndex, ) return BatchFetchResult.Success( @@ -350,7 +361,7 @@ internal class DefaultManageTokensRepository( }, tokensResponse = getSavedUserTokensResponseSync(userWallet.walletId), userWallet = userWallet, - accountIndex = null, + accountIndex = DerivationIndex.Main, ) return BatchFetchResult.Success( @@ -392,10 +403,10 @@ internal class DefaultManageTokensRepository( ) val newTokensList = storedTokens.tokens + addedTokens - removedTokens.toSet() - return newTokensList.any { - it.contractAddress != null && - it.networkId == network.backendId && - it.derivationPath == network.derivationPath.value + return newTokensList.any { token -> + token.contractAddress != null && + token.networkId == network.backendId && + token.derivationPath == network.derivationPath.value } } diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt index 5ecaec838c..49ec7c78de 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/utils/ManagedCryptoCurrencyFactory.kt @@ -35,10 +35,16 @@ internal class ManagedCryptoCurrencyFactory( coinsResponse: CoinsResponse, tokensResponse: UserTokensResponse?, userWallet: UserWallet?, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): List { return coinsResponse.coins.mapNotNull { coin -> - createToken(coin, tokensResponse, coinsResponse.imageHost, userWallet, accountIndex) + createToken( + coinResponse = coin, + tokensResponse = tokensResponse, + imageHost = coinsResponse.imageHost, + userWallet = userWallet, + accountIndex = accountIndex, + ) } } @@ -46,10 +52,15 @@ internal class ManagedCryptoCurrencyFactory( coinsResponse: CoinsResponse, tokensResponse: UserTokensResponse, userWallet: UserWallet, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): List { val customTokens = createCustomTokens(tokensResponse, userWallet, accountIndex) - val tokens = create(coinsResponse, tokensResponse, userWallet, accountIndex) + val tokens = create( + coinsResponse = coinsResponse, + tokensResponse = tokensResponse, + userWallet = userWallet, + accountIndex = accountIndex, + ) return customTokens + tokens } @@ -58,11 +69,11 @@ internal class ManagedCryptoCurrencyFactory( testnetTokensConfig: TestnetTokensConfig, tokensResponse: UserTokensResponse?, userWallet: UserWallet, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): List { val customTokens = tokensResponse ?.let { createCustomTokens(it, userWallet, accountIndex) } - ?: emptyList() + .orEmpty() val testnetTokens = testnetTokensConfig.tokens.map { testnetToken -> ManagedCryptoCurrency.Token( id = ManagedCryptoCurrency.ID(testnetToken.id), @@ -77,8 +88,13 @@ internal class ManagedCryptoCurrencyFactory( userWallet = userWallet, accountIndex = accountIndex, ) - } ?: emptyList(), - addedIn = findAddedInNetworks(testnetToken.id, tokensResponse, userWallet, accountIndex), + }.orEmpty(), + addedIn = findAddedInNetworks( + currencyId = testnetToken.id, + tokensResponse = tokensResponse, + userWallet = userWallet, + accountIndex = accountIndex, + ), ) } @@ -88,7 +104,7 @@ internal class ManagedCryptoCurrencyFactory( private fun createCustomTokens( tokensResponse: UserTokensResponse, userWallet: UserWallet, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): List = tokensResponse.tokens .mapNotNull { token -> maybeCreateCustomToken(token, userWallet, accountIndex) @@ -97,7 +113,7 @@ internal class ManagedCryptoCurrencyFactory( private fun maybeCreateCustomToken( token: UserTokensResponse.Token, userWallet: UserWallet, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): ManagedCryptoCurrency? { val blockchain = Blockchain.fromNetworkId(token.networkId) ?.takeUnless { it in excludedBlockchains } @@ -161,7 +177,7 @@ internal class ManagedCryptoCurrencyFactory( tokensResponse: UserTokensResponse?, imageHost: String?, userWallet: UserWallet?, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): ManagedCryptoCurrency? { if (coinResponse.networks.isEmpty() || !coinResponse.active) return null @@ -184,7 +200,12 @@ internal class ManagedCryptoCurrencyFactory( symbol = coinResponse.symbol, iconUrl = getIconUrl(coinResponse.id, imageHost), availableNetworks = availableNetworks, - addedIn = findAddedInNetworks(coinResponse.id, tokensResponse, userWallet, accountIndex), + addedIn = findAddedInNetworks( + currencyId = coinResponse.id, + tokensResponse = tokensResponse, + userWallet = userWallet, + accountIndex = accountIndex, + ), ) } @@ -194,7 +215,7 @@ internal class ManagedCryptoCurrencyFactory( decimals: Int?, userWallet: UserWallet?, extraDerivationPath: String? = null, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): SourceNetwork? { val blockchain = Blockchain.fromNetworkId(networkId) ?.takeUnless { it in excludedBlockchains } @@ -235,7 +256,7 @@ internal class ManagedCryptoCurrencyFactory( currencyId: String, tokensResponse: UserTokensResponse?, userWallet: UserWallet?, - accountIndex: DerivationIndex?, + accountIndex: DerivationIndex, ): Set { if (tokensResponse == null) return emptySet() diff --git a/data/swap/build.gradle.kts b/data/swap/build.gradle.kts index 78b5b851c7..a7ea5bd55c 100644 --- a/data/swap/build.gradle.kts +++ b/data/swap/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { /** Libs */ implementation(projects.libs.blockchainSdk) + implementation(projects.libs.crypto) /** Other */ implementation(deps.androidx.datastore) diff --git a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionConverter.kt b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionConverter.kt index c07926cd50..8895c05ffd 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionConverter.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionConverter.kt @@ -1,12 +1,16 @@ package com.tangem.data.swap.converter.transaction +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory import com.tangem.data.swap.models.SwapStatusDTO import com.tangem.data.swap.models.SwapTransactionDTO import com.tangem.data.swap.models.SwapTxTypeDTO +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.swap.models.SwapTransactionModel import com.tangem.domain.swap.models.SwapTxType +import com.tangem.lib.crypto.derivation.AccountNodeRecognizer import com.tangem.utils.converter.TwoWayConverter internal class SavedSwapTransactionConverter( @@ -48,9 +52,23 @@ internal class SavedSwapTransactionConverter( ): SwapTransactionModel { val status = txStatuses[value.txId] val refundCurrency = status?.refundTokensResponse?.let { id -> + val blockchain = Blockchain.fromNetworkId(id.networkId) ?: return@let null + val derivationPath = id.derivationPath ?: return@let null + + val accountIndex = if (blockchain == Blockchain.Chia) { + DerivationIndex.Main + } else { + val recognizer = AccountNodeRecognizer(blockchain = blockchain) + val index = recognizer.recognize(derivationPathValue = derivationPath)?.toInt() + ?: return@let null + + DerivationIndex(index).getOrNull() ?: return@let null + } + responseCryptoCurrenciesFactory.createCurrency( responseToken = id, userWallet = userWallet, + accountIndex = accountIndex, ) } val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency) diff --git a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt index 9688b3086b..051b7d9a47 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt @@ -72,7 +72,11 @@ internal class SavedSwapTransactionListConverter( return SwapTransactionListModel( transactions = value.transactions.map { tx -> - savedSwapTransactionConverter.convertBack(tx, userWallet, txStatuses) + savedSwapTransactionConverter.convertBack( + value = tx, + userWallet = userWallet, + txStatuses = txStatuses, + ) }, userWalletId = value.userWalletId, fromCryptoCurrencyId = value.fromCryptoCurrencyId, diff --git a/data/tokens/detekt-baseline-debug.xml b/data/tokens/detekt-baseline-debug.xml index 8be9ea8bd3..bc443d0652 100644 --- a/data/tokens/detekt-baseline-debug.xml +++ b/data/tokens/detekt-baseline-debug.xml @@ -3,11 +3,8 @@ MultilineLambdaItParameter:CustomTokensMerger.kt$CustomTokensMerger${ Timber.e(it, "Unable to fetch token:\n$token") null } - MultilineLambdaItParameter:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository${ it.networkId == blockchainNetworkId && compareIdWithMigrations(it, coinId) && it.derivationPath == derivationPath.value } NullableToStringCall:AccountListCryptoCurrenciesFetcher.kt$AccountListCryptoCurrenciesFetcher$${this::class.simpleName} NullableToStringCall:DefaultMultiWalletCryptoCurrenciesFetcher.kt$DefaultMultiWalletCryptoCurrenciesFetcher$${this::class.simpleName} - SuspendFunSwallowedCancellation:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository$runCatching - SuspendFunWithFlowReturnType:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository$suspend UseOrEmpty:DefaultYieldSupplyWarningsViewedRepository.kt$DefaultYieldSupplyWarningsViewedRepository$appPreferencesStore.getObjectSet<String>(PreferencesKeys.YIELD_SUPPLY_WARNINGS_STATES_KEY).firstOrNull() ?: emptySet() 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 e2988f92ce..ffb98afb6c 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 @@ -21,6 +21,7 @@ import com.tangem.domain.core.error.DataError import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.express.ExpressServiceFetcher import com.tangem.domain.express.models.ExpressAsset +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.network.Network @@ -31,6 +32,7 @@ import com.tangem.domain.tokens.model.FeePaidCurrency import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.coroutines.runSuspendCatching import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import timber.log.Timber @@ -301,8 +303,9 @@ internal class DefaultCurrenciesRepository( ) responseCryptoCurrenciesFactory.createCurrencies( - storedTokens, + response = storedTokens, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } @@ -357,15 +360,16 @@ internal class DefaultCurrenciesRepository( val coinId = blockchain.toCoinId() val storedCoin = storedTokens.tokens - .find { - it.networkId == blockchainNetworkId && - compareIdWithMigrations(it, coinId) && - it.derivationPath == derivationPath.value + .find { token -> + token.networkId == blockchainNetworkId && + compareIdWithMigrations(token, coinId) && + token.derivationPath == derivationPath.value } ?: error("Coin in this network $networkId not found") val coin = responseCryptoCurrenciesFactory.createCurrency( responseToken = storedCoin, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) coin as? CryptoCurrency.Coin ?: error("Unable to create currency") @@ -525,6 +529,7 @@ internal class DefaultCurrenciesRepository( } } + @Suppress("SuspendFunWithFlowReturnType") private suspend fun getCurrenciesForWallet( userWallet: UserWallet, currencyRawId: CryptoCurrency.RawID, @@ -539,6 +544,7 @@ internal class DefaultCurrenciesRepository( responseCryptoCurrenciesFactory.createCurrencies( response = storedTokens.copy(tokens = filterResponse), userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } } @@ -570,7 +576,7 @@ internal class DefaultCurrenciesRepository( } override suspend fun syncTokens(userWalletId: UserWalletId) { - runCatching { + runSuspendCatching { val savedCurrencies = requireNotNull( value = getSavedUserTokensResponseSync(key = userWalletId), lazyMessage = { "Saved tokens empty. Can not perform add currencies action" }, @@ -591,6 +597,7 @@ internal class DefaultCurrenciesRepository( responseCryptoCurrenciesFactory.createCurrencies( response = storedTokens, userWallet = userWallet, + accountIndex = DerivationIndex.Main, ) } } diff --git a/data/wallets/detekt-baseline-debug.xml b/data/wallets/detekt-baseline-debug.xml index 26f5591932..7ac40bc693 100644 --- a/data/wallets/detekt-baseline-debug.xml +++ b/data/wallets/detekt-baseline-debug.xml @@ -3,8 +3,6 @@ MultilineLambdaItParameter:DefaultColdMapDerivationsRepository.kt$DefaultColdMapDerivationsRepository${ networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, userWallet = userWallet, ) } - MultilineLambdaItParameter:DefaultDerivationsRepository.kt$DefaultDerivationsRepository${ userWallet.update(it.first) it.second } - MultilineLambdaItParameter:DefaultHotMapDerivationsRepository.kt$DefaultHotMapDerivationsRepository${ networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, userWallet = userWallet, ) } MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ AttemptsPersistentData( attempts = it[PreferencesKeys.getHotWalletUnlockAttemptsKey(id.attemptIdKey())] ?: 0, bootCount = it[PreferencesKeys.getHotWalletUnlockBootKey(id.attemptIdKey())] ?: 0, deadline = it[PreferencesKeys.getHotWalletUnlockDeadlineKey(id.attemptIdKey())] ?: 0L, ) } MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ it.remove(PreferencesKeys.getHotWalletUnlockAttemptsKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockAttemptsKey(noAuthAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockBootKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockBootKey(noAuthAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockDeadlineKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockDeadlineKey(noAuthAttemptId.attemptIdKey())) } MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ while (true) { emit(toState(id, it.attempts, it.deadline, it.bootCount)) val remaining = remainingSeconds(it.deadline, it.bootCount) if (remaining <= 0) break delay(timeMillis = 1000) } } @@ -16,9 +14,7 @@ SuspendFunSwallowedCancellation:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor$runCatching SuspendFunSwallowedCancellation:TangemHotWalletSigner.kt$TangemHotWalletSigner$runCatching UnnecessaryLet:MissedDerivationsFinder.kt$MissedDerivationsFinder$let(::findByNetworks) - UnusedImports:DefaultDerivationsRepository.kt$import com.tangem.common.map UseOrEmpty:DefaultColdMapDerivationsRepository.kt$DefaultColdMapDerivationsRepository$oldKeys[walletKey] ?: emptyMap() - UseOrEmpty:DefaultHotMapDerivationsRepository.kt$DefaultHotMapDerivationsRepository$oldKeys[walletKey] ?: emptyMap() VarCouldBeVal:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor$private var contextualUnlockHotWallet: ConcurrentHashMap<HotWalletId, UnlockHotWallet?> = ConcurrentHashMap() diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt index 862b90b035..3a3dcf27ac 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/derivations/DefaultDerivationsRepository.kt @@ -2,16 +2,16 @@ package com.tangem.data.wallets.derivations import com.tangem.common.CompletionResult import com.tangem.common.extensions.ByteArrayKey -import com.tangem.common.map import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.datasource.local.userwallet.UserWalletsStore -import com.tangem.domain.wallets.derivations.ColdMapDerivationsRepository -import com.tangem.domain.wallets.derivations.DerivationsRepository -import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.derivations.ColdMapDerivationsRepository +import com.tangem.domain.wallets.derivations.DerivationsRepository +import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository import com.tangem.domain.wallets.usecase.BackendId import com.tangem.operations.derivation.ExtendedPublicKeysMap import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -29,11 +29,17 @@ internal class DefaultDerivationsRepository @Inject constructor( derivePublicKeysByNetworks(userWalletId = userWalletId, networks = currencies.map(CryptoCurrency::network)) } - override suspend fun derivePublicKeysByNetworkIds(userWalletId: UserWalletId, networkIds: List) { + override suspend fun derivePublicKeysByNetworkIds( + userWalletId: UserWalletId, + networkIds: List, + accountIndex: DerivationIndex, + ) { val userWallet = userWalletsStore.getSyncStrict(userWalletId) when (userWallet) { is UserWallet.Cold -> coldDerivationsRepository.derivePublicKeysByNetworkIds(userWallet, networkIds) - is UserWallet.Hot -> hotDerivationsRepository.derivePublicKeysByNetworkIds(userWallet, networkIds) + is UserWallet.Hot -> { + hotDerivationsRepository.derivePublicKeysByNetworkIds(userWallet, networkIds, accountIndex) + } }.also { userWallet.update(it) } @@ -57,9 +63,9 @@ internal class DefaultDerivationsRepository @Inject constructor( return when (userWallet) { is UserWallet.Cold -> coldDerivationsRepository.derivePublicKeys(userWallet, derivations) is UserWallet.Hot -> hotDerivationsRepository.derivePublicKeys(userWallet, derivations) - }.let { - userWallet.update(it.first) - it.second + }.let { publicKeysMapByUserWallet -> + userWallet.update(publicKeysMapByUserWallet.first) + publicKeysMapByUserWallet.second } } diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt index aa09efcfb7..987dd65cc5 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/hot/DefaultHotMapDerivationsRepository.kt @@ -8,6 +8,7 @@ import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.data.common.network.NetworkFactory import com.tangem.data.wallets.derivations.MissedDerivationsFinder import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet @@ -38,14 +39,16 @@ internal class DefaultHotMapDerivationsRepository @Inject constructor( override suspend fun derivePublicKeysByNetworkIds( userWallet: UserWallet.Hot, networkIds: List, + accountIndex: DerivationIndex, ): UserWallet.Hot { return derivePublicKeysByNetworks( userWallet = userWallet, - networks = networkIds.mapNotNull { + networks = networkIds.mapNotNull { networkRawId -> networkFactory.create( - blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, + blockchain = Blockchain.fromNetworkId(networkRawId.value) ?: return@mapNotNull null, extraDerivationPath = null, userWallet = userWallet, + accountIndex = accountIndex, ) }, ) @@ -138,7 +141,7 @@ internal class DefaultHotMapDerivationsRepository @Inject constructor( ): Map { return (oldKeys.keys + newKeys.keys).toSet() .associateWith { walletKey -> - val oldDerivations = ExtendedPublicKeysMap(oldKeys[walletKey] ?: emptyMap()) + val oldDerivations = ExtendedPublicKeysMap(oldKeys[walletKey].orEmpty()) val newDerivations = newKeys[walletKey] ?: ExtendedPublicKeysMap(emptyMap()) ExtendedPublicKeysMap(oldDerivations + newDerivations) diff --git a/detekt_baseline_report.txt b/detekt_baseline_report.txt index 6e74d6e47d..85ca6a00e5 100644 --- a/detekt_baseline_report.txt +++ b/detekt_baseline_report.txt @@ -1,7 +1,7 @@ ========================================== Detekt Baseline Updater & Issue Counter ========================================== -Date: 2025-12-01 16:30:16 +Date: 2025-12-02 13:19:49 Step 1: Running detekt to check for new issues... @@ -17,13 +17,13 @@ Counting issues in baseline files... ========================================== Summary: - Total Issues: 1453 + Total Issues: 1435 Modules with Issues: 62 Average Issues per Module: 23 Progress: - Fixed: 349 out of 1802 (19%) - Remaining: 1453 + Fixed: 367 out of 1802 (20%) + Remaining: 1435 ========================================== All Modules with Issues (sorted by count) @@ -54,14 +54,13 @@ data/visa 22 features/yield-supply/impl 21 features/tangempay/details/impl 21 data/nft 20 -data/wallets 18 features/swap/data 15 +data/wallets 14 data/swap 13 features/token-recieve/impl 11 features/qr-scanning/impl 11 domain/account/status 11 data/onramp 11 -data/manage-tokens 11 core/datasource 11 data/markets 10 features/details/impl 9 @@ -72,22 +71,23 @@ features/referral/impl 8 domain/transaction 8 libs/tangem-sdk-api 7 data/txhistory 7 -data/tokens 7 -data/account 7 features/welcome/impl 6 -domain/markets 6 data/wallet-manager 6 libs/visa 5 features/send-v2/api 5 features/home/impl 5 +domain/markets 5 domain/legacy 5 data/transaction 5 +data/account 5 features/referral/domain 4 features/biometry/impl 4 +data/tokens 4 features/txhistory/impl 3 features/tangempay/onboarding/impl 3 features/create-wallet-start/impl 3 domain/manage-tokens 3 +data/manage-tokens 3 common/routing 3 features/account/api 2 data/promo 2 diff --git a/domain/markets/detekt-baseline-debug.xml b/domain/markets/detekt-baseline-debug.xml index ef5fed0f16..64d62630c1 100644 --- a/domain/markets/detekt-baseline-debug.xml +++ b/domain/markets/detekt-baseline-debug.xml @@ -5,7 +5,6 @@ BooleanPropertyNaming:FilterAvailableNetworksForWalletUseCase.kt$FilterAvailableNetworksForWalletUseCase$private val useNewRepository: Boolean BooleanPropertyNaming:GetStakingNotificationMaxApyUseCase.kt$GetStakingNotificationMaxApyUseCase$val showStakingNotification = if (!hideClicked && walletFirstUsageDate != 0L) { currentDate - walletFirstUsageDate > TWO_WEEKS_IN_MILLIS } else { false } MultilineLambdaItParameter:FilterAvailableNetworksForWalletUseCase.kt$FilterAvailableNetworksForWalletUseCase${ val blockchain = Blockchain.fromNetworkId(it.networkId) supportedBlockchains.contains(blockchain) } - MultilineLambdaItParameter:SaveMarketTokensUseCase.kt$SaveMarketTokensUseCase${ marketsTokenRepository.createCryptoCurrency( userWalletId = userWalletId, token = tokenMarketParams, network = it, ) } SuspendFunWithFlowReturnType:GetStakingNotificationMaxApyUseCase.kt$GetStakingNotificationMaxApyUseCase$suspend SuspendFunWithFlowReturnType:MarketsTokenRepository.kt$MarketsTokenRepository$suspend diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt index 77e9666e1e..c1d1b50552 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/SaveMarketTokensUseCase.kt @@ -2,6 +2,7 @@ package com.tangem.domain.markets import arrow.core.Either import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWalletId @@ -45,11 +46,11 @@ class SaveMarketTokensUseCase( removedNetworks: Set, ): Either = Either.catch { if (removedNetworks.isNotEmpty()) { - val removedCurrencies = removedNetworks.mapNotNull { + val removedCurrencies = removedNetworks.mapNotNull { network -> marketsTokenRepository.createCryptoCurrency( userWalletId = userWalletId, token = tokenMarketParams, - network = it, + network = network, ) } @@ -60,13 +61,15 @@ class SaveMarketTokensUseCase( derivationsRepository.derivePublicKeysByNetworkIds( userWalletId = userWalletId, networkIds = addedNetworks.map { Network.RawID(it.networkId) }, + accountIndex = DerivationIndex.Main, ) - val addedCurrencies = addedNetworks.mapNotNull { + val addedCurrencies = addedNetworks.mapNotNull { network -> marketsTokenRepository.createCryptoCurrency( userWalletId = userWalletId, token = tokenMarketParams, - network = it, + network = network, + accountIndex = DerivationIndex.Main, ) } diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt index 43b5190947..9eefdc6899 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/DerivationsRepository.kt @@ -2,6 +2,7 @@ package com.tangem.domain.wallets.derivations import com.tangem.common.extensions.ByteArrayKey import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWalletId @@ -13,7 +14,11 @@ interface DerivationsRepository { @Throws suspend fun derivePublicKeys(userWalletId: UserWalletId, currencies: List) - suspend fun derivePublicKeysByNetworkIds(userWalletId: UserWalletId, networkIds: List) + suspend fun derivePublicKeysByNetworkIds( + userWalletId: UserWalletId, + networkIds: List, + accountIndex: DerivationIndex, + ) @Throws suspend fun derivePublicKeysByNetworks(userWalletId: UserWalletId, networks: List) diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt index 65364e9a80..27b260db1d 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/derivations/HotMapDerivationsRepository.kt @@ -2,6 +2,7 @@ package com.tangem.domain.wallets.derivations import com.tangem.common.extensions.ByteArrayKey import com.tangem.crypto.hdWallet.DerivationPath +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet @@ -16,6 +17,7 @@ interface HotMapDerivationsRepository { suspend fun derivePublicKeysByNetworkIds( userWallet: UserWallet.Hot, networkIds: List, + accountIndex: DerivationIndex, ): UserWallet.Hot @Throws diff --git a/features/swap/data/build.gradle.kts b/features/swap/data/build.gradle.kts index 046da4aa6a..4efc95da23 100644 --- a/features/swap/data/build.gradle.kts +++ b/features/swap/data/build.gradle.kts @@ -37,7 +37,6 @@ dependencies { implementation(projects.domain.tokens.models) implementation(projects.domain.legacy) implementation(projects.domain.walletManager) - implementation(projects.libs.blockchainSdk) implementation(projects.domain.models) implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) @@ -45,6 +44,9 @@ dependencies { implementation(projects.domain.express.models) implementation(projects.domain.account.status) + implementation(projects.libs.blockchainSdk) + implementation(projects.libs.crypto) + /** Data */ implementation(projects.data.common) diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt index 3144aa0a95..8ec8958bd3 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt @@ -17,6 +17,7 @@ import com.tangem.feature.swap.domain.models.domain.ExchangeStatusModel import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModel import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModelInner import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionModel +import com.tangem.lib.crypto.derivation.AccountNodeRecognizer import com.tangem.utils.converter.Converter internal class SavedSwapTransactionListConverter( @@ -75,9 +76,23 @@ internal class SavedSwapTransactionListConverter( .map { tx -> val status = txStatuses[tx.txId] val refundCurrency = status?.refundTokensResponse?.let { id -> + val blockchain = Blockchain.fromNetworkId(id.networkId) ?: return@let null + val derivationPath = id.derivationPath ?: return@let null + + val accountIndex = if (blockchain == Blockchain.Chia) { + DerivationIndex.Main + } else { + val recognizer = AccountNodeRecognizer(blockchain = blockchain) + val index = recognizer.recognize(derivationPathValue = derivationPath)?.toInt() + ?: return@let null + + DerivationIndex(index).getOrNull() ?: return@let null + } + responseCryptoCurrenciesFactory.createCurrency( responseToken = id, userWallet = userWallet, + accountIndex = accountIndex, ) } val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)