Updated on 2026-08-14
This commit is contained in:
commit
3c2a006fb9
331 changed files with 8261 additions and 1670 deletions
|
|
@ -1,6 +1,9 @@
|
|||
package com.tangem.tap
|
||||
|
||||
import android.app.Application
|
||||
import android.os.StrictMode
|
||||
import android.os.StrictMode.ThreadPolicy
|
||||
import android.os.StrictMode.VmPolicy
|
||||
import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
import coil.ImageLoader
|
||||
|
|
@ -71,9 +74,7 @@ import com.tangem.tap.proxy.redux.DaggerGraphState
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import dagger.hilt.EntryPoints
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.*
|
||||
import org.rekotlin.Store
|
||||
import kotlin.collections.set
|
||||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
|
||||
|
|
@ -228,12 +229,32 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
|
||||
// endregion
|
||||
|
||||
private val appScope = MainScope()
|
||||
|
||||
override fun onCreate() {
|
||||
enableStrictModeInDebug()
|
||||
super.onCreate()
|
||||
|
||||
init()
|
||||
}
|
||||
|
||||
updateLogFiles()
|
||||
private fun enableStrictModeInDebug() {
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictMode.setThreadPolicy(
|
||||
ThreadPolicy.Builder()
|
||||
.detectDiskReads()
|
||||
.detectDiskWrites()
|
||||
.detectAll()
|
||||
.penaltyLog()
|
||||
.build(),
|
||||
)
|
||||
StrictMode.setVmPolicy(
|
||||
VmPolicy.Builder()
|
||||
.detectLeakedSqlLiteObjects()
|
||||
.detectLeakedClosableObjects()
|
||||
.penaltyLog()
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLogFiles() {
|
||||
|
|
@ -260,18 +281,31 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
foregroundActivityObserver = ForegroundActivityObserver()
|
||||
registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks)
|
||||
|
||||
// TODO: Try to performance and user experience.
|
||||
// [REDACTED_JIRA]
|
||||
// We need to initialize the toggles and excludedBlockchainsManager before the MainActivity starts using them.
|
||||
runBlocking {
|
||||
awaitAll(
|
||||
async { featureTogglesManager.init() },
|
||||
async { excludedBlockchainsManager.init() },
|
||||
async { initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize()) },
|
||||
async {
|
||||
featureTogglesManager.init()
|
||||
},
|
||||
async {
|
||||
excludedBlockchainsManager.init()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
loadNativeLibraries()
|
||||
appScope.launch {
|
||||
initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize())
|
||||
launch(Dispatchers.IO) {
|
||||
loadNativeLibraries()
|
||||
walletConnect2Repository.init(
|
||||
projectId = environmentConfigStorage.getConfigSync().walletConnectProjectId,
|
||||
)
|
||||
updateLogFiles()
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionHandler.append(blockchainExceptionHandler)
|
||||
|
||||
if (LogConfig.network.blockchainSdkNetwork) {
|
||||
BlockchainSdkRetrofitBuilder.interceptors = listOf(
|
||||
createNetworkLoggingInterceptor(),
|
||||
|
|
@ -287,9 +321,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
appPreferencesStore = appPreferencesStore,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
appStateHolder.mainStore = store
|
||||
|
||||
walletConnect2Repository.init(projectId = environmentConfigStorage.getConfigSync().walletConnectProjectId)
|
||||
appStateHolder.mainStore = store
|
||||
}
|
||||
|
||||
private fun createReduxStore(): Store<AppState> {
|
||||
|
|
|
|||
|
|
@ -20,18 +20,22 @@ internal class DefaultVisaAuthTokenStorage @Inject constructor(
|
|||
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||
) : VisaAuthTokenStorage {
|
||||
|
||||
private val secureStorage = AndroidSecureStorage(
|
||||
preferences = SecureStorage.createEncryptedSharedPreferences(
|
||||
context = applicationContext,
|
||||
storageName = "visa_auth_storage",
|
||||
),
|
||||
)
|
||||
private val secureStorage by lazy {
|
||||
AndroidSecureStorage(
|
||||
preferences = SecureStorage.createEncryptedSharedPreferences(
|
||||
context = applicationContext,
|
||||
storageName = "visa_auth_storage",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
private val moshi by lazy {
|
||||
Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
}
|
||||
|
||||
private val tokensAdapter = moshi.adapter(VisaAuthTokens::class.java)
|
||||
private val tokensAdapter by lazy { moshi.adapter(VisaAuthTokens::class.java) }
|
||||
|
||||
override suspend fun store(cardId: String, tokens: VisaAuthTokens) = withContext(dispatcherProvider.io) {
|
||||
val json = tokensAdapter.toJson(tokens)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ class DefaultVisaOTPStorage @Inject constructor(
|
|||
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||
) : VisaOTPStorage {
|
||||
|
||||
private val secureStorage = AndroidSecureStorage(
|
||||
preferences = SecureStorage.createEncryptedSharedPreferences(
|
||||
context = applicationContext,
|
||||
storageName = "visa_otp_storage",
|
||||
),
|
||||
)
|
||||
private val secureStorage by lazy {
|
||||
AndroidSecureStorage(
|
||||
preferences = SecureStorage.createEncryptedSharedPreferences(
|
||||
context = applicationContext,
|
||||
storageName = "visa_otp_storage",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun saveOTP(cardId: String, data: VisaOtpData) = withContext(dispatcherProvider.io) {
|
||||
secureStorage.store(data.rootOTP, VISA_ROOT_OTP_KEY_PREFIX + cardId)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.domain.managetokens.*
|
|||
import com.tangem.domain.managetokens.repository.CustomTokensRepository
|
||||
import com.tangem.domain.managetokens.repository.ManageTokensRepository
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteFetcher
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
|
|
@ -73,6 +74,7 @@ internal object ManageTokensDomainModule {
|
|||
stakingRepository: StakingRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): SaveManagedTokensUseCase {
|
||||
return SaveManagedTokensUseCase(
|
||||
|
|
@ -84,6 +86,7 @@ internal object ManageTokensDomainModule {
|
|||
stakingRepository = stakingRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import com.tangem.domain.card.repository.DerivationsRepository
|
|||
import com.tangem.domain.markets.*
|
||||
import com.tangem.domain.markets.repositories.MarketsTokenRepository
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteFetcher
|
||||
import com.tangem.domain.quotes.single.SingleQuoteSupplier
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
|
|
@ -49,8 +51,16 @@ object MarketsDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetTokenQuotesUseCase(quotesRepository: QuotesRepository): GetCurrencyQuotesUseCase {
|
||||
return GetCurrencyQuotesUseCase(quotesRepository = quotesRepository)
|
||||
fun provideGetTokenQuotesUseCase(
|
||||
quotesRepository: QuotesRepository,
|
||||
singleQuoteSupplier: SingleQuoteSupplier,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): GetCurrencyQuotesUseCase {
|
||||
return GetCurrencyQuotesUseCase(
|
||||
quotesRepository = quotesRepository,
|
||||
singleQuoteSupplier = singleQuoteSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -63,6 +73,7 @@ object MarketsDomainModule {
|
|||
stakingRepository: StakingRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): SaveMarketTokensUseCase {
|
||||
return SaveMarketTokensUseCase(
|
||||
|
|
@ -73,6 +84,7 @@ object MarketsDomainModule {
|
|||
stakingRepository = stakingRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
|||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.quotes.QuotesRepositoryV2
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteFetcher
|
||||
import com.tangem.domain.quotes.single.SingleQuoteSupplier
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.operations.BaseCurrenciesStatusesOperations
|
||||
|
|
@ -35,6 +38,7 @@ internal object TokensDomainModule {
|
|||
stakingRepository: StakingRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): AddCryptoCurrenciesUseCase {
|
||||
return AddCryptoCurrenciesUseCase(
|
||||
|
|
@ -43,6 +47,7 @@ internal object TokensDomainModule {
|
|||
stakingRepository = stakingRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -55,6 +60,7 @@ internal object TokensDomainModule {
|
|||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchTokenListUseCase {
|
||||
return FetchTokenListUseCase(
|
||||
|
|
@ -63,6 +69,7 @@ internal object TokensDomainModule {
|
|||
quotesRepository = quotesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -168,6 +175,7 @@ internal object TokensDomainModule {
|
|||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
singleNetworkStatusFetcher: SingleNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchCurrencyStatusUseCase {
|
||||
return FetchCurrencyStatusUseCase(
|
||||
|
|
@ -176,6 +184,7 @@ internal object TokensDomainModule {
|
|||
quotesRepository = quotesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
singleNetworkStatusFetcher = singleNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -188,6 +197,7 @@ internal object TokensDomainModule {
|
|||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): FetchCardTokenListUseCase {
|
||||
return FetchCardTokenListUseCase(
|
||||
|
|
@ -196,6 +206,7 @@ internal object TokensDomainModule {
|
|||
quotesRepository = quotesRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -364,10 +375,14 @@ internal object TokensDomainModule {
|
|||
fun provideRefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
): RefreshMultiCurrencyWalletQuotesUseCase {
|
||||
return RefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -386,20 +401,26 @@ internal object TokensDomainModule {
|
|||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
quotesRepositoryV2: QuotesRepositoryV2,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
|
||||
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
singleQuoteSupplier: SingleQuoteSupplier,
|
||||
): BaseCurrenciesStatusesOperations {
|
||||
return CachedCurrenciesStatusesOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
quotesRepositoryV2 = quotesRepositoryV2,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
|
||||
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
singleQuoteSupplier = singleQuoteSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -410,21 +431,33 @@ internal object TokensDomainModule {
|
|||
tokensFeatureToggles: TokensFeatureToggles,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
quotesRepositoryV2: QuotesRepositoryV2,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
|
||||
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
multiQuoteFetcher: MultiQuoteFetcher,
|
||||
singleQuoteSupplier: SingleQuoteSupplier,
|
||||
): BaseCurrencyStatusOperations {
|
||||
return CachedCurrenciesStatusesOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
quotesRepositoryV2 = quotesRepositoryV2,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
singleNetworkStatusSupplier = singleNetworkStatusSupplier,
|
||||
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
|
||||
multiNetworkStatusFetcher = multiNetworkStatusFetcher,
|
||||
multiQuoteFetcher = multiQuoteFetcher,
|
||||
singleQuoteSupplier = singleQuoteSupplier,
|
||||
tokensFeatureToggles = tokensFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCryptoCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase {
|
||||
return GetCryptoCurrenciesUseCase(currenciesRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -147,4 +147,22 @@ internal object TransactionDomainModule {
|
|||
fun provideGetAllowanceUseCase(transactionRepository: TransactionRepository): GetAllowanceUseCase {
|
||||
return GetAllowanceUseCase(transactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providePrepareForSendUseCase(
|
||||
transactionRepository: TransactionRepository,
|
||||
cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
): PrepareForSendUseCase {
|
||||
return PrepareForSendUseCase(transactionRepository, cardSdkConfigRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSignUseCase(
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
): SignUseCase {
|
||||
return SignUseCase(cardSdkConfigRepository, walletManagersFacade)
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@ import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSy
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.features.nft.NFTFeatureToggles
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -172,8 +174,16 @@ internal object WalletsDomainModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCardImageUseCase(onlineCardVerifier: OnlineCardVerifier): GetCardImageUseCase {
|
||||
return GetCardImageUseCase(verifier = onlineCardVerifier)
|
||||
fun provideGetCardImageUseCase(
|
||||
onlineCardVerifier: OnlineCardVerifier,
|
||||
cardArtworksProvider: CardArtworksProvider,
|
||||
cardSdkFeatureToggles: CardSdkFeatureToggles,
|
||||
): GetCardImageUseCase {
|
||||
return GetCardImageUseCase(
|
||||
verifier = onlineCardVerifier,
|
||||
cardArtworksProvider = cardArtworksProvider,
|
||||
cardSdkFeatureToggles = cardSdkFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.common.TwinCardNumber
|
|||
import com.tangem.domain.common.getTwinCardNumber
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.wallets.models.Artwork
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.api.models.CardVerifyAndGetInfo
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ suspend fun CardDTO.getOrLoadCardArtworkUrl(
|
|||
if (artworkId.isNullOrEmpty()) {
|
||||
ifAnyError()
|
||||
} else {
|
||||
OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
CardArtworksProvider.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,10 @@ internal class DefaultTokensFeatureToggles(
|
|||
|
||||
override val isNetworksLoadingRefactoringEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "NETWORKS_LOADING_REFACTORING_ENABLED")
|
||||
|
||||
override val isQuotesLoadingRefactoringEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "QUOTES_LOADING_REFACTORING_ENABLED")
|
||||
|
||||
override val isStakingLoadingRefactoringEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "STAKING_LOADING_REFACTORING_ENABLED")
|
||||
}
|
||||
|
|
@ -21,8 +21,6 @@ internal data class UserWalletPublicInformation(
|
|||
val name: String,
|
||||
@Json(name = "walletId")
|
||||
val walletId: UserWalletId,
|
||||
@Json(name = "artworkUrl")
|
||||
val artworkUrl: String,
|
||||
@Json(name = "cardsInWallet")
|
||||
val cardsInWallet: Set<String>,
|
||||
@Json(name = "scanResponse")
|
||||
|
|
|
|||
|
|
@ -20,9 +20,12 @@ internal class DefaultUserWalletsPublicInformationRepository(
|
|||
moshi: Moshi,
|
||||
private val secureStorage: SecureStorage,
|
||||
) : UserWalletsPublicInformationRepository {
|
||||
private val publicInformationAdapter: JsonAdapter<List<UserWalletPublicInformation>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, UserWalletPublicInformation::class.java),
|
||||
)
|
||||
|
||||
private val publicInformationAdapter: JsonAdapter<List<UserWalletPublicInformation>> by lazy {
|
||||
moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, UserWalletPublicInformation::class.java),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun save(userWallet: UserWallet, canOverride: Boolean): CompletionResult<Unit> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,15 @@ internal class DefaultUserWalletsSensitiveInformationRepository(
|
|||
private val secureStorage: SecureStorage,
|
||||
) : UserWalletsSensitiveInformationRepository {
|
||||
|
||||
private val sensitiveInformationAdapter: JsonAdapter<UserWalletSensitiveInformation> = moshi.adapter(
|
||||
UserWalletSensitiveInformation::class.java,
|
||||
)
|
||||
private val encryptedSensitiveInformationMapAdapter: JsonAdapter<Map<String, ByteArray>> = moshi.adapter(
|
||||
Types.newParameterizedType(Map::class.java, String::class.java, ByteArray::class.java),
|
||||
)
|
||||
private val sensitiveInformationAdapter: JsonAdapter<UserWalletSensitiveInformation> by lazy {
|
||||
moshi.adapter(UserWalletSensitiveInformation::class.java)
|
||||
}
|
||||
|
||||
private val encryptedSensitiveInformationMapAdapter: JsonAdapter<Map<String, ByteArray>> by lazy {
|
||||
moshi.adapter(
|
||||
Types.newParameterizedType(Map::class.java, String::class.java, ByteArray::class.java),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun save(userWallet: UserWallet, encryptionKey: ByteArray?): CompletionResult<Unit> {
|
||||
if (encryptionKey == null) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ internal val UserWallet.publicInformation: UserWalletPublicInformation
|
|||
get() = UserWalletPublicInformation(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
artworkUrl = artworkUrl,
|
||||
cardsInWallet = cardsInWallet,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
scanResponse = scanResponse.copy(
|
||||
|
|
@ -31,7 +30,6 @@ internal fun UserWalletPublicInformation.toUserWallet(): UserWallet {
|
|||
return UserWallet(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
artworkUrl = artworkUrl,
|
||||
cardsInWallet = cardsInWallet,
|
||||
scanResponse = scanResponse,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.Message
|
|||
import com.tangem.blockchain.blockchains.ethereum.EthereumGasLoader
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumUtils
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumUtils.toKeccak
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.extensions.*
|
||||
|
|
@ -16,6 +15,7 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.Basic.TransactionSent.MemoType
|
||||
import com.tangem.data.walletconnect.network.ethereum.LegacySdkHelper
|
||||
import com.tangem.operations.sign.SignHashCommand
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
|
|
@ -357,36 +357,9 @@ class WalletConnectSdkHelper {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createMessageData(message: WcSignMessage): ByteArray {
|
||||
val messageData = try {
|
||||
message.data.removePrefix(HEX_PREFIX).hexToBytes()
|
||||
} catch (exception: Exception) {
|
||||
message.data.asciiToHex()?.hexToBytes() ?: byteArrayOf()
|
||||
}
|
||||
private fun createMessageData(message: WcSignMessage): ByteArray = LegacySdkHelper.createMessageData(message.data)
|
||||
|
||||
val prefixData = (ETH_MESSAGE_PREFIX + messageData.size.toString()).toByteArray()
|
||||
return (prefixData + messageData).toKeccak()
|
||||
}
|
||||
|
||||
private fun String.hexToAscii(): String? {
|
||||
return try {
|
||||
removePrefix(HEX_PREFIX).hexToBytes()
|
||||
.map {
|
||||
val char = it.toInt().toChar()
|
||||
if (char.isAscii()) char else return null
|
||||
}
|
||||
.joinToString("")
|
||||
} catch (exception: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.asciiToHex(): String? {
|
||||
return map {
|
||||
if (!it.isAscii()) return null
|
||||
Integer.toHexString(it.code)
|
||||
}.joinToString("")
|
||||
}
|
||||
private fun String.hexToAscii(): String? = LegacySdkHelper.hexToAscii(hex = this)
|
||||
|
||||
suspend fun signPersonalMessage(
|
||||
hashToSign: ByteArray,
|
||||
|
|
@ -535,7 +508,6 @@ class WalletConnectSdkHelper {
|
|||
"{\"signature\":\"$signature\",\"publicKey\":\"$publicKey\"}"
|
||||
|
||||
private companion object {
|
||||
const val ETH_MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n"
|
||||
const val HEX_PREFIX = "0x"
|
||||
const val DEFAULT_MAX_GASLIMIT = 350000
|
||||
// TODO remove after [REDACTED_JIRA]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import com.tangem.domain.wallets.models.UserWallet
|
|||
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.BackupValidator
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.operations.backup.BackupService
|
||||
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||
import com.tangem.sdk.extensions.localizedDescriptionRes
|
||||
|
|
@ -250,7 +250,7 @@ private suspend fun loadArtworkForCard(cardId: String, cardPublicKey: ByteArray,
|
|||
if (artworkId.isNullOrEmpty()) {
|
||||
defaultArtwork ?: Uri.EMPTY
|
||||
} else {
|
||||
Uri.parse(OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId))
|
||||
Uri.parse(CardArtworksProvider.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId))
|
||||
}
|
||||
}
|
||||
is Result.Failure -> defaultArtwork ?: Uri.EMPTY
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
|||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.operations.attestation.CardArtworksProvider
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
||||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository
|
||||
|
|
@ -76,5 +77,6 @@ data class DaggerGraphState(
|
|||
val settingsManager: SettingsManager? = null,
|
||||
val uiMessageSender: UiMessageSender? = null,
|
||||
val onlineCardVerifier: OnlineCardVerifier? = null,
|
||||
val cardArworksProvider: CardArtworksProvider? = null,
|
||||
val userWalletBuilderFactory: UserWalletBuilder.Factory? = null,
|
||||
) : StateType
|
||||
|
|
@ -12,13 +12,12 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
|||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||
import com.tangem.features.nft.component.NFTCollectionsComponent
|
||||
import com.tangem.features.nft.component.NFTDetailsComponent
|
||||
import com.tangem.features.nft.component.NFTReceiveComponent
|
||||
import com.tangem.features.nft.component.*
|
||||
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
||||
import com.tangem.features.onramp.component.*
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsComponent
|
||||
import com.tangem.features.send.api.SendComponent
|
||||
import com.tangem.features.send.v2.api.NFTSendComponent
|
||||
import com.tangem.features.send.v2.api.SendFeatureToggles
|
||||
import com.tangem.features.staking.api.StakingComponent
|
||||
import com.tangem.features.swap.SwapComponent
|
||||
|
|
@ -83,9 +82,8 @@ internal class ChildFactory @Inject constructor(
|
|||
private val sendComponentFactoryV2: com.tangem.features.send.v2.api.SendComponent.Factory,
|
||||
private val sendFeatureToggles: SendFeatureToggles,
|
||||
private val redesignedWalletConnectComponentFactory: RedisegnedWalletConnectComponent.Factory,
|
||||
private val nftCollectionsComponentFactory: NFTCollectionsComponent.Factory,
|
||||
private val nftReceiveComponentFactory: NFTReceiveComponent.Factory,
|
||||
private val nftDetailsComponentFactory: NFTDetailsComponent.Factory,
|
||||
private val nftComponentFactory: NFTComponent.Factory,
|
||||
private val nftSendComponentFactory: NFTSendComponent.Factory,
|
||||
private val testerRouter: TesterRouter,
|
||||
private val routingFeatureToggles: RoutingFeatureToggles,
|
||||
private val walletConnectFeatureToggles: WalletConnectFeatureToggles,
|
||||
|
|
@ -405,24 +403,23 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = walletComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.NFTCollections ->
|
||||
is AppRoute.NFT ->
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = NFTCollectionsComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftCollectionsComponentFactory,
|
||||
params = NFTComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftComponentFactory,
|
||||
)
|
||||
is AppRoute.NFTReceive ->
|
||||
is AppRoute.NFTSend -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = NFTReceiveComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftReceiveComponentFactory,
|
||||
)
|
||||
is AppRoute.NFTDetails ->
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = NFTDetailsComponent.Params(userWalletId = route.userWalletId, nftAsset = route.nftAsset),
|
||||
componentFactory = nftDetailsComponentFactory,
|
||||
params = NFTSendComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
nftAsset = route.nftAsset,
|
||||
nftCollectionName = route.nftCollectionName,
|
||||
),
|
||||
componentFactory = nftSendComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.OnboardingNote,
|
||||
is AppRoute.SaveWallet,
|
||||
is AppRoute.OnboardingOther,
|
||||
|
|
@ -757,24 +754,23 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = storiesComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.NFTCollections ->
|
||||
is AppRoute.NFT ->
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = NFTCollectionsComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftCollectionsComponentFactory,
|
||||
params = NFTComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftComponentFactory,
|
||||
)
|
||||
is AppRoute.NFTReceive ->
|
||||
is AppRoute.NFTSend -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = NFTReceiveComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = nftReceiveComponentFactory,
|
||||
)
|
||||
is AppRoute.NFTDetails ->
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = NFTDetailsComponent.Params(userWalletId = route.userWalletId, nftAsset = route.nftAsset),
|
||||
componentFactory = nftDetailsComponentFactory,
|
||||
params = NFTSendComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
nftAsset = route.nftAsset,
|
||||
nftCollectionName = route.nftCollectionName,
|
||||
),
|
||||
componentFactory = nftSendComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
private val defaultUserWallet = UserWallet(
|
||||
name = "",
|
||||
walletId = defaultUserWalletId,
|
||||
artworkUrl = "",
|
||||
cardsInWallet = setOf(),
|
||||
isMultiCurrency = false,
|
||||
scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap()),
|
||||
|
|
|
|||
|
|
@ -194,7 +194,6 @@ internal class BiometricUserWalletsListManagerTest(private val model: Model) {
|
|||
return UserWallet(
|
||||
name = "Wallet $id",
|
||||
walletId = UserWalletId(stringValue = id),
|
||||
artworkUrl = "",
|
||||
cardsInWallet = emptySet(),
|
||||
isMultiCurrency = true,
|
||||
hasBackupError = false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue