diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d592ad2b98..794229daee 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -217,6 +217,8 @@ dependencies {
implementation(projects.features.usedesk.impl)
implementation(projects.features.hotWallet.api)
implementation(projects.features.hotWallet.impl)
+ implementation(projects.features.kyc.api)
+ implementation(projects.features.kyc.impl)
/** AndroidX libraries */
implementation(deps.androidx.core.ktx)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ac76057c04..a2c1f4e5fe 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -45,7 +45,14 @@
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning"
- tools:replace="android:allowBackup, android:fullBackupContent, android:label">
+ tools:replace="android:allowBackup, android:fullBackupContent, android:label, android:largeHeap">
+
+
+
/etc/apt/sources.list.d/github-cli.list && \
- apt-get update && apt-get install -y gh && \
- apt-get clean
-
-RUN mkdir -p $ANDROID_HOME/cmdline-tools/latest && \
- wget https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O /tmp/cmdline-tools.zip && \
- unzip /tmp/cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools/latest && \
- mv $ANDROID_HOME/cmdline-tools/latest/cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ && \
- rm -rf $ANDROID_HOME/cmdline-tools/latest/cmdline-tools && \
- rm -f /tmp/cmdline-tools.zip && \
- yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses && \
- $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-31" "platforms;android-34" "build-tools;34.0.0"
-
-RUN wget https://github.com/lzhiyong/android-sdk-tools/releases/download/34.0.3/android-sdk-tools-static-aarch64.zip -O /tmp/android-sdk-tools-static-aarch64.zip && \
- unzip /tmp/android-sdk-tools-static-aarch64.zip -d /tmp/android-sdk-tools-static-arm && \
- cp -r /tmp/android-sdk-tools-static-arm/build-tools/* $ANDROID_HOME/build-tools/34.0.0/ && \
- rm -rf /tmp/android-sdk-tools-static-arm /tmp/android-sdk-tools-static-aarch64.zip
-
-RUN gem install bundler:2.5.23
-RUN gem install fastlane -v 2.225.0 -N -V
-RUN gem install fastlane-plugin-firebase_app_distribution -v 0.9.1 -N -V
-
-COPY ../Gemfile Gemfile.lock ./
-RUN bundle install --jobs=4 --retry=3 --verbose
-
-RUN bundle exec fastlane -v
-
-CMD ["bash"]
diff --git a/ci_resources/Dockerfile.lightweight b/ci_resources/Dockerfile.lightweight
deleted file mode 100644
index c2b4b399b2..0000000000
--- a/ci_resources/Dockerfile.lightweight
+++ /dev/null
@@ -1,26 +0,0 @@
-FROM ubuntu:24.04
-
-ENV LC_ALL=en_US.UTF-8
-ENV LANG=en_US.UTF-8
-ENV DEBIAN_FRONTEND=noninteractive
-
-RUN apt-get update && apt-get install -y \
- locales \
- curl \
- git \
- && locale-gen en_US.UTF-8 \
- && update-locale LANG=en_US.UTF-8 \
- && apt-get clean
-
-RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
- chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
- echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list && \
- apt-get update && apt-get install -y gh && \
- apt-get clean
-
-RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \
- apt-get install -y git-lfs && \
- git lfs install && \
- apt-get clean
-
-CMD ["bash"]
diff --git a/ci_resources/tests_8gb_ram_ci_gradle.properties b/ci_resources/tests_ci_gradle.properties
similarity index 86%
rename from ci_resources/tests_8gb_ram_ci_gradle.properties
rename to ci_resources/tests_ci_gradle.properties
index 78577a0975..860c64d2b5 100644
--- a/ci_resources/tests_8gb_ram_ci_gradle.properties
+++ b/ci_resources/tests_ci_gradle.properties
@@ -8,6 +8,6 @@ org.gradle.caching=false
android.useAndroidX=true
android.nonTransitiveRClass=false
-android.aapt2FromMavenOverride=/opt/android-sdk/build-tools/34.0.0/aapt2
+android.aapt2FromMavenOverride=/opt/android-sdk/build-tools/35.0.0/aapt2
kotlin.incremental=false
diff --git a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/version/DefaultVersionProvider.kt b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/version/DefaultVersionProvider.kt
index b55e9637c3..105ca52d15 100644
--- a/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/version/DefaultVersionProvider.kt
+++ b/core/config-toggles/src/main/kotlin/com/tangem/core/configtoggle/version/DefaultVersionProvider.kt
@@ -28,9 +28,9 @@ internal class DefaultVersionProvider @Inject constructor(
context.packageName,
PackageManager.PackageInfoFlags.of(0),
)
- .versionName
+ .versionName!!
} else {
- context.packageManager.getPackageInfo(context.packageName, 0).versionName
+ context.packageManager.getPackageInfo(context.packageName, 0).versionName!!
}
}
diff --git a/core/decompose/build.gradle.kts b/core/decompose/build.gradle.kts
index aa1b6e3c82..792dbe9a1c 100644
--- a/core/decompose/build.gradle.kts
+++ b/core/decompose/build.gradle.kts
@@ -1,13 +1,19 @@
plugins {
- alias(deps.plugins.kotlin.jvm)
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
id("configuration")
}
+android {
+ namespace = "com.tangem.core.decompose"
+}
+
dependencies {
api(projects.core.utils)
api(deps.decompose)
+ api(deps.androidx.appCompat)
implementation(deps.kotlin.coroutines)
implementation(deps.hilt.core)
diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContext.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContext.kt
index 9426735800..8201bba2c4 100644
--- a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContext.kt
+++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContext.kt
@@ -4,6 +4,7 @@ import com.arkivanov.decompose.ComponentContext
import com.tangem.core.decompose.di.HiltComponentBuilderOwner
import com.tangem.core.decompose.navigation.NavigationOwner
import com.tangem.core.decompose.ui.UiMessageSenderOwner
+import com.tangem.core.decompose.utils.ActivityHolder
import com.tangem.core.decompose.utils.ComponentScopeOwner
import com.tangem.core.decompose.utils.DispatchersOwner
import com.tangem.core.decompose.utils.TagsOwner
@@ -20,4 +21,5 @@ interface AppComponentContext :
DispatchersOwner,
UiMessageSenderOwner,
HiltComponentBuilderOwner,
- TagsOwner
\ No newline at end of file
+ TagsOwner,
+ ActivityHolder
\ No newline at end of file
diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContextChildrenFactory.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContextChildrenFactory.kt
index 146a7e2bb0..2ae9d71656 100644
--- a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContextChildrenFactory.kt
+++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/AppComponentContextChildrenFactory.kt
@@ -10,6 +10,7 @@ import com.tangem.core.decompose.ui.DefaultUiMessageSender
import com.tangem.core.decompose.ui.UiMessageHandler
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.decompose.ui.UiMessageSenderOwner
+import com.tangem.core.decompose.utils.ActivityHolder
import com.tangem.core.decompose.utils.ComponentCoroutineScope
import com.tangem.core.decompose.utils.DispatchersOwner
import kotlinx.coroutines.CoroutineScope
@@ -58,7 +59,8 @@ fun AppComponentContext.childByContext(
NavigationOwner by this@childByContext,
UiMessageSenderOwner by this@childByContext,
DispatchersOwner by this@childByContext,
- HiltComponentBuilderOwner by this@childByContext {
+ HiltComponentBuilderOwner by this@childByContext,
+ ActivityHolder by this@childByContext {
override val tags: HashMap = HashMap()
diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/DefaultAppComponentContext.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/DefaultAppComponentContext.kt
index ea9afa04a5..a8a4fac2f7 100644
--- a/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/DefaultAppComponentContext.kt
+++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/context/DefaultAppComponentContext.kt
@@ -1,5 +1,6 @@
package com.tangem.core.decompose.context
+import androidx.appcompat.app.AppCompatActivity
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.essenty.instancekeeper.getOrCreate
import com.tangem.core.decompose.di.ModelComponent
@@ -17,6 +18,7 @@ class DefaultAppComponentContext(
override val dispatchers: CoroutineDispatcherProvider,
override val hiltComponentBuilder: ModelComponent.Builder,
override val messageSender: UiMessageSender,
+ override val activity: AppCompatActivity,
private val replaceRouter: Router? = null,
) : AppComponentContext, ComponentContext by componentContext {
diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/utils/ActivityHolder.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/utils/ActivityHolder.kt
new file mode 100644
index 0000000000..5ef79e239d
--- /dev/null
+++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/utils/ActivityHolder.kt
@@ -0,0 +1,16 @@
+package com.tangem.core.decompose.utils
+
+import androidx.appcompat.app.AppCompatActivity
+
+/**
+ * Interface for holding an [AppCompatActivity] instance.
+ *
+ * This interface is used to provide access to the activity in which the component is running.
+ */
+interface ActivityHolder {
+
+ /**
+ * The [AppCompatActivity] instance associated with this context.
+ */
+ val activity: AppCompatActivity
+}
\ No newline at end of file
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 950482041e..24ec4eb861 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -19,7 +19,7 @@ platform :android do
desc "Run detekt"
lane :detekt do
- FileUtils.cp("../ci_resources/tests_8gb_ram_ci_gradle.properties", "../gradle.properties")
+ FileUtils.cp("../ci_resources/tests_ci_gradle.properties", "../gradle.properties")
puts File.read("../gradle.properties")
gradle(task: "detekt")
end
@@ -27,7 +27,7 @@ platform :android do
desc "Run tests"
lane :test do
FileUtils.cp("../app/src/main/assets/tangem-app-config/android/google-services/dev/google-services.json", "../app")
- FileUtils.cp("../ci_resources/tests_8gb_ram_ci_gradle.properties", "../gradle.properties")
+ FileUtils.cp("../ci_resources/tests_ci_gradle.properties", "../gradle.properties")
puts File.read("../gradle.properties")
gradle(task: "testDebugUnitTest")
end
diff --git a/features/kyc/api/.gitignore b/features/kyc/api/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/features/kyc/api/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/features/kyc/api/build.gradle.kts b/features/kyc/api/build.gradle.kts
new file mode 100644
index 0000000000..3133f2c7de
--- /dev/null
+++ b/features/kyc/api/build.gradle.kts
@@ -0,0 +1,22 @@
+plugins {
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
+ id("configuration")
+}
+
+android {
+ namespace = "com.tangem.features.kyc.api"
+}
+
+dependencies {
+
+ /* Project - Domain */
+ implementation(projects.domain.models)
+
+ /* Project - Core */
+ implementation(projects.core.decompose)
+ implementation(projects.core.ui)
+
+ /* Compose */
+ implementation(deps.compose.runtime)
+}
\ No newline at end of file
diff --git a/features/kyc/api/src/main/kotlin/com/tangem/features/kyc/KycComponent.kt b/features/kyc/api/src/main/kotlin/com/tangem/features/kyc/KycComponent.kt
new file mode 100644
index 0000000000..6a18888000
--- /dev/null
+++ b/features/kyc/api/src/main/kotlin/com/tangem/features/kyc/KycComponent.kt
@@ -0,0 +1,12 @@
+package com.tangem.features.kyc
+
+import com.tangem.core.decompose.context.AppComponentContext
+
+interface KycComponent {
+
+ fun launch()
+
+ interface Factory {
+ fun create(appComponentContext: AppComponentContext): KycComponent
+ }
+}
\ No newline at end of file
diff --git a/features/kyc/impl/.gitignore b/features/kyc/impl/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/features/kyc/impl/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/features/kyc/impl/build.gradle.kts b/features/kyc/impl/build.gradle.kts
new file mode 100644
index 0000000000..86e6e641fb
--- /dev/null
+++ b/features/kyc/impl/build.gradle.kts
@@ -0,0 +1,54 @@
+plugins {
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
+ alias(deps.plugins.kotlin.kapt)
+ alias(deps.plugins.kotlin.serialization)
+ alias(deps.plugins.hilt.android)
+ id("configuration")
+}
+
+android {
+ namespace = "com.tangem.features.kyc.impl"
+}
+
+dependencies {
+ /** Api */
+ implementation(projects.features.kyc.api)
+
+ /** Core modules */
+ implementation(projects.core.configToggles)
+ implementation(projects.core.analytics)
+ implementation(projects.core.analytics.models)
+ implementation(projects.core.utils)
+ implementation(projects.core.ui)
+ implementation(projects.core.res)
+ implementation(projects.core.decompose)
+ implementation(projects.core.navigation)
+ implementation(projects.core.datasource)
+
+ /** Common */
+ implementation(projects.common.ui)
+ implementation(projects.common.routing)
+
+ /** Compose libraries */
+ implementation(deps.compose.material3)
+ implementation(deps.compose.animation)
+ implementation(deps.compose.foundation)
+ implementation(deps.compose.ui)
+ implementation(deps.compose.ui.tooling)
+ implementation(deps.compose.coil)
+ implementation(deps.lottie.compose)
+ implementation(deps.decompose.ext.compose)
+ implementation(deps.androidx.activity.compose)
+
+ /** Other libraries */
+ implementation(deps.kotlin.immutable.collections)
+ implementation(deps.kotlin.serialization)
+ implementation(deps.timber)
+ implementation(deps.firebase.crashlytics)
+ implementation(deps.sumsub.sdk)
+
+ /** DI */
+ implementation(deps.hilt.android)
+ kapt(deps.hilt.kapt)
+}
\ No newline at end of file
diff --git a/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/DefaultKycComponent.kt b/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/DefaultKycComponent.kt
new file mode 100644
index 0000000000..d192cead2d
--- /dev/null
+++ b/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/DefaultKycComponent.kt
@@ -0,0 +1,39 @@
+package com.tangem.features.kyc
+
+import com.sumsub.sns.core.SNSMobileSDK
+import com.sumsub.sns.core.data.listener.TokenExpirationHandler
+import com.tangem.core.decompose.context.AppComponentContext
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.Locale
+
+class DefaultKycComponent @AssistedInject constructor(
+ @Assisted appComponentContext: AppComponentContext,
+) : KycComponent, AppComponentContext by appComponentContext {
+
+ override fun launch() {
+ val accessToken = "123456"
+
+ val tokenExpirationHandler = object : TokenExpirationHandler {
+ override fun onTokenExpired(): String? {
+ // Access token expired
+ // get a new one and pass it to the callback to re-initiate the SDK
+ val newToken = "..." // get a new token from your backend
+ return newToken
+ }
+ }
+
+ val snsSdk = SNSMobileSDK.Builder(activity)
+ .withAccessToken(accessToken, onTokenExpiration = tokenExpirationHandler)
+ .withLocale(Locale("en"))
+ .build()
+
+ snsSdk.launch()
+ }
+
+ @AssistedFactory
+ interface Factory : KycComponent.Factory {
+ override fun create(appComponentContext: AppComponentContext): DefaultKycComponent
+ }
+}
\ No newline at end of file
diff --git a/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/di/FeatureModule.kt b/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/di/FeatureModule.kt
new file mode 100644
index 0000000000..c72f282775
--- /dev/null
+++ b/features/kyc/impl/src/main/kotlin/com/tangem/features/kyc/di/FeatureModule.kt
@@ -0,0 +1,16 @@
+package com.tangem.features.kyc.di
+
+import com.tangem.features.kyc.DefaultKycComponent
+import com.tangem.features.kyc.KycComponent
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal interface FeatureModule {
+
+ @Binds
+ fun bindComponentFactory(impl: DefaultKycComponent.Factory): KycComponent.Factory
+}
\ No newline at end of file
diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml
index 04c6f4b039..2473ea55b9 100644
--- a/gradle/dependencies.toml
+++ b/gradle/dependencies.toml
@@ -15,7 +15,7 @@ firebasePerf = "1.4.2"
androidxActivityCompose = "1.8.0"
androidxAppCompat = "1.5.1"
androidxBrowser = "1.4.0"
-androidxConstraintLayout = "2.1.4"
+androidxConstraintLayout = "2.2.1"
androidxKtx = "1.9.0"
androidxSplashScreen = "1.0.1"
androidxFragment = "1.8.5"
@@ -32,7 +32,7 @@ compose-runtime = "1.7.4"
compose-foundation = "1.7.4"
compose-material = "1.7.4"
compose-material3 = "1.3.1"
-compose-constraint = "1.0.1"
+compose-constraint = "1.1.1"
compose-navigation = "2.7.7"
compose-accompanist = "0.30.1"
compose-paging = "3.2.1"
@@ -90,6 +90,7 @@ room = "2.6.1"
markdown = "0.7.2"
markdownComposeView = "0.5.4"
usedesk = "4.4.0"
+sumsub = "1.36.0"
# endregion Other libraries
# region Tools
@@ -277,4 +278,5 @@ markdown = { module = "org.jetbrains:markdown", version.ref = "markdown" }
markdown-composeview = { module = "com.github.jeziellago:compose-markdown", version.ref = "markdownComposeView" }
usedesk-chat-sdk = { module = "com.github.Usedesk.Android_SDK:chat-sdk", version.ref = "usedesk" }
usedesk-chat-gui = { module = "com.github.Usedesk.Android_SDK:chat-gui", version.ref = "usedesk" }
+sumsub-sdk = { module = "com.sumsub.sns:idensic-mobile-sdk", version.ref = "sumsub" }
# endregion Other
diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt
index 3db7478662..5ddd7ba12d 100644
--- a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt
+++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt
@@ -6,6 +6,6 @@ internal object AppConfig {
const val versionName = "1.0.0-SNAPSHOT"
// const val versionName = "100.0.0-SNAPSHOT" //TODO: [REDACTED_JIRA]
const val minSdkVersion = 24
- const val targetSdkVersion = 34
- const val compileSdkVersion = 34
+ const val targetSdkVersion = 35
+ const val compileSdkVersion = 35
}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index c827ecc8a0..eca5b3d022 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -118,6 +118,7 @@ dependencyResolutionManagement {
}
}
maven("https://jitpack.io")
+ maven("https://maven.sumsub.com/repository/maven-public/")
}
versionCatalogs {
@@ -247,6 +248,9 @@ include(":features:walletconnect:impl")
include(":features:hot-wallet:api")
include(":features:hot-wallet:impl")
+
+include(":features:kyc:api")
+include(":features:kyc:impl")
// endregion Feature modules
// region Domain modules
diff --git a/tangem-android-tools b/tangem-android-tools
index 53e359bc2e..8d971eb9d9 160000
--- a/tangem-android-tools
+++ b/tangem-android-tools
@@ -1 +1 @@
-Subproject commit 53e359bc2ead37feeb9e70d7004c91cde07ccf9b
+Subproject commit 8d971eb9d901358419da78408ecf7dc3f0c4331f