Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-01 17:59:49 +03:00
parent 7fb7d4443a
commit 87f642a653
24 changed files with 81 additions and 109 deletions

View file

@ -2,8 +2,6 @@
<SmellBaseline> <SmellBaseline>
<ManuallySuppressedIssues/> <ManuallySuppressedIssues/>
<CurrentIssues> <CurrentIssues>
<ID>DoubleMutabilityForCollection:DevExcludedBlockchainsManager.kt$DevExcludedBlockchainsManager$private var blockchainTogglesMap: MutableMap&lt;String, Boolean&gt; by Delegates.notNull()</ID>
<ID>DoubleMutabilityForCollection:DevFeatureTogglesManager.kt$DevFeatureTogglesManager$private var featureTogglesMap: MutableMap&lt;String, Boolean&gt; by Delegates.notNull()</ID>
<ID>Indentation:ExcludedBlockchainToggles.kt$ExcludedBlockchainToggles$ </ID> <ID>Indentation:ExcludedBlockchainToggles.kt$ExcludedBlockchainToggles$ </ID>
<ID>Indentation:FeatureToggles.kt$FeatureToggles$ </ID> <ID>Indentation:FeatureToggles.kt$FeatureToggles$ </ID>
</CurrentIssues> </CurrentIssues>

View file

@ -21,6 +21,8 @@ internal class DevExcludedBlockchainsManager(
) : MutableExcludedBlockchainsManager { ) : MutableExcludedBlockchainsManager {
private val fileBlockchainToggles: Map<String, Boolean> = getFileBlockchainToggles() private val fileBlockchainToggles: Map<String, Boolean> = getFileBlockchainToggles()
@Suppress("DoubleMutabilityForCollection")
private var blockchainTogglesMap: MutableMap<String, Boolean> by Delegates.notNull() private var blockchainTogglesMap: MutableMap<String, Boolean> by Delegates.notNull()
override val excludedBlockchainsIds: Set<String> override val excludedBlockchainsIds: Set<String>

View file

@ -22,6 +22,8 @@ internal class DevFeatureTogglesManager(
) : MutableFeatureTogglesManager { ) : MutableFeatureTogglesManager {
private val fileFeatureTogglesMap: Map<String, Boolean> = getFileFeatureToggles() private val fileFeatureTogglesMap: Map<String, Boolean> = getFileFeatureToggles()
@Suppress("DoubleMutabilityForCollection")
private var featureTogglesMap: MutableMap<String, Boolean> by Delegates.notNull() private var featureTogglesMap: MutableMap<String, Boolean> by Delegates.notNull()
init { init {

View file

@ -115,7 +115,7 @@ internal class DefaultWalletAccountsFetcher @Inject constructor(
saveETag(userWalletId, apiResponse) saveETag(userWalletId, apiResponse)
apiResponse.bind() apiResponse.bind().enrichByAccountId()
}, },
onError = { error -> onError = { error ->
if (error.isNetworkError(code = Code.PRECONDITION_FAILED)) { if (error.isNetworkError(code = Code.PRECONDITION_FAILED)) {
@ -142,10 +142,11 @@ internal class DefaultWalletAccountsFetcher @Inject constructor(
saveETag(userWalletId, apiResponse) saveETag(userWalletId, apiResponse)
val responseBody = apiResponse.bind() val response = apiResponse.bind().enrichByAccountId()
store(userWalletId = userWalletId, response = responseBody)
FetchResult(responseBody) store(userWalletId = userWalletId, response = response)
FetchResult(response)
}, },
onError = { throwable -> onError = { throwable ->
// pushWalletAccounts and storeWalletAccounts help to avoid cyclic dependency // pushWalletAccounts and storeWalletAccounts help to avoid cyclic dependency
@ -215,6 +216,18 @@ internal class DefaultWalletAccountsFetcher @Inject constructor(
} }
} }
private fun GetWalletAccountsResponse.enrichByAccountId(): GetWalletAccountsResponse {
return copy(
accounts = accounts.map { accountDTO ->
accountDTO.copy(
tokens = accountDTO.tokens?.map { token ->
token.copy(accountId = accountDTO.id)
},
)
},
)
}
private fun getAccountsResponseStore(userWalletId: UserWalletId): AccountsResponseStore { private fun getAccountsResponseStore(userWalletId: UserWalletId): AccountsResponseStore {
return accountsResponseStoreFactory.create(userWalletId = userWalletId) return accountsResponseStoreFactory.create(userWalletId = userWalletId)
} }

View file

@ -61,7 +61,7 @@ internal class DefaultMainAccountTokensMigration(
val unassignedTokens = mainAccount.findUnassignedTokens(derivationIndex) val unassignedTokens = mainAccount.findUnassignedTokens(derivationIndex)
if (unassignedTokens == null) { if (unassignedTokens.isNullOrEmpty()) {
Timber.i("No unassigned tokens found for migration") Timber.i("No unassigned tokens found for migration")
return@either return@either
} }

View file

@ -74,6 +74,7 @@ class NetworkFactory @Inject constructor(
blockchain = blockchain, blockchain = blockchain,
excludedBlockchains = excludedBlockchains, excludedBlockchains = excludedBlockchains,
), ),
shouldCheckChia = false,
) )
} }
@ -128,9 +129,10 @@ class NetworkFactory @Inject constructor(
derivationPath: Network.DerivationPath, derivationPath: Network.DerivationPath,
canHandleTokens: Boolean, canHandleTokens: Boolean,
accountIndex: DerivationIndex? = null, accountIndex: DerivationIndex? = null,
shouldCheckChia: Boolean = true,
): Network? { ): Network? {
if (!blockchain.isBlockchainSupported()) return null if (!blockchain.isBlockchainSupported()) return null
if (blockchain == Blockchain.Chia && accountIndex != DerivationIndex.Main) return null if (shouldCheckChia && blockchain == Blockchain.Chia && accountIndex != DerivationIndex.Main) return null
return runCatching { return runCatching {
Network( Network(

View file

@ -3,7 +3,5 @@
<ManuallySuppressedIssues/> <ManuallySuppressedIssues/>
<CurrentIssues> <CurrentIssues>
<ID>BooleanPropertyNaming:DefaultFeedbackRepository.kt$DefaultFeedbackRepository$private val useNewUserWalletsRepository: Boolean</ID> <ID>BooleanPropertyNaming:DefaultFeedbackRepository.kt$DefaultFeedbackRepository$private val useNewUserWalletsRepository: Boolean</ID>
<ID>MultilineLambdaItParameter:DefaultFeedbackRepository.kt$DefaultFeedbackRepository${ it.toMutableMap().apply { put(userWallet.walletId, error) } }</ID>
<ID>UseOrEmpty:BlockchainInfoConverter.kt$BlockchainInfoConverter$value.wallet.publicKey.derivationPath?.rawPath ?: ""</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>

View file

@ -97,9 +97,9 @@ internal class DefaultFeedbackRepository(
override fun saveBlockchainErrorInfo(error: BlockchainErrorInfo) { override fun saveBlockchainErrorInfo(error: BlockchainErrorInfo) {
val userWallet = getSelectedWalletUseCase.sync().getOrNull() ?: error("UserWallet is not selected") val userWallet = getSelectedWalletUseCase.sync().getOrNull() ?: error("UserWallet is not selected")
blockchainsErrors.update { blockchainsErrors.update { map ->
it.toMutableMap().apply { map.toMutableMap().apply {
put(userWallet.walletId, error) this[userWallet.walletId] = error
} }
} }
} }

View file

@ -16,9 +16,11 @@ import com.tangem.domain.feedback.models.BlockchainInfo.Addresses as BlockchainA
internal object BlockchainInfoConverter : Converter<WalletManager, BlockchainInfo> { internal object BlockchainInfoConverter : Converter<WalletManager, BlockchainInfo> {
override fun convert(value: WalletManager): BlockchainInfo { override fun convert(value: WalletManager): BlockchainInfo {
val derivationPath = value.wallet.publicKey.derivationPath
return BlockchainInfo( return BlockchainInfo(
blockchain = value.wallet.blockchain.fullName, blockchain = value.wallet.blockchain.fullName,
derivationPath = value.wallet.publicKey.derivationPath?.rawPath ?: "", derivationPath = derivationPath?.rawPath.orEmpty(),
outputsCount = value.outputsCount?.toString(), outputsCount = value.outputsCount?.toString(),
host = value.currentHost, host = value.currentHost,
addresses = value.wallet.mapAddresses(Address::value), addresses = value.wallet.mapAddresses(Address::value),

View file

@ -2,8 +2,6 @@
<SmellBaseline> <SmellBaseline>
<ManuallySuppressedIssues/> <ManuallySuppressedIssues/>
<CurrentIssues> <CurrentIssues>
<ID>NullableBooleanCheck:DefaultPromoRepository.kt$DefaultPromoRepository$getSepaPromoBanner()?.isActive ?: false</ID>
<ID>NullableBooleanCheck:DefaultPromoRepository.kt$DefaultPromoRepository$getVisaPromoBanner()?.isActive ?: false</ID>
<ID>SuspendFunSwallowedCancellation:DefaultPromoRepository.kt$DefaultPromoRepository$runCatching</ID> <ID>SuspendFunSwallowedCancellation:DefaultPromoRepository.kt$DefaultPromoRepository$runCatching</ID>
<ID>SuspendFunWithFlowReturnType:DefaultPromoRepository.kt$DefaultPromoRepository$suspend</ID> <ID>SuspendFunWithFlowReturnType:DefaultPromoRepository.kt$DefaultPromoRepository$suspend</ID>
</CurrentIssues> </CurrentIssues>

View file

@ -1,7 +1,7 @@
========================================== ==========================================
Detekt Baseline Updater & Issue Counter Detekt Baseline Updater & Issue Counter
========================================== ==========================================
Date: 2025-11-27 14:13:20 Date: 2025-12-01 16:30:16
Step 1: Running detekt to check for new issues... Step 1: Running detekt to check for new issues...
@ -17,13 +17,13 @@ Counting issues in baseline files...
========================================== ==========================================
Summary: Summary:
Total Issues: 1593 Total Issues: 1453
Modules with Issues: 68 Modules with Issues: 62
Average Issues per Module: 23 Average Issues per Module: 23
Progress: Progress:
Fixed: 209 out of 1802 (11%) Fixed: 349 out of 1802 (19%)
Remaining: 1593 Remaining: 1453
========================================== ==========================================
All Modules with Issues (sorted by count) All Modules with Issues (sorted by count)
@ -31,28 +31,28 @@ All Modules with Issues (sorted by count)
Module Issues Module Issues
──────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────
features/wallet/impl 169 features/wallet/impl 148
features/markets/impl 155 features/markets/impl 148
features/onboarding-v2/impl 131 features/onboarding-v2/impl 130
features/send-v2/impl 80 features/swap/impl 67
features/swap/impl 73 features/send-v2/impl 57
features/hot-wallet/impl 57
features/staking/impl 56
data/wallet-connect 55 data/wallet-connect 55
features/swap-v2/impl 53 features/hot-wallet/impl 53
features/walletconnect/impl 51 features/tokendetails/impl 48
features/tokendetails/impl 49 features/staking/impl 48
features/walletconnect/impl 47
features/manage-tokens/impl 45 features/manage-tokens/impl 45
domain/wallets 39 features/swap-v2/impl 40
features/nft/impl 36 domain/wallets 37
features/nft/impl 34
features/tester/impl 31 features/tester/impl 31
domain/tokens 28 domain/tokens 28
features/swap/domain 27
core/ui 27 core/ui 27
features/yield-supply/impl 26
common/ui 26 common/ui 26
data/visa 23 features/swap/domain 25
features/tangempay/details/impl 22 data/visa 22
features/yield-supply/impl 21
features/tangempay/details/impl 21
data/nft 20 data/nft 20
data/wallets 18 data/wallets 18
features/swap/data 15 features/swap/data 15
@ -63,40 +63,34 @@ domain/account/status 11
data/onramp 11 data/onramp 11
data/manage-tokens 11 data/manage-tokens 11
core/datasource 11 core/datasource 11
features/referral/impl 10
features/details/impl 10
data/markets 10 data/markets 10
features/details/impl 9
domain/staking 9 domain/staking 9
data/yield-supply 9 data/yield-supply 9
data/networks 9 data/networks 9
features/welcome/impl 8 features/referral/impl 8
features/home/impl 8
domain/transaction 8 domain/transaction 8
libs/tangem-sdk-api 7 libs/tangem-sdk-api 7
features/onramp/impl 7
data/txhistory 7 data/txhistory 7
data/tokens 7 data/tokens 7
data/account 7 data/account 7
features/send-v2/api 6 features/welcome/impl 6
domain/markets 6 domain/markets 6
data/wallet-manager 6 data/wallet-manager 6
libs/visa 5 libs/visa 5
features/send-v2/api 5
features/home/impl 5
domain/legacy 5 domain/legacy 5
data/transaction 5 data/transaction 5
features/referral/domain 4 features/referral/domain 4
features/biometry/impl 4 features/biometry/impl 4
features/account/impl 4
features/account/api 4
data/promo 4
core/config-toggles 4
features/wallet-settings/impl 3
features/txhistory/impl 3 features/txhistory/impl 3
features/tangempay/onboarding/impl 3 features/tangempay/onboarding/impl 3
features/create-wallet-start/impl 3 features/create-wallet-start/impl 3
domain/manage-tokens 3 domain/manage-tokens 3
domain/demo/models 3
domain/card 3
data/feedback 3
common/routing 3 common/routing 3
features/yield-supply/api 2 features/account/api 2
data/promo 2
core/config-toggles 2
data/feedback 1
──────────────────────────────────────────────────────────────── ────────────────────────────────────────────────────────────────

View file

@ -1,9 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>NamedArguments:TangemCardTypesResolver.kt$TangemCardTypesResolver$Token( cardToken.name, cardToken.symbol, cardToken.contractAddress, cardToken.decimals, )</ID>
<ID>PropertyUsedBeforeDeclaration:TapWorkarounds.kt$TapWorkarounds$excludedBatches</ID>
<ID>PropertyUsedBeforeDeclaration:TapWorkarounds.kt$TapWorkarounds$excludedIssuers</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -36,15 +36,15 @@ internal class TangemCardTypesResolver(
override fun isTangemWallet(): Boolean { override fun isTangemWallet(): Boolean {
return card.settings.isBackupAllowed && card.settings.isHDWalletAllowed && return card.settings.isBackupAllowed && card.settings.isHDWalletAllowed &&
card.firmwareVersion >= FirmwareVersion.Companion.MultiWalletAvailable card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
} }
override fun isShibaWallet(): Boolean { override fun isShibaWallet(): Boolean {
return card.firmwareVersion.compareTo(FirmwareVersion.Companion.KeysImportAvailable) == 0 return card.firmwareVersion.compareTo(FirmwareVersion.KeysImportAvailable) == 0
} }
override fun isWhiteWallet(): Boolean { override fun isWhiteWallet(): Boolean {
return walletData == null && card.firmwareVersion <= FirmwareVersion.Companion.HDWalletAvailable return walletData == null && card.firmwareVersion <= FirmwareVersion.HDWalletAvailable
} }
override fun isWallet2(): Boolean = card.isWallet2 override fun isWallet2(): Boolean = card.isWallet2
@ -73,7 +73,7 @@ internal class TangemCardTypesResolver(
(multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1) (multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
} }
private fun multiWalletAvailable() = card.firmwareVersion >= FirmwareVersion.Companion.MultiWalletAvailable private fun multiWalletAvailable() = card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
override fun getBlockchain(): Blockchain { override fun getBlockchain(): Blockchain {
return when (productType) { return when (productType) {
@ -93,13 +93,16 @@ internal class TangemCardTypesResolver(
override fun getPrimaryToken(): Token? { override fun getPrimaryToken(): Token? {
val cardToken = walletData?.token ?: return null val cardToken = walletData?.token ?: return null
return Token(
cardToken.name, return with(cardToken) {
cardToken.symbol, Token(
cardToken.contractAddress, name = name,
cardToken.decimals, symbol = symbol,
contractAddress = contractAddress,
decimals = decimals,
) )
} }
}
override fun isReleaseFirmwareType(): Boolean = card.firmwareVersion.type == FirmwareVersion.FirmwareType.Release override fun isReleaseFirmwareType(): Boolean = card.firmwareVersion.type == FirmwareVersion.FirmwareType.Release

View file

@ -38,6 +38,7 @@ object TapWorkarounds {
val CardDTO.hasOldStyleDerivation: Boolean val CardDTO.hasOldStyleDerivation: Boolean
get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95" get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95"
@Suppress("PropertyUsedBeforeDeclaration")
val CardDTO.isExcluded: Boolean val CardDTO.isExcluded: Boolean
get() { get() {
val isBatchExcluded = excludedBatches.contains(batchId) val isBatchExcluded = excludedBatches.contains(batchId)

View file

@ -1,9 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$debugTestDemoCardIds</ID>
<ID>PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$releaseDemoCardIds</ID>
<ID>PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$testDemoCardIds</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -4,7 +4,7 @@ import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import java.math.BigDecimal import java.math.BigDecimal
@Suppress("LargeClass") @Suppress("LargeClass", "ClassOrdering", "PropertyUsedBeforeDeclaration")
object DemoConfig { object DemoConfig {
/** /**
@ -65,7 +65,6 @@ object DemoConfig {
return (releaseDemoCardIds + testDemoCardIds).distinct() return (releaseDemoCardIds + testDemoCardIds).distinct()
} }
@Suppress("ClassOrdering")
private val releaseDemoCardIds = mutableListOf( private val releaseDemoCardIds = mutableListOf(
// === Not from the Google Sheet table === // === Not from the Google Sheet table ===
"AC01000000041225", "AC01000000041225",
@ -449,7 +448,6 @@ object DemoConfig {
"AF10100000000084", "AF10100000000084",
) )
@Suppress("ClassOrdering")
private val testDemoCardIds = listOf( private val testDemoCardIds = listOf(
"FB20000000000186", // Note ETH "FB20000000000186", // Note ETH
"FB10000000000196", // Note BTC "FB10000000000196", // Note BTC
@ -457,6 +455,5 @@ object DemoConfig {
"FB04000000000152", // Wallet 2 "FB04000000000152", // Wallet 2
) )
@Suppress("ClassOrdering")
private val debugTestDemoCardIds = emptyList<String>() private val debugTestDemoCardIds = emptyList<String>()
} }

View file

@ -25,8 +25,6 @@
<ID>NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$tryGetFromCacheV2(userWallet, initialCryptoCurrency, state, isReverseFromTo)</ID> <ID>NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$tryGetFromCacheV2(userWallet, initialCryptoCurrency, state, isReverseFromTo)</ID>
<ID>NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl$account</ID> <ID>NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl$account</ID>
<ID>NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl${ it.isAvailable }</ID> <ID>NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl${ it.isAvailable }</ID>
<ID>NonBooleanPropertyPrefixedWithIs:SwapInteractorImpl.kt$SwapInteractorImpl$private val isDemoCardUseCase: IsDemoCardUseCase</ID>
<ID>NullableToStringCall:SwapInteractorImpl.kt$SwapInteractorImpl$$swapData</ID>
<ID>NullableToStringCall:SwapInteractorImpl.kt$SwapInteractorImpl$${e.message}</ID> <ID>NullableToStringCall:SwapInteractorImpl.kt$SwapInteractorImpl$${e.message}</ID>
<ID>SuspendFunSwallowedCancellation:SwapInteractorImpl.kt$SwapInteractorImpl$runCatching</ID> <ID>SuspendFunSwallowedCancellation:SwapInteractorImpl.kt$SwapInteractorImpl$runCatching</ID>
</CurrentIssues> </CurrentIssues>

View file

@ -48,8 +48,6 @@
<ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ uiState = stateBuilder.dismissBottomSheet(uiState) dataState = dataState.copy(selectedFee = it) modelScope.launch(dispatchers.io) { startLoadingQuotesFromLastState(false) } }</ID> <ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ uiState = stateBuilder.dismissBottomSheet(uiState) dataState = dataState.copy(selectedFee = it) modelScope.launch(dispatchers.io) { startLoadingQuotesFromLastState(false) } }</ID>
<ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val balance = swapInteractor.getTokenBalance(it) onAmountChanged(balance.formatToUIRepresentation()) }</ID> <ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val balance = swapInteractor.getTokenBalance(it) onAmountChanged(balance.formatToUIRepresentation()) }</ID>
<ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val provider = findAndSelectProvider(it) val swapState = dataState.lastLoadedSwapStates[provider] val fromToken = dataState.fromCryptoCurrency if (provider != null &amp;&amp; swapState != null &amp;&amp; fromToken != null) { analyticsEventHandler.send(SwapEvents.ProviderChosen(provider)) uiState = stateBuilder.dismissBottomSheet(uiState) setupLoadedState( provider = provider, state = swapState, fromToken = fromToken, ) } }</ID> <ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val provider = findAndSelectProvider(it) val swapState = dataState.lastLoadedSwapStates[provider] val fromToken = dataState.fromCryptoCurrency if (provider != null &amp;&amp; swapState != null &amp;&amp; fromToken != null) { analyticsEventHandler.send(SwapEvents.ProviderChosen(provider)) uiState = stateBuilder.dismissBottomSheet(uiState) setupLoadedState( provider = provider, state = swapState, fromToken = fromToken, ) } }</ID>
<ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ when (it) { is SwapTransactionState.TxSent -&gt; { sendApproveSuccessEvent(fromToken, feeForPermission.feeType, approveType) updateWalletBalance() uiState = stateBuilder.loadingPermissionState(uiState) uiState = stateBuilder.dismissBottomSheet(uiState) startLoadingQuotesFromLastState(isSilent = true) } is SwapTransactionState.Error -&gt; { uiState = stateBuilder.createErrorTransactionAlert( uiState = uiState, error = it, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, onSupportClick = ::onFailedTxEmailClick, isReverseSwapPossible = isReverseSwapPossible(), ) } SwapTransactionState.DemoMode -&gt; { uiState = stateBuilder.createDemoModeAlert( uiState = uiState, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, isReverseSwapPossible = isReverseSwapPossible(), ) } } }</ID>
<ID>MultilineLambdaItParameter:SwapModel.kt$SwapModel${ when (it) { is SwapTransactionState.TxSent -&gt; { sendSuccessSwapEvent(fromCurrency.currency, fee.feeType) val url = getExplorerTransactionUrlUseCase( txHash = it.txHash, networkId = fromCurrency.currency.network.id, ).getOrElse { Timber.i("tx hash explore not supported") "" } updateWalletBalance() uiState = stateBuilder.createSuccessState( uiState = uiState, swapTransactionState = it, dataState = dataState, txUrl = url, onExploreClick = { if (it.txHash.isNotEmpty()) { urlOpener.openUrl(url) } analyticsEventHandler.send( event = SwapEvents.ButtonExplore(initialCurrencyFrom.symbol), ) }, onStatusClick = { val txExternalUrl = it.txExternalUrl if (!txExternalUrl.isNullOrBlank()) { urlOpener.openUrl(txExternalUrl) analyticsEventHandler.send( event = SwapEvents.ButtonStatus(initialCurrencyFrom.symbol), ) } }, ) sendSuccessEvent() swapRouter.openScreen(SwapNavScreen.Success) } SwapTransactionState.DemoMode -&gt; { uiState = stateBuilder.createDemoModeAlert( uiState = uiState, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, isReverseSwapPossible = isReverseSwapPossible(), ) } is SwapTransactionState.Error -&gt; { startLoadingQuotesFromLastState() uiState = stateBuilder.createErrorTransactionAlert( uiState = uiState, error = it, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, onSupportClick = ::onFailedTxEmailClick, isReverseSwapPossible = isReverseSwapPossible(), ) } } }</ID>
<ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, ) }</ID> <ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, ) }</ID>
<ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier .align(Alignment.CenterVertically) .testTag(SwapTokenScreenTestTags.BALANCE), ) }</ID> <ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier .align(Alignment.CenterVertically) .testTag(SwapTokenScreenTestTags.BALANCE), ) }</ID>
<ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size20), ) }</ID> <ID>MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size20), ) }</ID>

View file

@ -77,7 +77,7 @@ internal class DefaultTokenDetailsComponent @AssistedInject constructor(
params = YieldSupplyComponent.Params( params = YieldSupplyComponent.Params(
userWalletId = params.userWalletId, userWalletId = params.userWalletId,
cryptoCurrency = params.currency, cryptoCurrency = params.currency,
handleNavigation = (params.navigationAction as? NavigationAction.YieldSupply) shouldHandleNavigation = (params.navigationAction as? NavigationAction.YieldSupply)
?.isActive, ?.isActive,
), ),
) )

View file

@ -5,7 +5,6 @@
<ID>BooleanPropertyNaming:DefaultUserWalletsFetcher.kt$DefaultUserWalletsFetcher$@Assisted("onlyMultiCurrency") private val onlyMultiCurrency: Boolean</ID> <ID>BooleanPropertyNaming:DefaultUserWalletsFetcher.kt$DefaultUserWalletsFetcher$@Assisted("onlyMultiCurrency") private val onlyMultiCurrency: Boolean</ID>
<ID>BooleanPropertyNaming:DraggableItem.kt$DraggableItem$abstract val showShadow: Boolean</ID> <ID>BooleanPropertyNaming:DraggableItem.kt$DraggableItem$abstract val showShadow: Boolean</ID>
<ID>BooleanPropertyNaming:DraggableItem.kt$DraggableItem.RoundingMode$abstract val showGap: Boolean</ID> <ID>BooleanPropertyNaming:DraggableItem.kt$DraggableItem.RoundingMode$abstract val showGap: Boolean</ID>
<ID>BooleanPropertyNaming:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$val accessCodeSkipped = array[7] as Boolean</ID>
<ID>BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private var readyForRateAppNotification = false</ID> <ID>BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private var readyForRateAppNotification = false</ID>
<ID>BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$val userHasWalletOrWallet2 = userWallets.filterIsInstance&lt;UserWallet.Cold&gt;().any { val typesResolver = it.scanResponse.cardTypesResolver typesResolver.isTangemWallet() || typesResolver.isWallet2() }</ID> <ID>BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$val userHasWalletOrWallet2 = userWallets.filterIsInstance&lt;UserWallet.Cold&gt;().any { val typesResolver = it.scanResponse.cardTypesResolver typesResolver.isTangemWallet() || typesResolver.isWallet2() }</ID>
<ID>BooleanPropertyNaming:OrganizeTokensState.kt$OrganizeTokensState.ActionsConfig$val showApplyProgress: Boolean = false</ID> <ID>BooleanPropertyNaming:OrganizeTokensState.kt$OrganizeTokensState.ActionsConfig$val showApplyProgress: Boolean = false</ID>
@ -78,7 +77,6 @@
<ID>MultilineLambdaItParameter:WalletModel.kt$WalletModel${ walletsUpdateActionResolver.resolve( wallets = it, currentState = stateHolder.value, ) }</ID> <ID>MultilineLambdaItParameter:WalletModel.kt$WalletModel${ walletsUpdateActionResolver.resolve( wallets = it, currentState = stateHolder.value, ) }</ID>
<ID>MultilineLambdaItParameter:WalletNFTListSubscriber.kt$WalletNFTListSubscriber${ stateHolder.update( SetNFTCollectionsTransformer( userWalletId = userWallet.walletId, nftCollections = it, onItemClick = { clickIntents.onNFTClick(userWallet) }, ), ) }</ID> <ID>MultilineLambdaItParameter:WalletNFTListSubscriber.kt$WalletNFTListSubscriber${ stateHolder.update( SetNFTCollectionsTransformer( userWalletId = userWallet.walletId, nftCollections = it, onItemClick = { clickIntents.onNFTClick(userWallet) }, ), ) }</ID>
<ID>MultilineLambdaItParameter:WalletNameMigrationUseCase.kt$WalletNameMigrationUseCase${ val defaultName = it.name val suggestedWalletName = suggestedWalletName(defaultName, existingNames) if (defaultName != suggestedWalletName) { userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true) } Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName) }</ID> <ID>MultilineLambdaItParameter:WalletNameMigrationUseCase.kt$WalletNameMigrationUseCase${ val defaultName = it.name val suggestedWalletName = suggestedWalletName(defaultName, existingNames) if (defaultName != suggestedWalletName) { userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true) } Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName) }</ID>
<ID>MultilineLambdaItParameter:WalletNotifications.kt${ // TODO develop promo banner general component when (it) { is WalletNotification.SwapPromo -&gt; { // Use it on new promo action } is WalletNotification.NoteMigration -&gt; { NoteMigrationNotification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), ) } is WalletNotification.FinishWalletActivation -&gt; { Notification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), ) } else -&gt; { Notification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), iconTint = when (it) { is WalletNotification.Critical -&gt; TangemTheme.colors.icon.warning is WalletNotification.Informational -&gt; TangemTheme.colors.icon.accent is WalletNotification.RateApp -&gt; TangemTheme.colors.icon.attention is WalletNotification.UnlockWallets -&gt; TangemTheme.colors.icon.primary1 is WalletNotification.UsedOutdatedData -&gt; TangemTheme.colors.text.attention else -&gt; null }, ) } } }</ID>
<ID>MultilineLambdaItParameter:WalletScreen.kt${ PaddingValues( bottom = it.calculateBottomPadding() + marketHintAproxHeight + 52.dp, ) }</ID> <ID>MultilineLambdaItParameter:WalletScreen.kt${ PaddingValues( bottom = it.calculateBottomPadding() + marketHintAproxHeight + 52.dp, ) }</ID>
<ID>MultilineLambdaItParameter:WalletScreen.kt${ WalletSnackbarHost( snackbarHostState = it, event = state.event, modifier = Modifier .padding(bottom = TangemTheme.dimens.spacing4) .navigationBarsPadding(), ) }</ID> <ID>MultilineLambdaItParameter:WalletScreen.kt${ WalletSnackbarHost( snackbarHostState = it, event = state.event, modifier = Modifier .padding(bottom = TangemTheme.dimens.spacing4) .navigationBarsPadding(), ) }</ID>
<ID>MultilineLambdaItParameter:WalletScreen.kt${ balancesAndLimitsBlock( modifier = itemModifier, state = it.balancesAndLimitBlockState, ) }</ID> <ID>MultilineLambdaItParameter:WalletScreen.kt${ balancesAndLimitsBlock( modifier = itemModifier, state = it.balancesAndLimitBlockState, ) }</ID>
@ -91,7 +89,6 @@
<ID>MultilineLambdaItParameter:WalletWithFundsChecker.kt$WalletWithFundsChecker${ val amount = it.value.amount ?: return@any false !amount.isZero() }</ID> <ID>MultilineLambdaItParameter:WalletWithFundsChecker.kt$WalletWithFundsChecker${ val amount = it.value.amount ?: return@any false !amount.isZero() }</ID>
<ID>MultilineLambdaItParameter:WalletsUpdateActionResolver.kt$WalletsUpdateActionResolver${ if (it.warnings.any { it is WalletNotification.FinishWalletActivation }) { it.walletCardState.id } else { null } }</ID> <ID>MultilineLambdaItParameter:WalletsUpdateActionResolver.kt$WalletsUpdateActionResolver${ if (it.warnings.any { it is WalletNotification.FinishWalletActivation }) { it.walletCardState.id } else { null } }</ID>
<ID>NamedArguments:BasicAccountListSubscriber.kt$BasicAccountListSubscriber$updateContent(convertParams, appCurrency, yieldSupplyApyMap, stakingApyMap)</ID> <ID>NamedArguments:BasicAccountListSubscriber.kt$BasicAccountListSubscriber$updateContent(convertParams, appCurrency, yieldSupplyApyMap, stakingApyMap)</ID>
<ID>NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addFinishWalletActivationNotification(userWallet, totalFiatBalance, clickIntents, accessCodeSkipped)</ID>
<ID>NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addInformationalNotifications(userWallet, cardTypesResolver, flattenCurrencies, clickIntents)</ID> <ID>NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addInformationalNotifications(userWallet, cardTypesResolver, flattenCurrencies, clickIntents)</ID>
<ID>NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addWarningNotifications(cardTypesResolver, flattenCurrencies, isNeedToBackup, clickIntents)</ID> <ID>NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addWarningNotifications(cardTypesResolver, flattenCurrencies, isNeedToBackup, clickIntents)</ID>
<ID>NamedArguments:TangemSnapFlingBehavior.kt$HighVelocityApproachAnimation$animateDecay(offset, animationState, decayAnimationSpec, onAnimationStep)</ID> <ID>NamedArguments:TangemSnapFlingBehavior.kt$HighVelocityApproachAnimation$animateDecay(offset, animationState, decayAnimationSpec, onAnimationStep)</ID>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>BooleanPropertyNaming:YieldSupplyComponent.kt$YieldSupplyComponent.Params$val handleNavigation: Boolean? = null</ID>
<ID>UseEmptyCounterpart:YieldSupplyAnalytics.kt$YieldSupplyAnalytics$mapOf()</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -10,7 +10,7 @@ interface YieldSupplyComponent : ComposableContentComponent {
data class Params( data class Params(
val userWalletId: UserWalletId, val userWalletId: UserWalletId,
val cryptoCurrency: CryptoCurrency, val cryptoCurrency: CryptoCurrency,
val handleNavigation: Boolean? = null, val shouldHandleNavigation: Boolean? = null,
) )
interface Factory : ComponentFactory<Params, YieldSupplyComponent> interface Factory : ComponentFactory<Params, YieldSupplyComponent>

View file

@ -8,7 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
sealed class YieldSupplyAnalytics( sealed class YieldSupplyAnalytics(
event: String, event: String,
params: Map<String, String> = mapOf(), params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category = "Earning", event = event, params = params) { ) : AnalyticsEvent(category = "Earning", event = event, params = params) {
data class EarningScreenInfoOpened( data class EarningScreenInfoOpened(

View file

@ -24,11 +24,7 @@ import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.yield.supply.YieldSupplyRepository import com.tangem.domain.yield.supply.YieldSupplyRepository
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
import com.tangem.domain.yield.supply.usecase.YieldSupplyActivateUseCase import com.tangem.domain.yield.supply.usecase.*
import com.tangem.domain.yield.supply.usecase.YieldSupplyDeactivateUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyIsAvailableUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyMinAmountUseCase
import com.tangem.features.yield.supply.api.YieldSupplyComponent import com.tangem.features.yield.supply.api.YieldSupplyComponent
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
import com.tangem.features.yield.supply.impl.R import com.tangem.features.yield.supply.impl.R
@ -274,8 +270,7 @@ internal class YieldSupplyModel @Inject constructor(
private fun loadActiveState(cryptoCurrencyStatus: CryptoCurrencyStatus, yieldSupplyStatus: YieldSupplyStatus) { private fun loadActiveState(cryptoCurrencyStatus: CryptoCurrencyStatus, yieldSupplyStatus: YieldSupplyStatus) {
val cryptoCurrencyToken = cryptoCurrency as? CryptoCurrency.Token ?: return val cryptoCurrencyToken = cryptoCurrency as? CryptoCurrency.Token ?: return
val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend
val state = uiState.value val isShowInfoIconPrevState = when (val state = uiState.value) {
val isShowInfoIconPrevState = when (state) {
is YieldSupplyUM.Content -> state.showInfoIcon is YieldSupplyUM.Content -> state.showInfoIcon
else -> false else -> false
} }