Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-29 12:25:21 +04:00
parent 48137d6199
commit f18ec7ac86
18 changed files with 148 additions and 178 deletions

View file

@ -86,7 +86,7 @@ internal class DefaultTangemSdkManager(
secureStorage = tangemSdk.secureStorage, secureStorage = tangemSdk.secureStorage,
) )
} }
override val needEnrollBiometrics: Boolean override val isEnrollBiometricsNeeded: Boolean
get() { get() {
val isNeedEnrollBiometrics = tangemSdk.authenticationManager.needEnrollBiometrics val isNeedEnrollBiometrics = tangemSdk.authenticationManager.needEnrollBiometrics
if (isNeedEnrollBiometrics) { if (isNeedEnrollBiometrics) {
@ -102,7 +102,7 @@ internal class DefaultTangemSdkManager(
override val canUseBiometry: Boolean override val canUseBiometry: Boolean
get() { get() {
val isCanUseBiometry = tangemSdk.authenticationManager.canAuthenticate || needEnrollBiometrics val isCanUseBiometry = tangemSdk.authenticationManager.canAuthenticate || isEnrollBiometricsNeeded
if (!isCanUseBiometry) { if (!isCanUseBiometry) {
analyticsErrorHandler.sendErrorEvent( analyticsErrorHandler.sendErrorEvent(
AnalyticsEvent( AnalyticsEvent(
@ -124,7 +124,7 @@ internal class DefaultTangemSdkManager(
get() = tangemSdk.config.userCodeRequestPolicy get() = tangemSdk.config.userCodeRequestPolicy
override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean { override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean {
return needEnrollBiometrics return isEnrollBiometricsNeeded
} }
override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean { override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean {

View file

@ -46,7 +46,7 @@ class MockTangemSdkManager(
override val canUseBiometry: Boolean = false override val canUseBiometry: Boolean = false
override val needEnrollBiometrics: Boolean = false override val isEnrollBiometricsNeeded: Boolean = false
override val keystoreManager = DummyKeystoreManager() override val keystoreManager = DummyKeystoreManager()
@ -57,7 +57,7 @@ class MockTangemSdkManager(
override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean = canUseBiometry override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean = canUseBiometry
override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean = needEnrollBiometrics override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean = isEnrollBiometricsNeeded
override suspend fun scanProduct( override suspend fun scanProduct(
cardId: String?, cardId: String?,

View file

@ -115,7 +115,7 @@ internal class AppSettingsModel @Inject constructor(
private fun observeBiometricsStatusChanges() { private fun observeBiometricsStatusChanges() {
flow { flow {
do { do {
val isEnrollBiometricsNeeded = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() val isEnrollBiometricsNeeded = runCatching(tangemSdkManager::isEnrollBiometricsNeeded).getOrNull()
if (isEnrollBiometricsNeeded != null) { if (isEnrollBiometricsNeeded != null) {
emit(isEnrollBiometricsNeeded) emit(isEnrollBiometricsNeeded)
} }
@ -366,7 +366,7 @@ internal class AppSettingsModel @Inject constructor(
localState.update { state -> localState.update { state ->
state.copy( state.copy(
hasSecuredWallets = userWalletsListRepository.hasSecuredWallets(), hasSecuredWallets = userWalletsListRepository.hasSecuredWallets(),
isEnrollBiometricsNeeded = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() == true, isEnrollBiometricsNeeded = runCatching(tangemSdkManager::isEnrollBiometricsNeeded).getOrNull() == true,
isBiometricAuthenticationUsed = walletsRepository.useBiometricAuthentication(), isBiometricAuthenticationUsed = walletsRepository.useBiometricAuthentication(),
isAccessCodeRequired = walletsRepository.requireAccessCode(), isAccessCodeRequired = walletsRepository.requireAccessCode(),
) )

View file

@ -32,7 +32,7 @@ internal class VisaLibLoader @Inject constructor(
val config = getOrLoadConfig() val config = getOrLoadConfig()
provider = VisaContractInfoProvider.Builder( provider = VisaContractInfoProvider.Builder(
useTestnetRpc = VisaConstants.USE_TEST_ENV, isTestnetRpcEnabled = VisaConstants.USE_TEST_ENV,
bridgeProcessorAddress = if (VisaConstants.USE_TEST_ENV) { bridgeProcessorAddress = if (VisaConstants.USE_TEST_ENV) {
config.testnet.bridgeProcessor config.testnet.bridgeProcessor
} else { } else {

View file

@ -5,16 +5,16 @@ plugins {
} }
dependencies { dependencies {
/** Project - Core */
implementation(projects.core.analytics.models)
/** Project - Domain */ // region Kotlin
implementation(projects.domain.models) api(deps.kotlin.serialization.core)
implementation(projects.domain.txhistory.models) // endregion
implementation(projects.domain.staking.models)
implementation(projects.domain.stories.models)
/** Other dependencies */ // region Core modules
implementation(deps.kotlin.serialization) api(projects.core.analytics.models)
implementation(deps.jodatime) // endregion
// region Domain models
api(projects.domain.models)
// endregion
} }

View file

@ -19,10 +19,13 @@ huaweiPush = "6.11.0.300"
# endregion AppGallery # endregion AppGallery
# region AndroidX # region AndroidX
androidxActivity = "1.10.1"
androidxActivityCompose = "1.8.0" androidxActivityCompose = "1.8.0"
androidxAnnotation = "1.9.1"
androidxAppCompat = "1.5.1" androidxAppCompat = "1.5.1"
androidxBrowser = "1.4.0" androidxBrowser = "1.4.0"
androidxConstraintLayout = "2.2.1" androidxConstraintLayout = "2.2.1"
androidxCore = "1.13.1"
androidxKtx = "1.9.0" androidxKtx = "1.9.0"
androidxSplashScreen = "1.0.1" androidxSplashScreen = "1.0.1"
androidxFragment = "1.8.5" androidxFragment = "1.8.5"
@ -152,10 +155,13 @@ gradle-kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinp
# end region Classpath # end region Classpath
# region AndroidX # region AndroidX
androidx-activity = { module = "androidx.activity:activity", version.ref = "androidxActivity" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" }
androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidxAnnotation" }
androidx-appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidxAppCompat" } androidx-appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidxAppCompat" }
androidx-browser = { module = "androidx.browser:browser", version.ref = "androidxBrowser" } androidx-browser = { module = "androidx.browser:browser", version.ref = "androidxBrowser" }
androidx-constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidxConstraintLayout" } androidx-constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidxConstraintLayout" }
androidx-core = { module = "androidx.core:core", version.ref = "androidxCore" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxKtx" } androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxKtx" }
androidx-core-splashScreen = { module = "androidx.core:core-splashscreen", version.ref = "androidxSplashScreen" } androidx-core-splashScreen = { module = "androidx.core:core-splashscreen", version.ref = "androidxSplashScreen" }
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidxFragment" } androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidxFragment" }
@ -284,6 +290,7 @@ viewBindingDelegate = { module = "com.github.kirich1409:viewbindingpropertydeleg
xmlShimmer = { module = "com.github.skydoves:androidveil", version.ref = "xmlShimmer" } xmlShimmer = { module = "com.github.skydoves:androidveil", version.ref = "xmlShimmer" }
zxing-qrCore = { module = "com.google.zxing:core", version.ref = "zxingQrCode" } zxing-qrCore = { module = "com.google.zxing:core", version.ref = "zxingQrCode" }
kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinSerialization" } kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinSerialization" }
kotlin-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinSerialization" }
kotlin-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinDatetime" } kotlin-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinDatetime" }
arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" } arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" }
arrow-fx = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" } arrow-fx = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" }

View file

@ -8,32 +8,50 @@ plugins {
} }
android { android {
namespace = "com.tangem.lib.auth" namespace = "com.tangem.libs.auth"
} }
dependencies { dependencies {
/** Core */
// region DI
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
// endregion
// region Kotlin
api(deps.kotlin.datetime)
api(deps.kotlin.serialization)
implementation(deps.kotlin.coroutines)
// endregion
// region Other libraries
api(deps.arrow.core)
api(deps.okHttp)
implementation(deps.moshi)
implementation(deps.retrofit)
// endregion
// region Firebase
implementation(platform(deps.firebase.bom))
implementation(deps.firebase.crashlytics)
// endregion
// region Tangem
implementation(tangemDeps.card.android)
implementation(tangemDeps.card.core)
// endregion
// region Core modules
implementation(projects.core.configToggles) implementation(projects.core.configToggles)
implementation(projects.core.datasource) implementation(projects.core.datasource)
implementation(projects.core.utils) implementation(projects.core.utils)
// endregion
/** Tangem libraries */ // region Tests
implementation(tangemDeps.card.core) testImplementation(deps.androidx.datastore)
implementation(tangemDeps.card.android)
/** Firebase */
implementation(platform(deps.firebase.bom))
implementation(deps.firebase.crashlytics)
/** Other */
implementation(deps.arrow.core)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
/** Tests */
testImplementation(deps.test.junit5)
testImplementation(deps.test.coroutine) testImplementation(deps.test.coroutine)
testImplementation(deps.test.truth) testImplementation(deps.test.junit5)
testImplementation(deps.test.mockk) testImplementation(deps.test.mockk)
testImplementation(deps.test.truth)
// endregion
} }

View file

@ -15,45 +15,53 @@ android {
dependencies { dependencies {
// region Core modules // region DI
implementation(projects.core.datasource)
implementation(projects.core.configToggles)
implementation(projects.core.utils)
implementation(projects.core.analytics)
// endregion
api(projects.domain.models)
// region AndroidX libraries
implementation(deps.androidx.datastore)
// endregion
// region DI libraries
implementation(deps.hilt.android) implementation(deps.hilt.android)
kapt(deps.hilt.kapt) kapt(deps.hilt.kapt)
// endregion // endregion
// region Kotlin
api(deps.kotlin.coroutines)
// endregion
// region AndroidX
implementation(deps.androidx.core)
implementation(deps.androidx.datastore)
// endregion
// region Other libraries // region Other libraries
implementation(deps.kotlin.coroutines)
implementation(deps.moshi) implementation(deps.moshi)
implementation(deps.moshi.kotlin)
ksp(deps.moshi.kotlin.codegen) ksp(deps.moshi.kotlin.codegen)
kaptForObfuscatingVariants(deps.retrofit.response.type.keeper) kaptForObfuscatingVariants(deps.retrofit.response.type.keeper)
// endregion // endregion
// region Firebase libraries // region Firebase
implementation(platform(deps.firebase.bom)) implementation(platform(deps.firebase.bom))
implementation(deps.firebase.analytics) implementation(deps.firebase.analytics)
implementation(deps.firebase.crashlytics) implementation(deps.firebase.crashlytics)
// endregion // endregion
// region Tangem libraries // region Tangem
implementation(tangemDeps.blockchain) { exclude(module = "joda-time") } api(tangemDeps.blockchain) { exclude(module = "joda-time") }
implementation(tangemDeps.card.core) implementation(tangemDeps.card.core)
// endregion // endregion
// region Core modules
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
api(projects.core.configToggles)
api(projects.core.datasource)
implementation(projects.core.utils)
// endregion
// region Domain models
api(projects.domain.models)
// endregion
// region Tests
testImplementation(deps.test.coroutine) testImplementation(deps.test.coroutine)
testImplementation(deps.test.junit5) testImplementation(deps.test.junit5)
testImplementation(deps.test.mockk) testImplementation(deps.test.mockk)
testImplementation(deps.test.truth) testImplementation(deps.test.truth)
// endregion
} }

View file

@ -1,28 +1,24 @@
plugins { plugins {
alias(deps.plugins.android.library) alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android) alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.kotlin.serialization)
id("configuration") id("configuration")
} }
android { android {
namespace = "com.tangem.lib.crypto" namespace = "com.tangem.libs.crypto"
} }
dependencies { dependencies {
// region Tangem SDKs
api(tangemDeps.blockchain)
api(tangemDeps.card.core)
// endregion
// region Project // region Project
implementation(projects.core.utils) implementation(projects.core.utils)
implementation(projects.libs.blockchainSdk) api(projects.domain.models)
// endregion api(projects.libs.blockchainSdk)
// region Tangem SDKs
implementation(tangemDeps.card.core)
implementation(tangemDeps.blockchain)
// endregion
// region Other deps
implementation(deps.kotlin.coroutines)
// endregion // endregion
// region Test libraries // region Test libraries

View file

@ -7,24 +7,39 @@ plugins {
} }
android { android {
namespace = "com.tangem.legacy" namespace = "com.tangem.libs.tangem_sdk_api"
} }
dependencies { dependencies {
implementation(projects.domain.models)
implementation(projects.domain.visa.models)
api(projects.core.analytics.models) // region DI
implementation(projects.core.configToggles) implementation(deps.hilt.android)
implementation(projects.core.res) kapt(deps.hilt.kapt)
// endregion
/** Tangem libraries */ // region AndroidX
implementation(tangemDeps.card.core) api(deps.androidx.activity)
api(deps.androidx.annotation)
// endregion
// region Other libraries
api(deps.arrow.core)
// endregion
// region Tangem
api(tangemDeps.card.core)
implementation(tangemDeps.card.android) { implementation(tangemDeps.card.android) {
exclude(module = "joda-time") exclude(module = "joda-time")
} }
// endregion
/** DI */ // region Core modules
implementation(deps.hilt.android) api(projects.core.analytics.models)
kapt(deps.hilt.kapt) implementation(projects.core.configToggles)
// endregion
// region Domain models
api(projects.domain.models)
api(projects.domain.visa.models)
// endregion
} }

View file

@ -1,13 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>BooleanPropertyNaming:TangemSdkManager.kt$TangemSdkManager$val needEnrollBiometrics: Boolean</ID>
<ID>ObjectExtendsThrowable:TapErrors.kt$TapError$NoInternetConnection : TapError</ID>
<ID>ObjectExtendsThrowable:TapErrors.kt$TapError$UnknownError : TapError</ID>
<ID>ObjectExtendsThrowable:TapErrors.kt$TapError.WalletManager$BlockchainIsUnreachableTryLater : TapError</ID>
<ID>ObjectExtendsThrowable:TapErrors.kt$TapSdkError$CardForDifferentApp : TapSdkError</ID>
<ID>ObjectExtendsThrowable:TapErrors.kt$TapSdkError$CardNotSupportedByRelease : TapSdkError</ID>
<ID>UseEmptyCounterpart:CreateProductWalletTaskResponse.kt$CreateProductWalletTaskResponse$mapOf()</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -9,12 +9,12 @@ import com.tangem.operations.derivation.ExtendedPublicKeysMap
data class CreateProductWalletTaskResponse( data class CreateProductWalletTaskResponse(
val card: CardDTO, val card: CardDTO,
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(), val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = emptyMap(),
val primaryCard: PrimaryCard? = null, val primaryCard: PrimaryCard? = null,
) : CommandResponse { ) : CommandResponse {
constructor( constructor(
card: Card, card: Card,
derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(), derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = emptyMap(),
primaryCard: PrimaryCard? = null, primaryCard: PrimaryCard? = null,
) : this( ) : this(
card = CardDTO(card), card = CardDTO(card),

View file

@ -34,7 +34,7 @@ interface TangemSdkManager {
val canUseBiometry: Boolean val canUseBiometry: Boolean
val needEnrollBiometrics: Boolean val isEnrollBiometricsNeeded: Boolean
val keystoreManager: KeystoreManager val keystoreManager: KeystoreManager

View file

@ -1,49 +0,0 @@
package com.tangem.sdk.api
import androidx.annotation.StringRes
import com.tangem.common.core.TangemError
import com.tangem.legacy.R
interface TapErrors
interface ArgError {
val args: List<Any>?
}
interface MultiMessageError : TapErrors {
val errorList: List<TapError>
val builder: (List<String>) -> String
}
sealed class TapError(
@StringRes val messageResource: Int,
override val args: List<Any>? = null,
) : Throwable(), TapErrors, ArgError {
object UnknownError : TapError(R.string.send_error_unknown)
open class CustomError(val customMessage: String) : TapError(R.string.common_custom_string, listOf(customMessage))
object NoInternetConnection : TapError(R.string.wallet_notification_no_internet)
sealed class WalletManager {
class NoAccountError(amountToCreateAccount: String) : CustomError(amountToCreateAccount)
class InternalError(message: String) : CustomError(message)
object BlockchainIsUnreachableTryLater : TapError(R.string.wallet_balance_blockchain_unreachable_try_later)
}
}
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
override var customMessage: String = code.toString()
object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
object CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
}
fun TapErrors.assembleErrors(): MutableList<Pair<Int, List<Any>?>> {
val idList = mutableListOf<Pair<Int, List<Any>?>>()
when (this) {
is MultiMessageError -> this.errorList.forEach { idList.addAll(it.assembleErrors()) }
is TapError -> idList.add(Pair(this.messageResource, this.args))
}
return idList
}

View file

@ -1,10 +1,6 @@
import com.tangem.plugin.configuration.configurations.extension.kaptForObfuscatingVariants
plugins { plugins {
alias(deps.plugins.android.library) alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android) alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.ksp)
id("configuration") id("configuration")
} }
@ -20,23 +16,19 @@ android {
dependencies { dependencies {
/** Project */ // region Kotlin
implementation(projects.core.utils) implementation(deps.kotlin.coroutines)
implementation(projects.core.datasource) // endregion
implementation(projects.data.common)
/** Libs - Network */ // region Other libraries
implementation(deps.moshi.kotlin) implementation(deps.arrow.fx)
api(deps.jodatime)
implementation(deps.okHttp) implementation(deps.okHttp)
implementation(deps.okHttp.prettyLogging) implementation(deps.okHttp.prettyLogging)
implementation(deps.retrofit)
implementation(deps.retrofit.moshi)
ksp(deps.moshi.kotlin.codegen)
kaptForObfuscatingVariants(deps.retrofit.response.type.keeper)
/** Libs - Other */
implementation(deps.web3j.core) implementation(deps.web3j.core)
implementation(deps.kotlin.coroutines) // endregion
implementation(deps.arrow.fx)
implementation(deps.jodatime) // region Core modules
api(projects.core.utils)
// endregion
} }

View file

@ -1,11 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>BooleanPropertyNaming:VisaContractInfoProvider.kt$VisaContractInfoProvider.Builder$private val useTestnetRpc: Boolean</ID>
<ID>NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { fetchToken(paymentAccount) }, { fetchBalances(paymentAccount, paymentToken) }, { fetchLimits(paymentAccount, paymentToken, walletAddress) }, { token, balances, (oldLimit, newLimit, changeDate) -&gt; VisaContractInfo( token = token, balances = balances, oldLimits = oldLimit, newLimits = newLimit, paymentAccountAddress = paymentAccount.contractAddress, limitsChangeDate = changeDate, ) }, )</ID>
<ID>NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { loadPaymentAccount(walletAddress = walletAddress, paymentAccountAddress = paymentAccountAddress) }, { loadPaymentTokenInfo() }, { paymentAccount, paymentToken -&gt; fetchBalancesAndLimits( paymentAccount = paymentAccount, paymentToken = paymentToken, walletAddress = walletAddress, ) }, )</ID>
<ID>NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { paymentToken.contract.balanceOf(paymentAccount.contractAddress).send() }, { paymentAccount.verifiedBalance().send() }, { paymentAccount.availableForPayment().send() }, { paymentAccount.availableForWithdrawal().send() }, { paymentAccount.availableForDebtPayment().send() }, { paymentAccount.blockedAmount().send() }, { paymentAccount.debtAmount().send() }, ) { total, verified, payment, withdrawal, debtPayment, blocked, debt -&gt; val decimals = paymentToken.decimals Balances( total = total.toBigDecimal(decimals), verified = verified.toBigDecimal(decimals), available = Balances.Available( forPayment = payment.toBigDecimal(decimals), forWithdrawal = withdrawal.toBigDecimal(decimals), forDebtPayment = debtPayment.toBigDecimal(decimals), ), blocked = blocked.toBigDecimal(decimals), debt = debt.toBigDecimal(decimals), ) }</ID>
<ID>NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { paymentTokenContract.name().send() }, { paymentTokenContract.symbol().send() }, { paymentTokenContract.decimals().send() }, ) { name, symbol, decimals -&gt; Token( name = name, symbol = symbol, decimals = decimals.toInt(), address = paymentTokenContractAddress, ) }</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -20,6 +20,10 @@ internal class DefaultVisaContractInfoProvider(
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
) : VisaContractInfoProvider { ) : VisaContractInfoProvider {
// NamedArguments flags the parZip(...) invocation itself (a dispatcher + several positional
// supplier lambdas + a result combiner); those positional lambda parameters can't be meaningfully
// named, so it is suppressed here. Calls inside the lambdas still use named arguments.
@Suppress("NamedArguments")
override suspend fun getContractInfo(walletAddress: String, paymentAccountAddress: String?): VisaContractInfo { override suspend fun getContractInfo(walletAddress: String, paymentAccountAddress: String?): VisaContractInfo {
return parZip( return parZip(
dispatchers.io, dispatchers.io,
@ -71,6 +75,7 @@ internal class DefaultVisaContractInfoProvider(
) )
} }
@Suppress("NamedArguments") // parZip(...) call: positional supplier/combiner lambdas, not meaningfully nameable
private suspend fun fetchBalancesAndLimits( private suspend fun fetchBalancesAndLimits(
paymentAccount: TangemPaymentAccount, paymentAccount: TangemPaymentAccount,
paymentToken: PaymentTokenInfo, paymentToken: PaymentTokenInfo,
@ -92,6 +97,7 @@ internal class DefaultVisaContractInfoProvider(
}, },
) )
@Suppress("NamedArguments") // parZip(...) call: positional supplier/combiner lambdas, not meaningfully nameable
private suspend fun fetchToken(paymentAccount: TangemPaymentAccount): Token { private suspend fun fetchToken(paymentAccount: TangemPaymentAccount): Token {
val paymentTokenContractAddress = paymentAccount.paymentToken().send() val paymentTokenContractAddress = paymentAccount.paymentToken().send()
val paymentTokenContract = ERC20.load(paymentTokenContractAddress, web3j, transactionManager, gasProvider) val paymentTokenContract = ERC20.load(paymentTokenContractAddress, web3j, transactionManager, gasProvider)
@ -111,6 +117,7 @@ internal class DefaultVisaContractInfoProvider(
} }
} }
@Suppress("NamedArguments") // parZip(...) call: positional supplier/combiner lambdas, not meaningfully nameable
private suspend fun fetchBalances(paymentAccount: TangemPaymentAccount, paymentToken: PaymentTokenInfo): Balances { private suspend fun fetchBalances(paymentAccount: TangemPaymentAccount, paymentToken: PaymentTokenInfo): Balances {
return parZip( return parZip(
dispatchers.io, dispatchers.io,

View file

@ -31,7 +31,7 @@ interface VisaContractInfoProvider {
suspend fun getContractInfo(walletAddress: String, paymentAccountAddress: String?): VisaContractInfo suspend fun getContractInfo(walletAddress: String, paymentAccountAddress: String?): VisaContractInfo
class Builder( class Builder(
private val useTestnetRpc: Boolean, private val isTestnetRpcEnabled: Boolean,
private val bridgeProcessorAddress: String, private val bridgeProcessorAddress: String,
private val paymentAccountRegistryAddress: String, private val paymentAccountRegistryAddress: String,
private val isNetworkLoggingEnabled: Boolean, private val isNetworkLoggingEnabled: Boolean,
@ -59,7 +59,7 @@ interface VisaContractInfoProvider {
} }
private fun createWeb3J(): Web3j { private fun createWeb3J(): Web3j {
val baseUrl: String = if (useTestnetRpc) Constants.TESTNET_RPC_URL else Constants.MAINNET_RPC_URL val baseUrl: String = if (isTestnetRpcEnabled) Constants.TESTNET_RPC_URL else Constants.MAINNET_RPC_URL
val httpClient = OkHttpClient.Builder().apply { val httpClient = OkHttpClient.Builder().apply {
connectTimeout(networkTimeoutSeconds, TimeUnit.SECONDS) connectTimeout(networkTimeoutSeconds, TimeUnit.SECONDS)