diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b38fcaaff0..18f2560bb9 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -172,4 +172,10 @@ dependencies {
testImplementation(deps.test.truth)
androidTestImplementation(deps.test.junit.android)
androidTestImplementation(deps.test.espresso)
+
+ /** Chucker */
+ debugImplementation(deps.chucker)
+ externalImplementation(deps.chuckerStub)
+ internalImplementation(deps.chuckerStub)
+ releaseImplementation(deps.chuckerStub)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 53d4be3c7f..6e5584b665 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,6 +12,7 @@
+
diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt
index 8968591dd2..58f0388211 100644
--- a/app/src/main/java/com/tangem/tap/MainActivity.kt
+++ b/app/src/main/java/com/tangem/tap/MainActivity.kt
@@ -1,14 +1,19 @@
package com.tangem.tap
+import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
import android.content.res.Configuration
+import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
@@ -52,6 +57,7 @@ import com.tangem.tap.features.welcome.ui.WelcomeFragment
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.redux.DaggerGraphAction
import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
+import com.tangem.wallet.BuildConfig
import com.tangem.wallet.R
import com.tangem.wallet.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
@@ -139,6 +145,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
initContent()
checkGooglePayAvailability()
+
+ checkForNotificationPermission()
}
private fun installActivityDependencies() {
@@ -371,4 +379,14 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
store.dispatch(BackupAction.CheckForUnfinishedBackup)
}
+
+ private fun checkForNotificationPermission() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
+ BuildConfig.DEBUG &&
+ ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=
+ PackageManager.PERMISSION_GRANTED
+ ) {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt
index 7139ed166e..f1c7401484 100644
--- a/app/src/main/java/com/tangem/tap/TapApplication.kt
+++ b/app/src/main/java/com/tangem/tap/TapApplication.kt
@@ -5,6 +5,7 @@ import android.content.Context
import android.content.pm.PackageManager
import coil.ImageLoader
import coil.ImageLoaderFactory
+import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.orhanobut.logger.AndroidLogAdapter
import com.orhanobut.logger.Logger
import com.tangem.Log
@@ -259,6 +260,7 @@ internal class TapApplication : Application(), ImageLoaderFactory {
if (LogConfig.network.blockchainSdkNetwork) {
BlockchainSdkRetrofitBuilder.interceptors = listOf(
createNetworkLoggingInterceptor(),
+ ChuckerInterceptor(this),
)
}
diff --git a/core/datasource/build.gradle.kts b/core/datasource/build.gradle.kts
index 6d7e66c87e..88d82bd624 100644
--- a/core/datasource/build.gradle.kts
+++ b/core/datasource/build.gradle.kts
@@ -47,4 +47,11 @@ dependencies {
/** Security */
implementation(deps.spongecastle.core)
+
+ /** Chucker */
+ /** Chucker */
+ debugImplementation(deps.chucker)
+ externalImplementation(deps.chuckerStub)
+ internalImplementation(deps.chuckerStub)
+ releaseImplementation(deps.chuckerStub)
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApi.kt
deleted file mode 100644
index d3d092493f..0000000000
--- a/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApi.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.tangem.datasource.api.paymentology
-
-import com.tangem.datasource.api.paymentology.models.request.CheckRegistrationRequests
-import com.tangem.datasource.api.paymentology.models.request.RegisterKYCRequest
-import com.tangem.datasource.api.paymentology.models.request.RegisterWalletRequest
-import com.tangem.datasource.api.paymentology.models.response.AttestationResponse
-import com.tangem.datasource.api.paymentology.models.response.RegisterWalletResponse
-import com.tangem.datasource.api.paymentology.models.response.RegistrationResponse
-import retrofit2.http.Body
-import retrofit2.http.Headers
-import retrofit2.http.POST
-
-/**
- * Interface of Paymentology Api.
- *
- * IMPORTANT: Cannot replace [Headers] annotations with OkHttpClient.addHeader(), because OkHttp adds encoding to
- * content type value. But Paymentology API expects a value without the charset.
- *
-[REDACTED_AUTHOR]
- */
-interface PaymentologyApi {
-
- @Headers("Content-Type: application/json")
- @POST("card/verify")
- suspend fun checkRegistration(@Body request: CheckRegistrationRequests): RegistrationResponse
-
- @Headers("Content-Type: application/json")
- @POST("card/get_challenge")
- suspend fun requestAttestationChallenge(@Body request: CheckRegistrationRequests.Item): AttestationResponse
-
- @Headers("Content-Type: application/json")
- @POST("card/set_pin")
- suspend fun registerWallet(@Body request: RegisterWalletRequest): RegisterWalletResponse
-
- @Headers("Content-Type: application/json")
- @POST("card/kyc")
- suspend fun registerKYC(@Body request: RegisterKYCRequest): RegisterWalletResponse
-}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApiService.kt b/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApiService.kt
deleted file mode 100644
index f660c1fc47..0000000000
--- a/core/datasource/src/main/java/com/tangem/datasource/api/paymentology/PaymentologyApiService.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.tangem.datasource.api.paymentology
-
-import com.tangem.datasource.api.common.MoshiConverter
-import com.tangem.datasource.utils.allowLogging
-import okhttp3.OkHttpClient
-import retrofit2.Retrofit
-
-/**
-[REDACTED_AUTHOR]
- */
-// TODO("Remove after removing Redux")
-@Deprecated("Use PaymentologyApi")
-object PaymentologyApiService {
- val api = createApi()
-
- private const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
-
- private fun createApi(): PaymentologyApi {
- return Retrofit.Builder()
- .addConverterFactory(MoshiConverter.networkMoshiConverter)
- .baseUrl(PAYMENTOLOGY_BASE_URL)
- .client(
- OkHttpClient.Builder()
- .allowLogging()
- .build(),
- )
- .build()
- .create(PaymentologyApi::class.java)
- }
-}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechService.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechService.kt
index cf51d43c58..4c08c5ce73 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechService.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/TangemTechService.kt
@@ -6,7 +6,7 @@ import com.tangem.datasource.utils.RequestHeader
import com.tangem.datasource.utils.RequestHeader.AuthenticationHeader
import com.tangem.datasource.utils.RequestHeader.CacheControlHeader
import com.tangem.datasource.utils.addHeaders
-import com.tangem.datasource.utils.allowLogging
+import com.tangem.datasource.utils.addLoggers
import okhttp3.OkHttpClient
import retrofit2.Retrofit
@@ -35,7 +35,7 @@ object TangemTechService {
.client(
OkHttpClient.Builder()
.addHeaders(*headers.toTypedArray())
- .allowLogging()
+ .addLoggers()
.build(),
)
.build()
diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
index 3a9580d2d0..f3e245e0d6 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
@@ -1,17 +1,18 @@
package com.tangem.datasource.di
+import android.content.Context
import com.squareup.moshi.Moshi
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
-import com.tangem.datasource.api.paymentology.PaymentologyApi
import com.tangem.datasource.api.promotion.PromotionApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.utils.RequestHeader.*
import com.tangem.datasource.utils.addHeaders
-import com.tangem.datasource.utils.allowLogging
+import com.tangem.datasource.utils.addLoggers
import com.tangem.lib.auth.AuthProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
@@ -25,7 +26,7 @@ class NetworkModule {
@Provides
@Singleton
- fun provideTangemTechApi(@NetworkMoshi moshi: Moshi): TangemTechApi {
+ fun provideTangemTechApi(@NetworkMoshi moshi: Moshi, @ApplicationContext context: Context): TangemTechApi {
return Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
@@ -37,35 +38,24 @@ class NetworkModule {
// TODO("refactor header init") get auth data after biometric auth to avoid race condition
// AuthenticationHeader(authProvider),
)
- .allowLogging()
+ .addLoggers(context)
.build(),
)
.build()
.create(TangemTechApi::class.java)
}
- @Provides
- @Singleton
- fun providePaymentologyApi(@NetworkMoshi moshi: Moshi): PaymentologyApi {
- return Retrofit.Builder()
- .addConverterFactory(MoshiConverterFactory.create(moshi))
- .baseUrl(PAYMENTOLOGY_BASE_URL)
- .client(
- OkHttpClient.Builder()
- .allowLogging()
- .build(),
- )
- .build()
- .create(PaymentologyApi::class.java)
- }
-
@Provides
@Singleton
@PromotionOneInch
- fun providePromotionOneInchApi(authProvider: AuthProvider, @NetworkMoshi moshi: Moshi): PromotionApi {
+ fun providePromotionOneInchApi(
+ authProvider: AuthProvider,
+ @NetworkMoshi moshi: Moshi,
+ @ApplicationContext context: Context,
+ ): PromotionApi {
val okClient = OkHttpClient.Builder()
.addHeaders(AuthenticationHeader(authProvider))
- .allowLogging()
+ .addLoggers(context)
.callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.readTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/OneInchApisModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/OneInchApisModule.kt
index b413b2aa14..68c9fdf683 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/di/OneInchApisModule.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/di/OneInchApisModule.kt
@@ -1,12 +1,14 @@
package com.tangem.datasource.di
+import android.content.Context
import com.squareup.moshi.Moshi
import com.tangem.datasource.api.oneinch.OneInchApi
import com.tangem.datasource.api.oneinch.OneInchApiFactory
-import com.tangem.datasource.utils.allowLogging
+import com.tangem.datasource.utils.addLoggers
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
@@ -19,23 +21,31 @@ class OneInchApisModule {
@Provides
@Singleton
- fun provideOneInchApiFactory(@NetworkMoshi moshi: Moshi): OneInchApiFactory {
- val apiFactory = OneInchApiFactory()
- apiFactory.putApi(ETH_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_ETH_PATH, moshi))
- apiFactory.putApi(BSC_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_BSC_PATH, moshi))
- apiFactory.putApi(POLYGON_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_POLYGON_PATH, moshi))
- apiFactory.putApi(OPTIMISM_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_OPTIMISM_PATH, moshi))
- apiFactory.putApi(ARBITRUM_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_ARBITRUM_PATH, moshi))
- apiFactory.putApi(GNOSIS_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_GNOSIS_PATH, moshi))
- apiFactory.putApi(
- AVALANCHE_NETWORK,
- createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_AVALANCHE_PATH, moshi),
+ fun provideOneInchApiFactory(@NetworkMoshi moshi: Moshi, @ApplicationContext context: Context): OneInchApiFactory {
+ val networks = mapOf(
+ ETH_NETWORK to ONE_INCH_ETH_PATH,
+ BSC_NETWORK to ONE_INCH_BSC_PATH,
+ POLYGON_NETWORK to ONE_INCH_POLYGON_PATH,
+ OPTIMISM_NETWORK to ONE_INCH_OPTIMISM_PATH,
+ ARBITRUM_NETWORK to ONE_INCH_ARBITRUM_PATH,
+ GNOSIS_NETWORK to ONE_INCH_GNOSIS_PATH,
+ AVALANCHE_NETWORK to ONE_INCH_AVALANCHE_PATH,
+ FANTOM_NETWORK to ONE_INCH_FANTOM_PATH,
)
- apiFactory.putApi(FANTOM_NETWORK, createOneInchApiWithUrl(ONE_INCH_BASE_URL + ONE_INCH_FANTOM_PATH, moshi))
+
+ val apiFactory = OneInchApiFactory()
+
+ for ((network, path) in networks) {
+ apiFactory.putApi(
+ networkId = network,
+ api = createOneInchApiWithUrl("$ONE_INCH_BASE_URL$path", moshi, context),
+ )
+ }
+
return apiFactory
}
- private fun createOneInchApiWithUrl(url: String, moshi: Moshi): OneInchApi {
+ private fun createOneInchApiWithUrl(url: String, moshi: Moshi, context: Context): OneInchApi {
return Retrofit.Builder()
.addConverterFactory(
MoshiConverterFactory.create(moshi),
@@ -43,7 +53,7 @@ class OneInchApisModule {
.baseUrl(url)
.client(
OkHttpClient.Builder()
- .allowLogging()
+ .addLoggers(context)
.build(),
)
.build()
diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
index 4a5a6a1b75..5490d5f8f3 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
@@ -1,5 +1,7 @@
package com.tangem.datasource.utils
+import android.content.Context
+import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.tangem.datasource.BuildConfig
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
import okhttp3.Interceptor
@@ -25,8 +27,11 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade
*
* @param level logging level. By default, only the request body.
*/
-internal fun OkHttpClient.Builder.allowLogging(): OkHttpClient.Builder {
- return if (BuildConfig.DEBUG) {
+internal fun OkHttpClient.Builder.addLoggers(context: Context? = null): OkHttpClient.Builder {
+ return if (BuildConfig.LOG_ENABLED) {
+ context?.let {
+ addInterceptor(interceptor = ChuckerInterceptor(it))
+ }
addInterceptor(interceptor = createNetworkLoggingInterceptor())
} else {
this
diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalState.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalState.kt
index a424fbb683..bd6efc230c 100644
--- a/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalState.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalState.kt
@@ -1,6 +1,5 @@
package com.tangem.domain.redux.global
-import com.tangem.datasource.api.paymentology.PaymentologyApiService
import com.tangem.datasource.api.tangemTech.TangemTechService
import com.tangem.domain.models.scan.ScanResponse
@@ -17,5 +16,4 @@ data class DomainGlobalState(
data class NetworkServices(
val tangemTechService: TangemTechService = TangemTechService,
- val paymentologyService: PaymentologyApiService = PaymentologyApiService,
)
\ No newline at end of file
diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml
index b63f0cc158..3bb832ee06 100644
--- a/gradle/dependencies.toml
+++ b/gradle/dependencies.toml
@@ -79,6 +79,7 @@ walletConnectCore = "1.18.0"
walletConnectWeb3 = "1.11.0"
prettyLogger = "2.2.0"
okHttp-prettyLogging = "3.1.0"
+chucker = "4.0.0"
# endregion Other libraries
# region Tangem
@@ -230,4 +231,6 @@ reactive-network = { module = "com.github.pwittchen:reactivenetwork-rx2", versio
walletConnectCore = { module = "com.walletconnect:android-core", version.ref = "walletConnectCore" }
walletConnectWeb3 = { module = "com.walletconnect:web3wallet", version.ref = "walletConnectWeb3" }
prettyLogger = { module = "com.orhanobut:logger", version.ref = "prettyLogger" }
+chucker = { module = "com.github.chuckerteam.chucker:library", version.ref = "chucker" }
+chuckerStub = { module = "com.github.chuckerteam.chucker:library-no-op", version.ref = "chucker" }
# endregion Other