Updated on 2026-08-14
This commit is contained in:
commit
ab96b860d8
87 changed files with 630 additions and 146 deletions
|
|
@ -28,8 +28,10 @@ dependencies {
|
|||
implementation(project(":domain:card"))
|
||||
implementation(project(":domain:wallets"))
|
||||
implementation(project(":domain:wallets:models"))
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(project(":common"))
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(project(":core:navigation"))
|
||||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:res"))
|
||||
|
|
@ -39,6 +41,7 @@ dependencies {
|
|||
implementation(project(":libs:crypto"))
|
||||
implementation(project(":libs:auth"))
|
||||
implementation(project(":data:source:preferences"))
|
||||
implementation(projects.data.tokens)
|
||||
|
||||
/** Features */
|
||||
implementation(project(":features:onboarding"))
|
||||
|
|
@ -119,13 +122,6 @@ dependencies {
|
|||
implementation(deps.appsflyer)
|
||||
implementation(deps.amplitude)
|
||||
implementation(deps.kotsonGson)
|
||||
//TODO: refactoring: remove it when all network services moved to the datasource module
|
||||
implementation(deps.retrofit)
|
||||
implementation(deps.retrofit.moshi)
|
||||
implementation(deps.moshi)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.okHttp)
|
||||
implementation(deps.okHttp.logging)
|
||||
implementation(deps.zendesk.chat)
|
||||
implementation(deps.zendesk.messaging)
|
||||
implementation(deps.spongecastle.core)
|
||||
|
|
@ -144,6 +140,7 @@ dependencies {
|
|||
implementation(deps.kotlin.serialization)
|
||||
implementation(deps.walletConnectCore)
|
||||
implementation(deps.walletConnectWeb3)
|
||||
implementation(deps.prettyLogger)
|
||||
|
||||
/** Testing libraries */
|
||||
testImplementation(deps.test.junit)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||
import android.content.pm.PackageManager
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import com.orhanobut.logger.Logger
|
||||
import com.tangem.Log
|
||||
import com.tangem.LogFormat
|
||||
import com.tangem.blockchain.common.BlockchainSdkConfig
|
||||
|
|
@ -14,12 +15,14 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.data.source.preferences.PreferencesDataSource
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.datasource.config.FeaturesLocalLoader
|
||||
import com.tangem.datasource.config.models.Config
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.domain.DomainLayer
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.wallets.legacy.WalletManagersRepository
|
||||
import com.tangem.feature.learn2earn.domain.api.Learn2earnInteractor
|
||||
|
|
@ -59,7 +62,6 @@ import com.tangem.tap.proxy.redux.DaggerGraphState
|
|||
import com.tangem.wallet.BuildConfig
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import org.rekotlin.Store
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
|
@ -151,6 +153,9 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
@Inject
|
||||
lateinit var tokenDetailsFeatureToggles: TokenDetailsFeatureToggles
|
||||
|
||||
@Inject
|
||||
lateinit var scanCardProcessor: ScanCardProcessor
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
|
|
@ -168,12 +173,19 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
walletConnectRepository = walletConnect2Repository,
|
||||
walletConnectSessionsRepository = walletConnectSessionsRepository,
|
||||
tokenDetailsFeatureToggles = tokenDetailsFeatureToggles,
|
||||
scanCardProcessor = scanCardProcessor,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
Timber.plant(
|
||||
object : Timber.DebugTree() {
|
||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||
Logger.log(priority, tag, message, t)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
foregroundActivityObserver = ForegroundActivityObserver()
|
||||
|
|
@ -192,7 +204,7 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
if (LogConfig.network.blockchainSdkNetwork) {
|
||||
BlockchainSdkRetrofitBuilder.interceptors = listOf(
|
||||
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY },
|
||||
createNetworkLoggingInterceptor(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -13,7 +13,6 @@ sealed class MainScreen(
|
|||
class ScreenOpened : MainScreen("Screen opened")
|
||||
class ButtonScanCard : MainScreen("Button - Scan Card")
|
||||
class ButtonMyWallets : MainScreen("Button - My Wallets")
|
||||
class ButtonBuy : MainScreen("Button - Buy")
|
||||
|
||||
class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreen(
|
||||
event = "Enable Biometric",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
sealed class MyWallets(
|
||||
event: String,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -72,26 +72,8 @@ sealed class Onboarding(
|
|||
class SetupFinished : Twins("Twin Setup Finished")
|
||||
}
|
||||
|
||||
class PinScreenOpened : Onboarding("Onboarding", "PIN screen opened")
|
||||
class ButtonSetPinCode : Onboarding("Onboarding", "Button - Set PIN Code")
|
||||
class CardConnectionScreenOpened : Onboarding("Onboarding", "Card Connection Screen Opened")
|
||||
class ButtonConnect : Onboarding("Onboarding", "Button - Connect")
|
||||
class PinCodeSet : Onboarding("Onboarding", "PIN Code Set")
|
||||
|
||||
class KYCScreenOpened : Onboarding("Onboarding", "KYC screen opened")
|
||||
class KYCStarted : Onboarding("Onboarding", "KYC Started")
|
||||
class KYCInProgress : Onboarding("Onboarding", "KYC In Progress")
|
||||
class KYCRejected : Onboarding("Onboarding", "KYC Rejected")
|
||||
|
||||
class ClaimScreenOpened : Onboarding("Onboarding", "Claim Screen Opened")
|
||||
class ButtonClaim : Onboarding("Onboarding", "Button - Claim")
|
||||
class ClaimWasSuccessfully : Onboarding("Onboarding", "Claim Was Successfully")
|
||||
|
||||
class ButtonChat : Onboarding("Onboarding", "Button - Chat")
|
||||
|
||||
class NotEnoughGasError : Onboarding("Onboarding", "Not Enough Gas Error")
|
||||
class CardNotPassedError : Onboarding("Onboarding", "Card Not Passed Error")
|
||||
|
||||
class EnableBiometrics(state: AnalyticsParam.OnOffState) : Onboarding(
|
||||
category = "Onboarding / Biometric",
|
||||
event = "Enable Biometric",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.features.details.ui.details.SocialNetwork
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam.CurrencyType
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.common.analytics.handlers.appsFlyer
|
||||
|
||||
import com.appsflyer.AFInAppEventType
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.tap.common.analytics.handlers.firebase
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.api.ErrorEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.converters.AnalyticsErrorConverter
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.common.analytics.paramsInterceptor
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
package com.tangem.tap.common.analytics.paramsInterceptor
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class LinkedCardContextInterceptor(
|
||||
private val scanResponse: ScanResponse,
|
||||
scanResponse: ScanResponse,
|
||||
val parent: LinkedCardContextInterceptor? = null,
|
||||
) : ParamsInterceptor {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import android.content.Context
|
|||
import android.util.Log
|
||||
import coil.ImageLoader
|
||||
import coil.util.Logger
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import timber.log.Timber
|
||||
|
||||
private const val COIL_LOG_TAG = "COIL"
|
||||
|
|
@ -18,14 +18,7 @@ fun createCoilImageLoader(context: Context, logEnabled: Boolean = false): ImageL
|
|||
logger(CoilTimberLogger())
|
||||
okHttpClient {
|
||||
OkHttpClient.Builder()
|
||||
.addNetworkInterceptor(
|
||||
HttpLoggingInterceptor { message ->
|
||||
Timber.tag(COIL_LOG_TAG).d(message)
|
||||
}
|
||||
.apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
},
|
||||
)
|
||||
.addNetworkInterceptor(createNetworkLoggingInterceptor())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.tap.domain.scanCard.DefaultScanCardProcessor
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object CardDomainModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideScanCardUseCase(): ScanCardProcessor = DefaultScanCardProcessor()
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.tokens.repository.TokensRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ViewModelComponent
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
|
||||
@Module
|
||||
@InstallIn(ViewModelComponent::class)
|
||||
internal object TokensDomainModule {
|
||||
|
||||
@Provides
|
||||
@ViewModelScoped
|
||||
fun provideGetTokenListUseCase(
|
||||
tokensRepository: TokensRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) = GetTokenListUseCase(tokensRepository, quotesRepository, networksRepository, dispatchers)
|
||||
}
|
||||
|
|
@ -2,21 +2,22 @@ package com.tangem.tap.domain.scanCard
|
|||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
|
||||
// TODO: Remove this object after feature toggle was removed and use ScanCardUseCase instead
|
||||
internal object ScanCardProcessor {
|
||||
internal class DefaultScanCardProcessor : ScanCardProcessor {
|
||||
private val isNewCardScanningEnabled: Boolean
|
||||
get() = store.state.daggerGraphState
|
||||
.get(DaggerGraphState::customTokenFeatureToggles)
|
||||
.isNewCardScanningEnabled
|
||||
|
||||
suspend fun scan(
|
||||
cardId: String? = null,
|
||||
allowsRequestAccessCodeFromRepository: Boolean = false,
|
||||
override suspend fun scan(
|
||||
cardId: String?,
|
||||
allowsRequestAccessCodeFromRepository: Boolean,
|
||||
): CompletionResult<ScanResponse> {
|
||||
return if (isNewCardScanningEnabled) {
|
||||
UseCaseScanProcessor.scan(cardId, allowsRequestAccessCodeFromRepository)
|
||||
|
|
@ -26,15 +27,15 @@ internal object ScanCardProcessor {
|
|||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun scan(
|
||||
analyticsEvent: AnalyticsEvent? = null,
|
||||
cardId: String? = null,
|
||||
onProgressStateChange: suspend (showProgress: Boolean) -> Unit = {},
|
||||
onScanStateChange: suspend (scanInProgress: Boolean) -> Unit = {},
|
||||
onWalletNotCreated: suspend () -> Unit = {},
|
||||
disclaimerWillShow: () -> Unit = {},
|
||||
onFailure: suspend (error: TangemError) -> Unit = {},
|
||||
onSuccess: suspend (scanResponse: ScanResponse) -> Unit = {},
|
||||
override suspend fun scan(
|
||||
analyticsEvent: AnalyticsEvent?,
|
||||
cardId: String?,
|
||||
onProgressStateChange: suspend (showProgress: Boolean) -> Unit,
|
||||
onScanStateChange: suspend (scanInProgress: Boolean) -> Unit,
|
||||
onWalletNotCreated: suspend () -> Unit,
|
||||
disclaimerWillShow: () -> Unit,
|
||||
onFailure: suspend (error: TangemError) -> Unit,
|
||||
onSuccess: suspend (scanResponse: ScanResponse) -> Unit,
|
||||
) {
|
||||
if (isNewCardScanningEnabled) {
|
||||
UseCaseScanProcessor.scan(
|
||||
|
|
@ -6,7 +6,7 @@ import com.tangem.common.core.TangemSdkError
|
|||
import com.tangem.common.doOnFailure
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.scanCard
|
|||
import arrow.fx.coroutines.resourceScope
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.scanCard.chains
|
|||
import arrow.core.Either
|
||||
import arrow.core.right
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
import com.tangem.domain.core.chain.Chain
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ class ResetToFactorySettingsTask : CardSessionRunnable<Card> {
|
|||
}
|
||||
|
||||
private fun resetBackup(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit) {
|
||||
val backupStatus = session.environment.card?.backupStatus
|
||||
if (backupStatus == null || backupStatus == Card.BackupStatus.NoBackup) {
|
||||
if (session.environment.card?.backupStatus?.isActive != true) {
|
||||
callback(CompletionResult.Success(session.environment.card!!))
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
|
|
@ -36,7 +37,6 @@ import okhttp3.Interceptor
|
|||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
|
@ -56,8 +56,9 @@ class WalletConnectManager {
|
|||
.addInterceptor(RetryInterceptor())
|
||||
.build()
|
||||
}
|
||||
|
||||
private val interceptor by lazy {
|
||||
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
|
||||
createNetworkLoggingInterceptor()
|
||||
}
|
||||
|
||||
private var sessions: MutableMap<Topic, WalletConnectActiveData> = mutableMapOf()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
||||
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
|
||||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
|
||||
import com.tangem.tap.domain.userWalletList.di.provideRuntimeImplementation
|
||||
import com.tangem.tap.domain.userWalletList.isLockedSync
|
||||
|
|
@ -33,6 +32,7 @@ import com.tangem.tap.features.demo.DemoHelper
|
|||
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -74,7 +74,8 @@ class DetailsMiddleware {
|
|||
is DetailsAction.AccessCodeRecovery -> accessCodeRecoveryMiddleware.handle(state, action)
|
||||
DetailsAction.ScanCard -> {
|
||||
scope.launch {
|
||||
ScanCardProcessor.scan(allowsRequestAccessCodeFromRepository = true)
|
||||
store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor)
|
||||
.scan(allowsRequestAccessCodeFromRepository = true)
|
||||
.doOnSuccess { scanResponse ->
|
||||
// if we use biometric, scanResponse in GlobalState is null, and crashes NPE on twin cards
|
||||
store.dispatch(GlobalAction.SaveScanResponse(scanResponse))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.home.redux
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.entities.IndeterminateProgressButton
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.common.doOnResult
|
|||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
|
@ -21,12 +21,12 @@ import com.tangem.tap.common.extensions.onUserWalletSelected
|
|||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
||||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.features.home.BELARUS_COUNTRY_CODE
|
||||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware.BUY_WALLET_URL
|
||||
import com.tangem.tap.features.send.redux.states.ButtonState
|
||||
import com.tangem.tap.features.signin.redux.SignInAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
|
|
@ -78,7 +78,7 @@ private fun readCard(analyticsEvent: AnalyticsEvent?) = scope.launch {
|
|||
useBiometricsForAccessCode = preferencesStorage.shouldSaveAccessCodes,
|
||||
)
|
||||
|
||||
ScanCardProcessor.scan(
|
||||
store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan(
|
||||
analyticsEvent = analyticsEvent,
|
||||
onProgressStateChange = { showProgress ->
|
||||
if (showProgress) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.features.wallet.redux
|
|||
import android.content.Context
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.common.BlockchainNetwork
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import com.tangem.tap.common.extensions.dispatchErrorNotification
|
|||
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletState
|
||||
import com.tangem.tap.features.wallet.redux.models.WalletDialog
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.userWalletsListManager
|
||||
|
|
@ -102,7 +102,8 @@ class MultiWalletMiddleware {
|
|||
}
|
||||
|
||||
private fun scanAndUpdateCard(selectedUserWallet: UserWallet) = scope.launch(Dispatchers.Default) {
|
||||
ScanCardProcessor.scan(selectedUserWallet.cardId, allowsRequestAccessCodeFromRepository = true)
|
||||
store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor)
|
||||
.scan(cardId = selectedUserWallet.cardId, allowsRequestAccessCodeFromRepository = true)
|
||||
.flatMap { scanResponse ->
|
||||
userWalletsListManager.update(
|
||||
userWalletId = selectedUserWallet.walletId,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ import com.tangem.tap.domain.model.TotalFiatBalance
|
|||
import com.tangem.tap.domain.model.WalletStoreModel
|
||||
import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
||||
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
|
||||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.domain.userWalletList.unlockIfLockable
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
|
@ -133,7 +133,7 @@ internal class WalletSelectorMiddleware {
|
|||
useBiometricsForAccessCode = preferencesStorage.shouldSaveAccessCodes,
|
||||
)
|
||||
|
||||
ScanCardProcessor.scan(
|
||||
store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan(
|
||||
analyticsEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.MyWallets),
|
||||
onWalletNotCreated = {
|
||||
// No need to rollback policy, continue with the policy set before the card scan
|
||||
|
|
@ -208,7 +208,7 @@ internal class WalletSelectorMiddleware {
|
|||
private suspend fun unlockUserWalletWithScannedCard(userWallet: UserWallet): CompletionResult<Unit> {
|
||||
Analytics.send(MyWallets.Button.WalletUnlockTapped())
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(userWallet.scanResponse)
|
||||
return ScanCardProcessor.scan()
|
||||
return store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan()
|
||||
.map { scanResponse ->
|
||||
val scannedUserWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()
|
||||
if (scannedUserWalletId == userWallet.walletId) {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ import com.tangem.tap.common.extensions.dispatchWithMain
|
|||
import com.tangem.tap.common.extensions.onUserWalletSelected
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
||||
import com.tangem.tap.domain.scanCard.ScanCardProcessor
|
||||
import com.tangem.tap.domain.userWalletList.unlockIfLockable
|
||||
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
|
||||
import com.tangem.tap.features.signin.redux.SignInAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Middleware
|
||||
import timber.log.Timber
|
||||
|
|
@ -103,7 +103,7 @@ internal class WelcomeMiddleware {
|
|||
tangemSdkManager.setAccessCodeRequestPolicy(
|
||||
useBiometricsForAccessCode = preferencesStorage.shouldSaveAccessCodes,
|
||||
)
|
||||
ScanCardProcessor.scan(
|
||||
store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan(
|
||||
analyticsEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.SignIn),
|
||||
onSuccess = { scanResponse ->
|
||||
scope.launch { onCardScanned(scanResponse) }
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.proxy.redux
|
|||
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.ScanCardUseCase
|
||||
import com.tangem.features.tester.api.TesterRouter
|
||||
import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles
|
||||
|
|
@ -27,6 +28,7 @@ data class DaggerGraphState(
|
|||
val walletConnectInteractor: WalletConnectInteractor? = null,
|
||||
val tokenDetailsFeatureToggles: TokenDetailsFeatureToggles? = null,
|
||||
val tokenDetailsRouter: TokenDetailsRouter? = null,
|
||||
val scanCardProcessor: ScanCardProcessor? = null,
|
||||
) : StateType {
|
||||
|
||||
inline fun <reified T> get(getDependency: DaggerGraphState.() -> T?): T {
|
||||
|
|
|
|||
|
|
@ -13,5 +13,7 @@ dependencies {
|
|||
kapt(deps.hilt.kapt)
|
||||
|
||||
/** Core shouldn't depends on core, but in case with utils and logging its necessary */
|
||||
implementation(project(":core:utils"))
|
||||
implementation(projects.core.utils)
|
||||
|
||||
implementation(projects.core.analytics.models)
|
||||
}
|
||||
1
core/analytics/models/.gitignore
vendored
Normal file
1
core/analytics/models/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
4
core/analytics/models/build.gradle.kts
Normal file
4
core/analytics/models/build.gradle.kts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
plugins {
|
||||
alias(deps.plugins.kotlin.jvm)
|
||||
id("configuration")
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.core.analytics
|
||||
package com.tangem.core.analytics.models
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -1,18 +1,9 @@
|
|||
package com.tangem.core.analytics
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventFilter
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsFilterHolder
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsHandlerHolder
|
||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||
import com.tangem.core.analytics.api.ParamsInterceptorHolder
|
||||
import com.tangem.core.analytics.api.*
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.core.analytics.api
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.core.analytics.api
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.core.analytics.api
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ dependencies {
|
|||
implementation(deps.moshi)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.okHttp)
|
||||
implementation(deps.okHttp.logging)
|
||||
implementation(deps.okHttp.prettyLogging)
|
||||
implementation(deps.retrofit)
|
||||
implementation(deps.retrofit.moshi)
|
||||
implementation(deps.reactive.network)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.datasource.api.common
|
||||
|
||||
import android.util.Log
|
||||
import com.ihsanbal.logging.Level
|
||||
import com.ihsanbal.logging.LoggingInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ fun createRetrofitInstance(
|
|||
}
|
||||
interceptors.forEach { okHttpBuilder.addInterceptor(it) }
|
||||
|
||||
if (logEnabled) okHttpBuilder.addInterceptor(createHttpLoggingInterceptor())
|
||||
if (logEnabled) okHttpBuilder.addInterceptor(createNetworkLoggingInterceptor())
|
||||
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
|
|
@ -31,6 +33,9 @@ fun createRetrofitInstance(
|
|||
.build()
|
||||
}
|
||||
|
||||
private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
fun createNetworkLoggingInterceptor(): Interceptor {
|
||||
return LoggingInterceptor.Builder()
|
||||
.setLevel(Level.BODY)
|
||||
.log(Log.VERBOSE)
|
||||
.build()
|
||||
}
|
||||
|
|
@ -63,9 +63,7 @@ class NetworkModule {
|
|||
@PromotionOneInch
|
||||
fun providePromotionOneInchApi(authProvider: AuthProvider, @NetworkMoshi moshi: Moshi): PromotionApi {
|
||||
val okClient = OkHttpClient.Builder()
|
||||
.addHeaders(
|
||||
AuthenticationHeader(authProvider),
|
||||
)
|
||||
.addHeaders(AuthenticationHeader(authProvider))
|
||||
.allowLogging()
|
||||
.callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||
.connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package com.tangem.datasource.utils
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import okhttp3.logging.HttpLoggingInterceptor.Level
|
||||
|
||||
/** Extension for adding headers [requestHeaders] to every [OkHttpClient] request */
|
||||
internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeader): OkHttpClient.Builder {
|
||||
|
|
@ -26,5 +25,10 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade
|
|||
*
|
||||
* @param level logging level. By default, only the request body.
|
||||
*/
|
||||
internal fun OkHttpClient.Builder.allowLogging(level: Level = Level.BODY): OkHttpClient.Builder =
|
||||
if (BuildConfig.DEBUG) addInterceptor(interceptor = HttpLoggingInterceptor().setLevel(level)) else this
|
||||
internal fun OkHttpClient.Builder.allowLogging(): OkHttpClient.Builder {
|
||||
return if (BuildConfig.DEBUG) {
|
||||
addInterceptor(interceptor = createNetworkLoggingInterceptor())
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
1
data/tokens/.gitignore
vendored
Normal file
1
data/tokens/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
17
data/tokens/build.gradle.kts
Normal file
17
data/tokens/build.gradle.kts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
plugins {
|
||||
alias(deps.plugins.kotlin.jvm)
|
||||
alias(deps.plugins.kotlin.kapt)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.wallets.models)
|
||||
|
||||
implementation(deps.kotlin.coroutines)
|
||||
|
||||
implementation(deps.arrow.core)
|
||||
|
||||
implementation(deps.hilt.core)
|
||||
kapt(deps.hilt.kapt)
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.data.tokens.di
|
||||
|
||||
import com.tangem.data.tokens.repository.DefaultNetworksRepository
|
||||
import com.tangem.data.tokens.repository.DefaultQuotesRepository
|
||||
import com.tangem.data.tokens.repository.DefaultTokensRepository
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.tokens.repository.TokensRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object TokensDataModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideTokensRepository(): TokensRepository = DefaultTokensRepository()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideQuotesRepository(): QuotesRepository = DefaultQuotesRepository()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideNetworksRepository(): NetworksRepository = DefaultNetworksRepository()
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
internal class DefaultNetworksRepository : NetworksRepository {
|
||||
|
||||
override fun getNetworks(networksIds: Set<Network.ID>): Either<TokensError, Set<Network>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getNetworkStatuses(
|
||||
userWalletId: UserWalletId,
|
||||
networks: Map<Network.ID, Set<Token.ID>>,
|
||||
refresh: Boolean,
|
||||
): Flow<Either<TokensError, Set<NetworkStatus>>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Quote
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
internal class DefaultQuotesRepository : QuotesRepository {
|
||||
|
||||
override fun getQuotes(tokensIds: Set<Token.ID>, refresh: Boolean): Flow<Either<TokensError, Set<Quote>>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.data.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.tokens.repository.TokensRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
internal class DefaultTokensRepository : TokensRepository {
|
||||
|
||||
override suspend fun sortTokens(
|
||||
userWalletId: UserWalletId,
|
||||
sortedTokensIds: Set<Token.ID>,
|
||||
isGrouped: Boolean,
|
||||
isSortedByBalance: Boolean,
|
||||
): Either<TokensError, Unit> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getTokens(userWalletId: UserWalletId, refresh: Boolean): Flow<Either<TokensError, Set<Token>>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun isTokensGrouped(userWalletId: UserWalletId): Flow<Either<TokensError, Boolean>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Either<TokensError, Boolean>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,11 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":domain:core"))
|
||||
implementation(projects.domain.core)
|
||||
// TODO: Remove after new card scan result was implemented
|
||||
implementation(project(":domain:models"))
|
||||
implementation(projects.domain.models)
|
||||
|
||||
implementation(projects.core.analytics.models)
|
||||
|
||||
implementation(deps.tangem.card.core)
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.domain.card
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
||||
interface ScanCardProcessor {
|
||||
|
||||
suspend fun scan(
|
||||
cardId: String? = null,
|
||||
allowsRequestAccessCodeFromRepository: Boolean = false,
|
||||
): CompletionResult<ScanResponse>
|
||||
|
||||
suspend fun scan(
|
||||
analyticsEvent: AnalyticsEvent? = null,
|
||||
cardId: String? = null,
|
||||
onProgressStateChange: suspend (showProgress: Boolean) -> Unit = {},
|
||||
onScanStateChange: suspend (scanInProgress: Boolean) -> Unit = {},
|
||||
onWalletNotCreated: suspend () -> Unit = {},
|
||||
disclaimerWillShow: () -> Unit = {},
|
||||
onFailure: suspend (error: TangemError) -> Unit = {},
|
||||
onSuccess: suspend (scanResponse: ScanResponse) -> Unit = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -22,12 +22,8 @@ dependencies {
|
|||
|
||||
/** Other libraries */
|
||||
implementation(deps.reKotlin)
|
||||
//TODO: refactoring: remove it when all network services moved to the datasource module
|
||||
implementation(deps.retrofit)
|
||||
implementation(deps.retrofit.moshi)
|
||||
implementation(deps.moshi)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.okHttp.logging)
|
||||
implementation(deps.timber)
|
||||
implementation(deps.kotlin.coroutines)
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ data class CardDTO(
|
|||
object NoBackup : BackupStatus()
|
||||
|
||||
val isActive: Boolean
|
||||
get() = this is Active || this is CardLinked
|
||||
get() = this is Active
|
||||
|
||||
companion object {
|
||||
internal fun fromSdkStatus(sdkStatus: Card.BackupStatus?): BackupStatus? {
|
||||
|
|
|
|||
1
domain/tokens/.gitignore
vendored
Normal file
1
domain/tokens/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
10
domain/tokens/build.gradle.kts
Normal file
10
domain/tokens/build.gradle.kts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
plugins {
|
||||
alias(deps.plugins.kotlin.jvm)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.domain.core)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.core.utils)
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// TODO: [REDACTED_JIRA]
|
||||
@file:Suppress("unused", "unused_parameter")
|
||||
|
||||
package com.tangem.domain.tokens
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.tokens.repository.TokensRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
class GetTokenListUseCase(
|
||||
private val tokensRepository: TokensRepository,
|
||||
private val quotesRepository: QuotesRepository,
|
||||
private val networksRepository: NetworksRepository,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
operator fun invoke(userWalletId: UserWalletId, refresh: Boolean = true): Flow<Either<TokensError, TokenList>> {
|
||||
return flowOf(TokensError.EmptyTokens.left())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.tangem.domain.tokens.error
|
||||
|
||||
sealed class TokensError {
|
||||
|
||||
object EmptyTokens : TokensError()
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
data class Network(
|
||||
val id: ID,
|
||||
val name: String,
|
||||
) {
|
||||
|
||||
@JvmInline
|
||||
value class ID(val value: String)
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import arrow.core.NonEmptySet
|
||||
|
||||
data class NetworkGroup(
|
||||
val networkId: Network.ID,
|
||||
val name: String,
|
||||
val tokens: NonEmptySet<TokenStatus>,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class NetworkStatus(
|
||||
val networkId: Network.ID,
|
||||
val value: Status,
|
||||
) {
|
||||
|
||||
sealed class Status {
|
||||
open val amounts: Map<Token.ID, BigDecimal>? = null
|
||||
}
|
||||
|
||||
object Unreachable : Status()
|
||||
|
||||
object MissedDerivation : Status()
|
||||
|
||||
data class TransactionInProgress(override val amounts: Map<Token.ID, BigDecimal>) : Status()
|
||||
|
||||
data class Verified(override val amounts: Map<Token.ID, BigDecimal>) : Status()
|
||||
|
||||
data class NoAccount(val amountToCreateAccount: BigDecimal) : Status()
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class Quote(
|
||||
val tokenId: Token.ID,
|
||||
val fiatRate: BigDecimal,
|
||||
val priceChange: BigDecimal,
|
||||
)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
data class Token(
|
||||
val id: ID,
|
||||
val networkId: Network.ID,
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val isCustom: Boolean,
|
||||
val isCoin: Boolean,
|
||||
) {
|
||||
|
||||
@JvmInline
|
||||
value class ID(val value: String)
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import arrow.core.NonEmptySet
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class TokenList {
|
||||
open val totalFiatBalance: FiatBalance = FiatBalance.Loading
|
||||
open val sortedBy: SortType = SortType.NONE
|
||||
|
||||
data class GroupedByNetwork(
|
||||
val groups: NonEmptySet<NetworkGroup>,
|
||||
override val totalFiatBalance: FiatBalance,
|
||||
override val sortedBy: SortType,
|
||||
) : TokenList()
|
||||
|
||||
data class Ungrouped(
|
||||
val tokens: NonEmptySet<TokenStatus>,
|
||||
override val totalFiatBalance: FiatBalance,
|
||||
override val sortedBy: SortType,
|
||||
) : TokenList()
|
||||
|
||||
object NotInitialized : TokenList()
|
||||
|
||||
enum class SortType {
|
||||
NONE, BALANCE,
|
||||
}
|
||||
|
||||
sealed class FiatBalance {
|
||||
object Loading : FiatBalance()
|
||||
|
||||
object Failed : FiatBalance()
|
||||
|
||||
data class Loaded(
|
||||
val amount: BigDecimal,
|
||||
val isAllAmountsSummarized: Boolean,
|
||||
) : FiatBalance()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class TokenStatus(
|
||||
val id: Token.ID,
|
||||
val networkId: Network.ID,
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val isCoin: Boolean,
|
||||
val value: Status,
|
||||
) {
|
||||
|
||||
sealed class Status {
|
||||
open val amount: BigDecimal? = null
|
||||
open val fiatAmount: BigDecimal? = null
|
||||
open val priceChange: BigDecimal? = null
|
||||
open val hasTransactionsInProgress: Boolean = false
|
||||
}
|
||||
|
||||
object Loading : Status()
|
||||
|
||||
object Unreachable : Status()
|
||||
|
||||
object MissedDerivation : Status()
|
||||
|
||||
object NoAccount : Status()
|
||||
|
||||
data class Loaded(
|
||||
override val amount: BigDecimal,
|
||||
override val fiatAmount: BigDecimal,
|
||||
override val priceChange: BigDecimal,
|
||||
override val hasTransactionsInProgress: Boolean,
|
||||
) : Status()
|
||||
|
||||
data class Custom(
|
||||
override val amount: BigDecimal,
|
||||
override val fiatAmount: BigDecimal?,
|
||||
override val priceChange: BigDecimal?,
|
||||
override val hasTransactionsInProgress: Boolean,
|
||||
) : Status()
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.domain.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
// FIXME: Use Raise as context instead of Effect when context receivers become stable
|
||||
// [REDACTED_JIRA]
|
||||
|
||||
/**
|
||||
* Repository for everything related to the blockchain networks
|
||||
* */
|
||||
interface NetworksRepository {
|
||||
|
||||
fun getNetworks(networksIds: Set<Network.ID>): Either<TokensError, Set<Network>>
|
||||
|
||||
fun getNetworkStatuses(
|
||||
userWalletId: UserWalletId,
|
||||
networks: Map<Network.ID, Set<Token.ID>>,
|
||||
refresh: Boolean,
|
||||
): Flow<Either<TokensError, Set<NetworkStatus>>>
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.domain.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Quote
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
// FIXME: Use Raise as context instead of Effect when context receivers become stable
|
||||
// [REDACTED_JIRA]
|
||||
|
||||
/**
|
||||
* Repository for everything related to the quotes of tokens
|
||||
* */
|
||||
interface QuotesRepository {
|
||||
|
||||
fun getQuotes(tokensIds: Set<Token.ID>, refresh: Boolean): Flow<Either<TokensError, Set<Quote>>>
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.domain.tokens.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.error.TokensError
|
||||
import com.tangem.domain.tokens.model.Token
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
// FIXME: Use Raise as context instead of Effect when context receivers become stable
|
||||
// [REDACTED_JIRA]
|
||||
|
||||
/**
|
||||
* Repository for everything related to the tokens of user wallet
|
||||
* */
|
||||
interface TokensRepository {
|
||||
|
||||
suspend fun sortTokens(
|
||||
userWalletId: UserWalletId,
|
||||
sortedTokensIds: Set<Token.ID>,
|
||||
isGrouped: Boolean,
|
||||
isSortedByBalance: Boolean,
|
||||
): Either<TokensError, Unit>
|
||||
|
||||
fun getTokens(userWalletId: UserWalletId, refresh: Boolean): Flow<Either<TokensError, Set<Token>>>
|
||||
|
||||
fun isTokensGrouped(userWalletId: UserWalletId): Flow<Either<TokensError, Boolean>>
|
||||
|
||||
fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Either<TokensError, Boolean>>
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ dependencies {
|
|||
/** Core modules */
|
||||
implementation(project(":common"))
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:datasource"))
|
||||
implementation(project(":core:utils"))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.learn2earn.analytics
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
internal sealed class Learn2earnEvents(
|
||||
category: String,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.learn2earn.domain.api
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
* Handler that helps determine a result of the Learn2earnWebViewActivity webView actions.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ dependencies {
|
|||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:datasource"))
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
implementation(project(":core:res"))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.onboarding.presentation.wallet2.analytics
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
sealed class SeedPhraseEvents(
|
||||
event: String,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ plugins {
|
|||
dependencies {
|
||||
/** Core modules */
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(project(":core:res"))
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.referral.analytics
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
sealed class ReferralEvents(event: String) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ plugins {
|
|||
dependencies {
|
||||
/** Core modules */
|
||||
implementation(project(":core:analytics"))
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.swap.analytics
|
||||
|
||||
import com.tangem.core.analytics.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
sealed class SwapEvents(
|
||||
event: String,
|
||||
|
|
@ -13,7 +13,6 @@ sealed class SwapEvents(
|
|||
)
|
||||
|
||||
object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked")
|
||||
object ReceiveTokenClicked : SwapEvents(event = "Receive Token Clicked")
|
||||
object ChooseTokenScreenOpened : SwapEvents(event = "Choose Token Screen Opened")
|
||||
object SearchTokenClicked : SwapEvents(event = "Searched Token Clicked")
|
||||
data class ButtonSwapClicked(val sendToken: String, val receiveToken: String) : SwapEvents(
|
||||
|
|
@ -24,7 +23,6 @@ sealed class SwapEvents(
|
|||
object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission")
|
||||
object ButtonPermissionApproveClicked : SwapEvents(event = "Button - Permission Approve")
|
||||
object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel")
|
||||
object ButtonPermitAndSwapClicked : SwapEvents(event = "Button - Permit and Swap")
|
||||
object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe")
|
||||
object SwapInProgressScreen : SwapEvents(event = "Swap in Progress Screen Opened")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ dependencies {
|
|||
|
||||
/** Other libraries */
|
||||
implementation(deps.kotlin.immutable.collections)
|
||||
implementation(deps.tangem.card.core)
|
||||
implementation(deps.tangem.blockchain)
|
||||
|
||||
/** DI */
|
||||
|
|
@ -37,14 +38,17 @@ dependencies {
|
|||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:navigation"))
|
||||
implementation(project(":core:ui"))
|
||||
implementation(projects.core.utils)
|
||||
|
||||
/** Feature Apis */
|
||||
implementation(project(":features:wallet:api"))
|
||||
|
||||
/** Domain modules */
|
||||
implementation(project(":common"))
|
||||
implementation(projects.domain.card)
|
||||
implementation(project(":domain:legacy"))
|
||||
implementation(project(":domain:models"))
|
||||
implementation(project(":domain:wallets"))
|
||||
implementation(project(":domain:wallets:models"))
|
||||
implementation(projects.domain.tokens)
|
||||
}
|
||||
|
|
@ -40,7 +40,8 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation
|
|||
startDestination = WalletScreens.WALLET.name,
|
||||
) {
|
||||
composable(WalletScreens.WALLET.name) {
|
||||
val viewModel = hiltViewModel<WalletViewModel>().apply { router = this@DefaultWalletRouter }
|
||||
val viewModel = hiltViewModel<WalletViewModel>()
|
||||
.apply { router = this@DefaultWalletRouter }
|
||||
WalletScreen(state = viewModel.uiState)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,18 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.common.doOnFailure
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletTopBarConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
|
|
@ -19,7 +26,12 @@ import kotlin.properties.Delegates
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@HiltViewModel
|
||||
internal class WalletViewModel @Inject constructor() : ViewModel() {
|
||||
internal class WalletViewModel @Inject constructor(
|
||||
@Suppress("unused") // TODO: [REDACTED_JIRA]
|
||||
private val getTokenListUseCase: GetTokenListUseCase,
|
||||
private val scanCardProcessor: ScanCardProcessor,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ViewModel() {
|
||||
|
||||
/** Feature router */
|
||||
var router: InnerWalletRouter by Delegates.notNull()
|
||||
|
|
@ -30,16 +42,32 @@ internal class WalletViewModel @Inject constructor() : ViewModel() {
|
|||
|
||||
// TODO: [REDACTED_TASK_KEY] Use production data instead of WalletPreviewData
|
||||
private fun getInitialState(): WalletStateHolder = WalletPreviewData.multicurrencyWalletScreenState.copy(
|
||||
onBackClick = { router.popBackStack() },
|
||||
topBarConfig = WalletTopBarConfig(
|
||||
onScanCardClick = { router.openOrganizeTokensScreen() },
|
||||
onMoreClick = { router.openDetailsScreen() },
|
||||
),
|
||||
onBackClick = ::onBackClick,
|
||||
topBarConfig = createTopBarConfig(),
|
||||
walletsListConfig = WalletPreviewData.multicurrencyWalletScreenState.walletsListConfig.copy(
|
||||
onWalletChange = ::selectWallet,
|
||||
),
|
||||
)
|
||||
|
||||
private fun onBackClick() {
|
||||
router.popBackStack()
|
||||
}
|
||||
|
||||
private fun createTopBarConfig(): WalletTopBarConfig {
|
||||
return WalletTopBarConfig(
|
||||
onScanCardClick = ::onScanCardClick,
|
||||
onMoreClick = { router.openDetailsScreen() },
|
||||
)
|
||||
}
|
||||
|
||||
private fun onScanCardClick() {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
scanCardProcessor.scan(allowsRequestAccessCodeFromRepository = true)
|
||||
.doOnSuccess { /* [REDACTED_TODO_COMMENT] */ }
|
||||
.doOnFailure { /* [REDACTED_TODO_COMMENT] */ }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_TASK_KEY] Use production data instead of WalletPreviewData
|
||||
private fun selectWallet(index: Int) {
|
||||
if (uiState.walletsListConfig.selectedWalletIndex == index) return
|
||||
|
|
|
|||
|
|
@ -75,12 +75,14 @@ arrow = "1.2.0-RC"
|
|||
reactiveNetwork = "3.0.8"
|
||||
walletConnectCore = "1.17.0"
|
||||
walletConnectWeb3 = "1.10.0"
|
||||
prettyLogger = "2.2.0"
|
||||
okHttp-prettyLogging = "3.1.0"
|
||||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
#tangemBlockchainSdk = "develop-240"
|
||||
tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-266"
|
||||
tangemBlockchainSdk = "develop-281"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-273"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||
# endregion Tangem
|
||||
|
||||
|
|
@ -201,7 +203,7 @@ material = { module = "com.google.android.material:material", version.ref = "goo
|
|||
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
|
||||
moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }
|
||||
okHttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
okHttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||
okHttp-prettyLogging = { module = "com.github.ihsanbal:LoggingInterceptor", version.ref = "okHttp-prettyLogging" }
|
||||
otaliastudiosCameraView = { module = "com.otaliastudios:cameraview", version.ref = "otaliastudiosCameraView" }
|
||||
shopify-buy = { module = "com.shopify.mobilebuysdk:buy3", version.ref = "shopifyBuySdk" }
|
||||
spongecastle-core = { module = "com.madgag.spongycastle:core", version.ref = "spongycastleCryptoCore" }
|
||||
|
|
@ -222,4 +224,5 @@ arrow-fx = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" }
|
|||
reactive-network = { module = "com.github.pwittchen:reactivenetwork-rx2", version.ref = "reactiveNetwork" }
|
||||
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" }
|
||||
# endregion Other
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ include(":common")
|
|||
|
||||
// region Core modules
|
||||
include(":core:analytics")
|
||||
include(":core:analytics:models")
|
||||
include(":core:datasource")
|
||||
include(":core:featuretoggles")
|
||||
include(":core:navigation")
|
||||
|
|
@ -80,8 +81,10 @@ include(":domain:core")
|
|||
include(":domain:card")
|
||||
include(":domain:wallets")
|
||||
include(":domain:wallets:models")
|
||||
include(":domain:tokens")
|
||||
// endregion Domain modules
|
||||
|
||||
// region Data modules
|
||||
include(":data:tokens")
|
||||
include(":data:source:preferences")
|
||||
// endregion Data modules
|
||||
Loading…
Add table
Add a link
Reference in a new issue