Updated on 2026-08-14
This commit is contained in:
parent
48137d6199
commit
f18ec7ac86
18 changed files with 148 additions and 178 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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?,
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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" }
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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>
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ interface TangemSdkManager {
|
||||||
|
|
||||||
val canUseBiometry: Boolean
|
val canUseBiometry: Boolean
|
||||||
|
|
||||||
val needEnrollBiometrics: Boolean
|
val isEnrollBiometricsNeeded: Boolean
|
||||||
|
|
||||||
val keystoreManager: KeystoreManager
|
val keystoreManager: KeystoreManager
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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) -> 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 -> 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 -> 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 -> Token( name = name, symbol = symbol, decimals = decimals.toInt(), address = paymentTokenContractAddress, ) }</ID>
|
|
||||||
</CurrentIssues>
|
|
||||||
</SmellBaseline>
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue