Updated on 2026-08-14
This commit is contained in:
parent
d77875be51
commit
e45d91b15e
15 changed files with 389 additions and 67 deletions
|
|
@ -4,10 +4,15 @@ import com.tangem.datasource.api.tangemTech.models.CardInfoBody
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletIdBody
|
import com.tangem.datasource.api.tangemTech.models.WalletIdBody
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletType
|
import com.tangem.datasource.api.tangemTech.models.WalletType
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||||
|
|
||||||
object WalletIdBodyConverter {
|
object WalletIdBodyConverter {
|
||||||
|
|
||||||
fun convert(userWallet: UserWallet, publicKeys: Map<String, String>? = null): WalletIdBody {
|
fun convert(
|
||||||
|
userWallet: UserWallet,
|
||||||
|
conversionData: AppsFlyerConversionData? = null,
|
||||||
|
publicKeys: Map<String, String>? = null,
|
||||||
|
): WalletIdBody {
|
||||||
return WalletIdBody(
|
return WalletIdBody(
|
||||||
walletId = userWallet.walletId.stringValue,
|
walletId = userWallet.walletId.stringValue,
|
||||||
name = userWallet.name,
|
name = userWallet.name,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ data class UserTokensResponse(
|
||||||
@Json(name = "notifyStatus") val notifyStatus: Boolean? = null,
|
@Json(name = "notifyStatus") val notifyStatus: Boolean? = null,
|
||||||
@Json(name = "name") val walletName: String? = null,
|
@Json(name = "name") val walletName: String? = null,
|
||||||
@Json(name = "type") val walletType: WalletType? = null,
|
@Json(name = "type") val walletType: WalletType? = null,
|
||||||
|
@Json(name = "ref") val refcode: String? = null,
|
||||||
|
@Json(name = "campaign") val campaign: String? = null,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,6 @@ data class WalletIdBody(
|
||||||
@Json(name = "name") val name: String,
|
@Json(name = "name") val name: String,
|
||||||
@Json(name = "type") val walletType: WalletType? = null,
|
@Json(name = "type") val walletType: WalletType? = null,
|
||||||
@Json(name = "cards") val cards: List<CardInfoBody>? = null,
|
@Json(name = "cards") val cards: List<CardInfoBody>? = null,
|
||||||
|
@Json(name = "ref") val refcode: String? = null,
|
||||||
|
@Json(name = "campaign") val campaign: String? = null,
|
||||||
)
|
)
|
||||||
|
|
@ -30,7 +30,11 @@ class WalletIdBodyConverterTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
val result = WalletIdBodyConverter.convert(userWallet, publicKeys)
|
val result = WalletIdBodyConverter.convert(
|
||||||
|
userWallet = userWallet,
|
||||||
|
conversionData = null,
|
||||||
|
publicKeys = publicKeys,
|
||||||
|
)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(result).isEqualTo(
|
assertThat(result).isEqualTo(
|
||||||
|
|
@ -68,7 +72,11 @@ class WalletIdBodyConverterTest {
|
||||||
val publicKeys = emptyMap<String, String>()
|
val publicKeys = emptyMap<String, String>()
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
val result = WalletIdBodyConverter.convert(userWallet, publicKeys)
|
val result = WalletIdBodyConverter.convert(
|
||||||
|
userWallet = userWallet,
|
||||||
|
conversionData = null,
|
||||||
|
publicKeys = publicKeys,
|
||||||
|
)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(result).isEqualTo(
|
assertThat(result).isEqualTo(
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,18 @@ import com.tangem.data.account.fetcher.DefaultWalletAccountsFetcher.FetchResult
|
||||||
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
||||||
import com.tangem.data.common.currency.UserTokensResponseAccountIdEnricher
|
import com.tangem.data.common.currency.UserTokensResponseAccountIdEnricher
|
||||||
import com.tangem.data.common.currency.UserTokensSaver
|
import com.tangem.data.common.currency.UserTokensSaver
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException.Code
|
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException.Code
|
||||||
import com.tangem.datasource.api.common.response.ETAG_HEADER
|
import com.tangem.datasource.api.common.response.ETAG_HEADER
|
||||||
import com.tangem.datasource.api.common.response.isNetworkError
|
import com.tangem.datasource.api.common.response.isNetworkError
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
|
||||||
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
|
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
@ -27,26 +23,21 @@ import javax.inject.Singleton
|
||||||
/**
|
/**
|
||||||
* Handles errors that occur during the fetching of wallet accounts
|
* Handles errors that occur during the fetching of wallet accounts
|
||||||
*
|
*
|
||||||
* @property tangemTechApi API for network requests
|
|
||||||
* @property userWalletsStore provides access to user wallets storage
|
|
||||||
* @property userTokensSaver saves user tokens to the storage
|
* @property userTokensSaver saves user tokens to the storage
|
||||||
* @property userTokensResponseStore provides access to user token responses.
|
* @property userTokensResponseStore provides access to user token responses.
|
||||||
* @property defaultWalletAccountsResponseFactory creates [GetWalletAccountsResponse] from [UserTokensResponse]
|
* @property defaultWalletAccountsResponseFactory creates [GetWalletAccountsResponse] from [UserTokensResponse]
|
||||||
* @property dispatchers dispatchers
|
* @property walletServerBinder binds user wallets on the server
|
||||||
*
|
*
|
||||||
* @see DefaultWalletAccountsFetcher
|
* @see DefaultWalletAccountsFetcher
|
||||||
*
|
*
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
@Suppress("LongParameterList")
|
|
||||||
@Singleton
|
@Singleton
|
||||||
internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
||||||
private val tangemTechApi: TangemTechApi,
|
|
||||||
private val userWalletsStore: UserWalletsStore,
|
|
||||||
private val userTokensSaver: UserTokensSaver,
|
private val userTokensSaver: UserTokensSaver,
|
||||||
private val userTokensResponseStore: UserTokensResponseStore,
|
private val userTokensResponseStore: UserTokensResponseStore,
|
||||||
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory,
|
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val walletServerBinder: WalletServerBinder,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -119,13 +110,7 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
||||||
|
|
||||||
*/
|
*/
|
||||||
private suspend fun createWallet(userWalletId: UserWalletId): String? {
|
private suspend fun createWallet(userWalletId: UserWalletId): String? {
|
||||||
val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId) ?: return null
|
val creationResponse = walletServerBinder.bind(userWalletId)
|
||||||
|
|
||||||
val creationResponse = withContext(dispatchers.io) {
|
|
||||||
tangemTechApi.createWallet(
|
|
||||||
body = WalletIdBodyConverter.convert(userWallet),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (creationResponse is ApiResponse.Success && creationResponse.code == Code.CREATED) {
|
return if (creationResponse is ApiResponse.Success && creationResponse.code == Code.CREATED) {
|
||||||
creationResponse.headers[ETAG_HEADER]?.firstOrNull()
|
creationResponse.headers[ETAG_HEADER]?.firstOrNull()
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,22 @@ import com.tangem.data.account.converter.createGetWalletAccountsResponse
|
||||||
import com.tangem.data.account.converter.createWalletAccountDTO
|
import com.tangem.data.account.converter.createWalletAccountDTO
|
||||||
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
||||||
import com.tangem.data.common.currency.UserTokensSaver
|
import com.tangem.data.common.currency.UserTokensSaver
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException.Code
|
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException.Code
|
||||||
import com.tangem.datasource.api.common.response.ETAG_HEADER
|
import com.tangem.datasource.api.common.response.ETAG_HEADER
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletIdBody
|
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletType
|
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
import io.mockk.clearMocks
|
||||||
import io.mockk.*
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
@ -33,18 +32,16 @@ import org.junit.jupiter.api.TestInstance
|
||||||
class FetchWalletAccountsErrorHandlerTest {
|
class FetchWalletAccountsErrorHandlerTest {
|
||||||
|
|
||||||
private val tangemTechApi: TangemTechApi = mockk()
|
private val tangemTechApi: TangemTechApi = mockk()
|
||||||
private val userWalletsStore: UserWalletsStore = mockk()
|
private val walletServerBinder: WalletServerBinder = mockk()
|
||||||
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
||||||
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true)
|
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true)
|
||||||
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory = mockk()
|
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory = mockk()
|
||||||
|
|
||||||
private val handler = FetchWalletAccountsErrorHandler(
|
private val handler = FetchWalletAccountsErrorHandler(
|
||||||
tangemTechApi = tangemTechApi,
|
walletServerBinder = walletServerBinder,
|
||||||
userWalletsStore = userWalletsStore,
|
|
||||||
userTokensSaver = userTokensSaver,
|
userTokensSaver = userTokensSaver,
|
||||||
userTokensResponseStore = userTokensResponseStore,
|
userTokensResponseStore = userTokensResponseStore,
|
||||||
defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory,
|
defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory,
|
||||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val pushWalletAccounts: suspend (List<WalletAccountDTO>, String) -> GetWalletAccountsResponse =
|
private val pushWalletAccounts: suspend (List<WalletAccountDTO>, String) -> GetWalletAccountsResponse =
|
||||||
|
|
@ -55,7 +52,7 @@ class FetchWalletAccountsErrorHandlerTest {
|
||||||
fun setupEach() {
|
fun setupEach() {
|
||||||
clearMocks(
|
clearMocks(
|
||||||
tangemTechApi,
|
tangemTechApi,
|
||||||
userWalletsStore,
|
walletServerBinder,
|
||||||
userTokensSaver,
|
userTokensSaver,
|
||||||
userTokensResponseStore,
|
userTokensResponseStore,
|
||||||
defaultWalletAccountsResponseFactory,
|
defaultWalletAccountsResponseFactory,
|
||||||
|
|
@ -112,22 +109,7 @@ class FetchWalletAccountsErrorHandlerTest {
|
||||||
code = Code.CREATED,
|
code = Code.CREATED,
|
||||||
)
|
)
|
||||||
|
|
||||||
val walletName = "Wallet"
|
coEvery { walletServerBinder.bind(userWalletId) } returns apiResponse
|
||||||
val userWallet = mockk<UserWallet.Cold> {
|
|
||||||
every { this@mockk.walletId } returns userWalletId
|
|
||||||
every { this@mockk.name } returns walletName
|
|
||||||
}
|
|
||||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
|
||||||
|
|
||||||
coEvery {
|
|
||||||
tangemTechApi.createWallet(
|
|
||||||
WalletIdBody(
|
|
||||||
walletId = userWalletId.stringValue,
|
|
||||||
name = walletName,
|
|
||||||
walletType = WalletType.COLD,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} returns apiResponse
|
|
||||||
coEvery { pushWalletAccounts(listOf(accountDTO), eTagValue) } returns savedAccountsResponse
|
coEvery { pushWalletAccounts(listOf(accountDTO), eTagValue) } returns savedAccountsResponse
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -142,13 +124,7 @@ class FetchWalletAccountsErrorHandlerTest {
|
||||||
// Assert
|
// Assert
|
||||||
coVerify {
|
coVerify {
|
||||||
userTokensSaver.pushWithRetryer(userWalletId, response = savedAccountsResponse.toUserTokensResponse())
|
userTokensSaver.pushWithRetryer(userWalletId, response = savedAccountsResponse.toUserTokensResponse())
|
||||||
tangemTechApi.createWallet(
|
walletServerBinder.bind(userWalletId)
|
||||||
WalletIdBody(
|
|
||||||
walletId = userWalletId.stringValue,
|
|
||||||
name = walletName,
|
|
||||||
walletType = WalletType.COLD,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
pushWalletAccounts(listOf(accountDTO), eTagValue)
|
pushWalletAccounts(listOf(accountDTO), eTagValue)
|
||||||
storeWalletAccounts(userWalletId, savedAccountsResponse)
|
storeWalletAccounts(userWalletId, savedAccountsResponse)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ package com.tangem.data.common.currency
|
||||||
|
|
||||||
import com.tangem.data.common.api.safeApiCall
|
import com.tangem.data.common.api.safeApiCall
|
||||||
import com.tangem.data.common.tokens.UserTokensBackwardCompatibility
|
import com.tangem.data.common.tokens.UserTokensBackwardCompatibility
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.common.response.isNetworkError
|
import com.tangem.datasource.api.common.response.isNetworkError
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
|
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletType
|
import com.tangem.datasource.api.tangemTech.models.WalletType
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||||
|
|
@ -27,6 +28,8 @@ class UserTokensSaver(
|
||||||
private val userTokensResponseStore: UserTokensResponseStore,
|
private val userTokensResponseStore: UserTokensResponseStore,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val addressesEnricher: UserTokensResponseAddressesEnricher,
|
private val addressesEnricher: UserTokensResponseAddressesEnricher,
|
||||||
|
private val walletServerBinder: WalletServerBinder,
|
||||||
|
private val appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||||
private val pushTokensRetryerPool: RetryerPool,
|
private val pushTokensRetryerPool: RetryerPool,
|
||||||
) {
|
) {
|
||||||
|
|
@ -69,6 +72,8 @@ class UserTokensSaver(
|
||||||
|
|
||||||
pushNew(userWallet = userWallet, response = enrichedResponse, onFailSend = onFailSend)
|
pushNew(userWallet = userWallet, response = enrichedResponse, onFailSend = onFailSend)
|
||||||
} else {
|
} else {
|
||||||
|
val conversionData = appsFlyerConversionStore.get()
|
||||||
|
|
||||||
val enrichedResponse = response.enrichIf(userWalletId = userWalletId, condition = useEnricher).copy(
|
val enrichedResponse = response.enrichIf(userWalletId = userWalletId, condition = useEnricher).copy(
|
||||||
walletName = userWallet.name,
|
walletName = userWallet.name,
|
||||||
walletType = WalletType.from(userWallet),
|
walletType = WalletType.from(userWallet),
|
||||||
|
|
@ -116,7 +121,7 @@ class UserTokensSaver(
|
||||||
apiResponse.cause.isNetworkError(ApiResponseError.HttpException.Code.NOT_FOUND)
|
apiResponse.cause.isNetworkError(ApiResponseError.HttpException.Code.NOT_FOUND)
|
||||||
|
|
||||||
if (isWalletNotFound) {
|
if (isWalletNotFound) {
|
||||||
tangemTechApi.createWallet(body = WalletIdBodyConverter.convert(userWallet)).bind()
|
walletServerBinder.bind(userWallet).bind()
|
||||||
|
|
||||||
tangemTechApi.saveTokens(
|
tangemTechApi.saveTokens(
|
||||||
userId = userWallet.walletId.stringValue,
|
userId = userWallet.walletId.stringValue,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ import com.tangem.data.common.cache.etag.ETagsStore
|
||||||
import com.tangem.data.common.currency.*
|
import com.tangem.data.common.currency.*
|
||||||
import com.tangem.data.common.quote.DefaultQuotesFetcher
|
import com.tangem.data.common.quote.DefaultQuotesFetcher
|
||||||
import com.tangem.data.common.quote.QuotesFetcher
|
import com.tangem.data.common.quote.QuotesFetcher
|
||||||
|
import com.tangem.data.common.wallet.DefaultWalletServerBinder
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
|
|
@ -72,6 +75,8 @@ internal object DataCommonModule {
|
||||||
userTokensResponseStore: UserTokensResponseStore,
|
userTokensResponseStore: UserTokensResponseStore,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
addressesEnricher: UserTokensResponseAddressesEnricher,
|
addressesEnricher: UserTokensResponseAddressesEnricher,
|
||||||
|
walletServerBinder: WalletServerBinder,
|
||||||
|
appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
accountsFeatureToggles: AccountsFeatureToggles,
|
accountsFeatureToggles: AccountsFeatureToggles,
|
||||||
): UserTokensSaver {
|
): UserTokensSaver {
|
||||||
return UserTokensSaver(
|
return UserTokensSaver(
|
||||||
|
|
@ -84,6 +89,8 @@ internal object DataCommonModule {
|
||||||
pushTokensRetryerPool = RetryerPool(
|
pushTokensRetryerPool = RetryerPool(
|
||||||
coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default),
|
coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default),
|
||||||
),
|
),
|
||||||
|
walletServerBinder = walletServerBinder,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,4 +105,20 @@ internal object DataCommonModule {
|
||||||
fun provideETagsStore(appPreferencesStore: AppPreferencesStore): ETagsStore {
|
fun provideETagsStore(appPreferencesStore: AppPreferencesStore): ETagsStore {
|
||||||
return DefaultETagsStore(appPreferencesStore = appPreferencesStore)
|
return DefaultETagsStore(appPreferencesStore = appPreferencesStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideWalletServerBinder(
|
||||||
|
userWalletsStore: UserWalletsStore,
|
||||||
|
appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
|
tangemTechApi: TangemTechApi,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
): WalletServerBinder {
|
||||||
|
return DefaultWalletServerBinder(
|
||||||
|
userWalletsStore = userWalletsStore,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
|
tangemTechApi = tangemTechApi,
|
||||||
|
dispatchers = dispatchers,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.tangem.data.common.wallet
|
||||||
|
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
internal class DefaultWalletServerBinder(
|
||||||
|
private val userWalletsStore: UserWalletsStore,
|
||||||
|
private val appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
|
private val tangemTechApi: TangemTechApi,
|
||||||
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
|
) : WalletServerBinder {
|
||||||
|
|
||||||
|
override suspend fun bind(userWalletId: UserWalletId): ApiResponse<Unit>? {
|
||||||
|
val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId) ?: return null
|
||||||
|
|
||||||
|
return bind(userWallet)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun bind(userWallet: UserWallet): ApiResponse<Unit> {
|
||||||
|
val conversionData = appsFlyerConversionStore.get()
|
||||||
|
|
||||||
|
return withContext(dispatchers.io) {
|
||||||
|
tangemTechApi.createWallet(
|
||||||
|
body = WalletIdBodyConverter.convert(userWallet, conversionData),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.tangem.data.common.wallet
|
||||||
|
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
interface WalletServerBinder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a wallet to the server using its [userWalletId].
|
||||||
|
* Returns an [ApiResponse] indicating the result of the binding operation,
|
||||||
|
* or null if the binding was not performed.
|
||||||
|
*/
|
||||||
|
suspend fun bind(userWalletId: UserWalletId): ApiResponse<Unit>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a wallet to the server using the provided [userWallet].
|
||||||
|
* Returns an [ApiResponse] indicating the result of the binding operation.
|
||||||
|
*/
|
||||||
|
suspend fun bind(userWallet: UserWallet): ApiResponse<Unit>
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package com.tangem.data.common.currency
|
package com.tangem.data.common.currency
|
||||||
|
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletType
|
import com.tangem.datasource.api.tangemTech.models.WalletType
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||||
|
|
@ -27,6 +29,8 @@ class UserTokensSaverTest {
|
||||||
private val accountsFeatureToggles = mockk<AccountsFeatureToggles> {
|
private val accountsFeatureToggles = mockk<AccountsFeatureToggles> {
|
||||||
every { this@mockk.isFeatureEnabled } returns true
|
every { this@mockk.isFeatureEnabled } returns true
|
||||||
}
|
}
|
||||||
|
private val walletServerBinder: WalletServerBinder = mockk()
|
||||||
|
private val appsFlyerConversionStore: AppsFlyerConversionStore = mockk()
|
||||||
|
|
||||||
private val userTokensSaver: UserTokensSaver = UserTokensSaver(
|
private val userTokensSaver: UserTokensSaver = UserTokensSaver(
|
||||||
tangemTechApi = tangemTechApi,
|
tangemTechApi = tangemTechApi,
|
||||||
|
|
@ -34,13 +38,21 @@ class UserTokensSaverTest {
|
||||||
userTokensResponseStore = userTokensResponseStore,
|
userTokensResponseStore = userTokensResponseStore,
|
||||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||||
addressesEnricher = enricher,
|
addressesEnricher = enricher,
|
||||||
|
walletServerBinder = walletServerBinder,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
accountsFeatureToggles = accountsFeatureToggles,
|
||||||
pushTokensRetryerPool = mockk(),
|
pushTokensRetryerPool = mockk(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun resetMocks() {
|
fun resetMocks() {
|
||||||
clearMocks(tangemTechApi, userWalletsStore, userTokensResponseStore, enricher)
|
clearMocks(
|
||||||
|
tangemTechApi,
|
||||||
|
userWalletsStore,
|
||||||
|
userTokensResponseStore,
|
||||||
|
enricher,
|
||||||
|
walletServerBinder,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -109,7 +121,6 @@ class UserTokensSaverTest {
|
||||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||||
coEvery { enricher(userWalletId, response) } returns enrichedResponse
|
coEvery { enricher(userWalletId, response) } returns enrichedResponse
|
||||||
coEvery { tangemTechApi.saveTokens(any(), any()) } returns ApiResponse.Error(error) as ApiResponse<Unit>
|
coEvery { tangemTechApi.saveTokens(any(), any()) } returns ApiResponse.Error(error) as ApiResponse<Unit>
|
||||||
coEvery { tangemTechApi.createWallet(body = any()) } returns ApiResponse.Error(error) as ApiResponse<Unit>
|
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
userTokensSaver.push(
|
userTokensSaver.push(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
package com.tangem.data.common.wallet
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.datasource.api.tangemTech.models.WalletIdBody
|
||||||
|
import com.tangem.datasource.api.tangemTech.models.WalletType
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||||
|
import io.mockk.*
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.Nested
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
/**
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class DefaultWalletServerBinderTest {
|
||||||
|
|
||||||
|
private val userWalletsStore: UserWalletsStore = mockk()
|
||||||
|
private val appsFlyerConversionStore: AppsFlyerConversionStore = mockk()
|
||||||
|
private val tangemTechApi: TangemTechApi = mockk()
|
||||||
|
private val dispatchers: CoroutineDispatcherProvider = TestingCoroutineDispatcherProvider()
|
||||||
|
|
||||||
|
private val binder = DefaultWalletServerBinder(
|
||||||
|
userWalletsStore = userWalletsStore,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
|
tangemTechApi = tangemTechApi,
|
||||||
|
dispatchers = dispatchers
|
||||||
|
)
|
||||||
|
|
||||||
|
private val userWalletId = UserWalletId("011")
|
||||||
|
private val userWallet = mockk<UserWallet.Cold> {
|
||||||
|
every { this@mockk.walletId } returns userWalletId
|
||||||
|
every { this@mockk.name } returns "Wallet"
|
||||||
|
}
|
||||||
|
private val conversionData = AppsFlyerConversionData(refcode = "refcode", campaign = "campaign")
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
fun tearDown() {
|
||||||
|
clearMocks(userWalletsStore, appsFlyerConversionStore, tangemTechApi)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
inner class BindUserWalletId {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind successfully`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
refcode = "refcode",
|
||||||
|
campaign = "campaign",
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Success(Unit)
|
||||||
|
|
||||||
|
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns conversionData
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWalletId = userWalletId)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
userWalletsStore.getSyncOrNull(userWalletId)
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind will skipped if userWalletsStore returns null`() = runTest {
|
||||||
|
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns null
|
||||||
|
|
||||||
|
val actual = binder.bind(userWalletId = userWalletId)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(null)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
userWalletsStore.getSyncOrNull(userWalletId)
|
||||||
|
}
|
||||||
|
|
||||||
|
coVerify(inverse = true) {
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind successfully if appsFlyerConversionStore returns null`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Success(Unit)
|
||||||
|
|
||||||
|
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns null
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWalletId = userWalletId)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
userWalletsStore.getSyncOrNull(userWalletId)
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind returns error if request is failed`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
refcode = "refcode",
|
||||||
|
campaign = "campaign",
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Error(ApiResponseError.TimeoutException()) as ApiResponse<Unit>
|
||||||
|
|
||||||
|
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns conversionData
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWalletId = userWalletId)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
userWalletsStore.getSyncOrNull(userWalletId)
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
inner class BindUserWallet {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind successfully`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
refcode = "refcode",
|
||||||
|
campaign = "campaign",
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Success(Unit)
|
||||||
|
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns conversionData
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWallet = userWallet)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind successfully if appsFlyerConversionStore returns null`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Success(Unit)
|
||||||
|
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns null
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWallet = userWallet)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bind returns error if request is failed`() = runTest {
|
||||||
|
val requestBody = WalletIdBody(
|
||||||
|
walletId = userWalletId.stringValue,
|
||||||
|
name = "Wallet",
|
||||||
|
walletType = WalletType.COLD,
|
||||||
|
refcode = "refcode",
|
||||||
|
campaign = "campaign",
|
||||||
|
)
|
||||||
|
val apiResponse = ApiResponse.Error(ApiResponseError.TimeoutException()) as ApiResponse<Unit>
|
||||||
|
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns conversionData
|
||||||
|
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
|
||||||
|
|
||||||
|
val actual = binder.bind(userWallet = userWallet)
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isEqualTo(apiResponse)
|
||||||
|
|
||||||
|
coVerifyOrder {
|
||||||
|
appsFlyerConversionStore.get()
|
||||||
|
tangemTechApi.createWallet(requestBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package com.tangem.data.wallets
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import arrow.core.left
|
import arrow.core.left
|
||||||
import arrow.core.right
|
import arrow.core.right
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.data.wallets.converters.UserWalletRemoteInfoConverter
|
import com.tangem.data.wallets.converters.UserWalletRemoteInfoConverter
|
||||||
import com.tangem.datasource.api.common.AuthProvider
|
import com.tangem.datasource.api.common.AuthProvider
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
|
@ -14,6 +15,7 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
|
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
|
||||||
import com.tangem.datasource.api.tangemTech.models.*
|
import com.tangem.datasource.api.tangemTech.models.*
|
||||||
import com.tangem.datasource.api.tangemTech.models.SeedPhraseNotificationDTO.Status
|
import com.tangem.datasource.api.tangemTech.models.SeedPhraseNotificationDTO.Status
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
|
|
@ -46,6 +48,8 @@ internal class DefaultWalletsRepository(
|
||||||
private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<SeedPhraseNotificationsStatuses>,
|
private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<SeedPhraseNotificationsStatuses>,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val authProvider: AuthProvider,
|
private val authProvider: AuthProvider,
|
||||||
|
private val walletServerBinder: WalletServerBinder,
|
||||||
|
private val appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||||
private val moshi: com.squareup.moshi.Moshi,
|
private val moshi: com.squareup.moshi.Moshi,
|
||||||
) : WalletsRepository {
|
) : WalletsRepository {
|
||||||
|
|
@ -250,13 +254,7 @@ internal class DefaultWalletsRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createWallet(userWalletId: UserWalletId) {
|
override suspend fun createWallet(userWalletId: UserWalletId) {
|
||||||
runCatching(dispatchers.io) {
|
walletServerBinder.bind(userWalletId)
|
||||||
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
|
|
||||||
|
|
||||||
tangemTechApi.createWallet(
|
|
||||||
body = WalletIdBodyConverter.convert(userWallet = userWallet),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun rejectSeedPhraseSecondNotification(userWalletId: UserWalletId) {
|
override suspend fun rejectSeedPhraseSecondNotification(userWalletId: UserWalletId) {
|
||||||
|
|
@ -413,10 +411,12 @@ internal class DefaultWalletsRepository(
|
||||||
associateApplicationIdWithWallets().getOrThrow()
|
associateApplicationIdWithWallets().getOrThrow()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
val conversionData = appsFlyerConversionStore.get()
|
||||||
val publicKeys = authProvider.getCardsPublicKeys()
|
val publicKeys = authProvider.getCardsPublicKeys()
|
||||||
val walletsBody = wallets.map { userWallet ->
|
val walletsBody = wallets.map { userWallet ->
|
||||||
WalletIdBodyConverter.convert(
|
WalletIdBodyConverter.convert(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
|
conversionData = conversionData,
|
||||||
publicKeys = if (userWallet is UserWallet.Cold) {
|
publicKeys = if (userWallet is UserWallet.Cold) {
|
||||||
publicKeys.filterKeys {
|
publicKeys.filterKeys {
|
||||||
userWallet.cardsInWallet.contains(it)
|
userWallet.cardsInWallet.contains(it)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.data.wallets.di
|
package com.tangem.data.wallets.di
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository
|
import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository
|
||||||
import com.tangem.data.wallets.DefaultWalletsRepository
|
import com.tangem.data.wallets.DefaultWalletsRepository
|
||||||
import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository
|
import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository
|
||||||
|
|
@ -10,6 +11,7 @@ import com.tangem.data.wallets.hot.DefaultHotWalletAccessCodeAttemptsRepository
|
||||||
import com.tangem.datasource.api.common.AuthProvider
|
import com.tangem.datasource.api.common.AuthProvider
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.di.NetworkMoshi
|
import com.tangem.datasource.di.NetworkMoshi
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
|
|
@ -40,6 +42,8 @@ internal object WalletsDataModule {
|
||||||
userWalletsStore: UserWalletsStore,
|
userWalletsStore: UserWalletsStore,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
authProvider: AuthProvider,
|
authProvider: AuthProvider,
|
||||||
|
walletServerBinder: WalletServerBinder,
|
||||||
|
appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||||
accountsFeatureToggles: AccountsFeatureToggles,
|
accountsFeatureToggles: AccountsFeatureToggles,
|
||||||
@NetworkMoshi moshi: Moshi,
|
@NetworkMoshi moshi: Moshi,
|
||||||
): WalletsRepository {
|
): WalletsRepository {
|
||||||
|
|
@ -50,6 +54,8 @@ internal object WalletsDataModule {
|
||||||
seedPhraseNotificationVisibilityStore = RuntimeStateStore(defaultValue = emptyMap()),
|
seedPhraseNotificationVisibilityStore = RuntimeStateStore(defaultValue = emptyMap()),
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
authProvider = authProvider,
|
authProvider = authProvider,
|
||||||
|
walletServerBinder = walletServerBinder,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
accountsFeatureToggles = accountsFeatureToggles,
|
||||||
moshi = moshi,
|
moshi = moshi,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import androidx.datastore.core.DataStore
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.tangem.data.common.wallet.WalletServerBinder
|
||||||
import com.tangem.datasource.api.common.AuthProvider
|
import com.tangem.datasource.api.common.AuthProvider
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException
|
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException
|
||||||
|
|
@ -11,6 +12,7 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.models.PromocodeActivationBody
|
import com.tangem.datasource.api.tangemTech.models.PromocodeActivationBody
|
||||||
import com.tangem.datasource.api.tangemTech.models.PromocodeActivationResponse
|
import com.tangem.datasource.api.tangemTech.models.PromocodeActivationResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.WalletResponse
|
import com.tangem.datasource.api.tangemTech.models.WalletResponse
|
||||||
|
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||||
|
|
@ -38,12 +40,16 @@ class DefaultWalletsRepositoryTest {
|
||||||
)
|
)
|
||||||
private lateinit var tangemTechApi: TangemTechApi
|
private lateinit var tangemTechApi: TangemTechApi
|
||||||
private lateinit var dispatchers: CoroutineDispatcherProvider
|
private lateinit var dispatchers: CoroutineDispatcherProvider
|
||||||
|
private lateinit var walletServerBinder: WalletServerBinder
|
||||||
|
private lateinit var appsFlyerConversionStore: AppsFlyerConversionStore
|
||||||
|
|
||||||
private val testWalletId = UserWalletId("1234567890abcdef")
|
private val testWalletId = UserWalletId("1234567890abcdef")
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
tangemTechApi = mockk()
|
tangemTechApi = mockk()
|
||||||
|
walletServerBinder = mockk()
|
||||||
|
appsFlyerConversionStore = mockk()
|
||||||
dispatchers = TestingCoroutineDispatcherProvider()
|
dispatchers = TestingCoroutineDispatcherProvider()
|
||||||
repository = DefaultWalletsRepository(
|
repository = DefaultWalletsRepository(
|
||||||
appPreferencesStore = appPreferenceStore,
|
appPreferencesStore = appPreferenceStore,
|
||||||
|
|
@ -52,6 +58,8 @@ class DefaultWalletsRepositoryTest {
|
||||||
seedPhraseNotificationVisibilityStore = mockk(),
|
seedPhraseNotificationVisibilityStore = mockk(),
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
authProvider = mockk(),
|
authProvider = mockk(),
|
||||||
|
walletServerBinder = walletServerBinder,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
accountsFeatureToggles = mockk(),
|
accountsFeatureToggles = mockk(),
|
||||||
moshi = mockk(),
|
moshi = mockk(),
|
||||||
)
|
)
|
||||||
|
|
@ -218,10 +226,14 @@ class DefaultWalletsRepositoryTest {
|
||||||
seedPhraseNotificationVisibilityStore = mockk(),
|
seedPhraseNotificationVisibilityStore = mockk(),
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
authProvider = authProvider,
|
authProvider = authProvider,
|
||||||
|
walletServerBinder = walletServerBinder,
|
||||||
|
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
accountsFeatureToggles = accountsFeatureToggles,
|
||||||
moshi = mockk(),
|
moshi = mockk(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
coEvery { appsFlyerConversionStore.get() } returns null
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
tangemTechApi.associateApplicationIdWithWallets(
|
tangemTechApi.associateApplicationIdWithWallets(
|
||||||
eq(applicationId),
|
eq(applicationId),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue