diff --git a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt index 42450edff8..0d9a4eba92 100644 --- a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt +++ b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt @@ -51,6 +51,16 @@ internal class DefaultTangemPayStorage @Inject constructor( private val withdrawStoreDataConverter by lazy { WithdrawStoreDataConverter() } private val withdrawStateConverter by lazy { WithdrawStateConverter() } + private val listType by lazy { + Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) + } + private val mapType by lazy { + Types.newParameterizedType(Map::class.java, String::class.java, listType) + } + private val adapter: JsonAdapter>> by lazy { + appPreferencesStore.moshi.adapter(mapType) + } + override suspend fun storeCustomerWalletAddress(userWalletId: UserWalletId, customerWalletAddress: String) { withContext(dispatcherProvider.io) { appPreferencesStore @@ -152,15 +162,19 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun storeWithdrawOrder(userWalletId: UserWalletId, data: TangemPayWithdrawState) { - val listType = Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) - val mapType = Types.newParameterizedType(Map::class.java, String::class.java, listType) - val adapter: JsonAdapter>> = appPreferencesStore.moshi.adapter(mapType) appPreferencesStore.editData { prefs -> val walletKey = createWithdrawOrderIdKey(userWalletId) - val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY]?.let(adapter::fromJson).orEmpty() - val updatedList = currentMap[walletKey].orEmpty() + withdrawStoreDataConverter.convert(data) - prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = adapter - .toJson(currentMap + (walletKey to updatedList)) + val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] + ?.let(adapter::fromJson) + .orEmpty() + val newItem = withdrawStoreDataConverter.convert(data) + val currentList = currentMap[walletKey].orEmpty() + val updatedList = buildList(currentList.size + 1) { + for (item in currentList) { if (item.orderId != newItem.orderId) add(item) } + add(newItem) + } + prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = + adapter.toJson(currentMap + (walletKey to updatedList)) } } @@ -170,9 +184,6 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun getWithdrawOrders(userWalletId: UserWalletId): List { - val listType = Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) - val mapType = Types.newParameterizedType(Map::class.java, String::class.java, listType) - val adapter: JsonAdapter>> = appPreferencesStore.moshi.adapter(mapType) val map = appPreferencesStore.data.firstOrNull() ?.get(PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY)?.let(adapter::fromJson).orEmpty() return map[createWithdrawOrderIdKey(userWalletId)].orEmpty().map(withdrawStateConverter::convert) @@ -190,15 +201,22 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun deleteWithdrawOrder(userWalletId: UserWalletId, orderId: String) { - appPreferencesStore.editData { mutablePreferences -> - val orders = mutablePreferences.getObjectMap( - PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY, - ) - .minus(createWithdrawOrderIdKey(userWalletId)) - mutablePreferences.setObjectMap( - key = PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY, - value = orders, - ) + appPreferencesStore.editData { prefs -> + val walletKey = createWithdrawOrderIdKey(userWalletId) + val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY]?.let(adapter::fromJson) + .orEmpty() + val currentList = currentMap[walletKey].orEmpty() + val updatedList = buildList(currentList.size) { + for (item in currentList) { + if (item.orderId != orderId) add(item) + } + } + val updatedMap = if (updatedList.isEmpty()) { + currentMap - walletKey + } else { + currentMap + (walletKey to updatedList) + } + prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = adapter.toJson(updatedMap) } } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt index cdad87d12b..02d63db72f 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt @@ -7,6 +7,7 @@ import com.squareup.moshi.JsonClass data class WithdrawStoreData( @Json(name = "orderId") val orderId: String, @Json(name = "exchangeData") val exchangeData: ExchangeStoreData?, + @Json(name = "txHash") val txHash: String?, ) @JsonClass(generateAdapter = false) diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt index 922b617842..7bf21432a7 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt @@ -110,12 +110,15 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( val storeData = TangemPayWithdrawState( orderId = orderId, exchangeData = exchangeData, + txHash = withdrawTxHash, ) if (order != null && !withdrawTxHash.isNullOrEmpty()) { - finalizeWithdraw(userWallet = userWallet, txHash = withdrawTxHash, exchangeData = exchangeData) - .onLeft { - tangemPayStorage.storeWithdrawOrder(userWalletId = userWallet.walletId, data = storeData) - } + finalizeWithdraw( + userWallet = userWallet, + txHash = withdrawTxHash, + exchangeData = exchangeData, + orderId = orderId, + ) } else { tangemPayStorage.storeWithdrawOrder(userWalletId = userWallet.walletId, data = storeData) } @@ -124,6 +127,7 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( private suspend fun finalizeWithdraw( userWallet: UserWallet, + orderId: String, txHash: String, exchangeData: TangemPayWithdrawExchangeState, ): Either { @@ -135,10 +139,9 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( payInAddress = exchangeData.payInAddress, txHash = txHash, payInExtraId = exchangeData.payInExtraId, - ) - .onLeft { error -> - Timber.tag(TAG).e(error.toString()) - } + ).also { + tangemPayStorage.deleteWithdrawOrder(userWallet.walletId, orderId) + } } override suspend fun hasWithdrawOrder(userWallet: UserWallet): Boolean { @@ -168,19 +171,23 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( private suspend fun pollWithdrawOrderIfNeeds(userWallet: UserWallet, data: TangemPayWithdrawState) { val exchangeData = data.exchangeData ?: return + val storedHash = data.txHash val orderId = data.orderId - val order = orderRepository.getOrderData(userWalletId = userWallet.walletId, orderId = orderId).getOrNull() - ?: return - val txHash = order.withdrawTxHash + val txHash = if (storedHash.isNullOrEmpty()) { + val order = orderRepository.getOrderData(userWalletId = userWallet.walletId, orderId = orderId).getOrNull() + ?: return + order.withdrawTxHash.also { fetchedHash -> + tangemPayStorage.storeWithdrawOrder( + userWalletId = userWallet.walletId, + data = data.copy(txHash = fetchedHash), + ) + } + } else { + storedHash + } if (!txHash.isNullOrEmpty()) { - finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData) - .onRight { - tangemPayStorage.deleteWithdrawOrder(userWalletId = userWallet.walletId, orderId = orderId) - } - .onLeft { - startWithdrawOrderPolling(userWallet = userWallet, orderId = orderId, exchangeData = exchangeData) - } + finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData, orderId = orderId) } else { startWithdrawOrderPolling(userWallet = userWallet, orderId = orderId, exchangeData = exchangeData) } @@ -204,20 +211,14 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( .onRight { order -> val txHash = order.withdrawTxHash if (txHash.isNullOrEmpty()) return@onRight - finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData) - .onRight { - tangemPayStorage.deleteWithdrawOrder( - userWalletId = userWallet.walletId, - orderId = orderId, - ) - withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } - return@launch - } - .onLeft { error -> - Timber.tag(TAG).e("finalizeWithdraw error: $error") - withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } - return@launch - } + finalizeWithdraw( + userWallet = userWallet, + txHash = txHash, + exchangeData = exchangeData, + orderId = orderId, + ) + withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } + return@launch } .onLeft { error -> Timber.tag(TAG).e("getOrderData error ${error.errorCode}") diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt index 5bcefd3b8e..019ee19504 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt @@ -18,5 +18,6 @@ class WithdrawStateConverter : Converter