From e8123e3455d51775001504e30e24f81bfcef80a9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 27 Feb 2019 11:19:55 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/src/main/java/com/tangem/App.kt | 3 + .../data/local/PendingTransactionsStorage.kt | 106 ++++++++++++++++++ .../domain/wallet/BalanceValidator.java | 15 +++ .../com/tangem/domain/wallet/CoinEngine.java | 2 + .../activity/SendTransactionActivity.kt | 7 +- 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/tangem/data/local/PendingTransactionsStorage.kt diff --git a/app/src/main/java/com/tangem/App.kt b/app/src/main/java/com/tangem/App.kt index dc02b999b5..9c4656de06 100644 --- a/app/src/main/java/com/tangem/App.kt +++ b/app/src/main/java/com/tangem/App.kt @@ -4,6 +4,7 @@ import android.app.Application import androidx.appcompat.app.AppCompatDelegate import com.google.gson.Gson import com.google.gson.reflect.TypeToken +import com.tangem.data.local.PendingTransactionsStorage import com.tangem.di.DaggerNavigatorComponent import com.tangem.di.DaggerNetworkComponent import com.tangem.di.NavigatorComponent @@ -33,6 +34,7 @@ class App : Application() { lateinit var firmwaresStorage: Firmwares lateinit var localStorage: LocalStorage lateinit var pinStorage: PINStorage + lateinit var pendingTransactionsStorage: PendingTransactionsStorage } override fun onCreate() { @@ -52,6 +54,7 @@ class App : Application() { firmwaresStorage = Firmwares(applicationContext) localStorage = LocalStorage(applicationContext) pinStorage = PINStorage() + pendingTransactionsStorage = PendingTransactionsStorage(applicationContext) } private fun buildNavigatorComponent(): NavigatorComponent { diff --git a/app/src/main/java/com/tangem/data/local/PendingTransactionsStorage.kt b/app/src/main/java/com/tangem/data/local/PendingTransactionsStorage.kt new file mode 100644 index 0000000000..7cdd993e28 --- /dev/null +++ b/app/src/main/java/com/tangem/data/local/PendingTransactionsStorage.kt @@ -0,0 +1,106 @@ +package com.tangem.data.local + +import android.content.Context +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.tangem.tangemcommon.data.TangemCard +import java.io.File +import java.util.* +import kotlin.collections.HashMap + +class PendingTransactionsStorage +( + val context: Context +) { + private lateinit var cardTransactions: MutableMap + private val transactionsFile: File = File(context.filesDir, "transactions.json") + + private var cacheDir: File? = null + + init { + cacheDir = File(context.filesDir, "artworks") + if (!cacheDir!!.exists()) + cacheDir!!.mkdirs() + + if (transactionsFile.exists()) { + try { + transactionsFile.bufferedReader().use { cardTransactions = Gson().fromJson(it, object : TypeToken>() {}.type) } + } catch (e: Exception) { + e.printStackTrace() + cardTransactions = HashMap() + } + } else { + cardTransactions = HashMap() + } + } + + private fun clearExpired() + { + for(cardId in cardTransactions.keys) { + cardTransactions[cardId]!!.transactions.removeAll { it.isExpired() } + } + cardTransactions.entries.removeAll { it.value.isEmpty() } + } + + fun save() { + clearExpired() + val sTransactions = Gson().toJson(cardTransactions) + + transactionsFile.bufferedWriter().use { it.write(sTransactions) } + } + + fun putTransaction(card: TangemCard, txId: String, expireTimeoutInSeconds: Int) { + val sendDate=Date() + val calendar=Calendar.getInstance() + calendar.time=sendDate + calendar.add(Calendar.SECOND, expireTimeoutInSeconds) + val expireDate=calendar.time + putTransaction(card.cidDescription, txId, sendDate, expireDate) + } + + private fun putTransaction(cardId: String, txId: String, sendDate: Date, expireDate: Date) { + val transactionInfo = TransactionInfo( + txId, sendDate, expireDate + ) + if (cardTransactions[cardId] == null) { + cardTransactions[cardId] = CardTransactionsInfo(arrayListOf()) + } + cardTransactions[cardId]?.transactions?.add(transactionInfo) + save() + } + + fun getTransactions(card: TangemCard): CardTransactionsInfo? { + clearExpired() + return cardTransactions[card.cidDescription] + } + + fun hasTransactions(card: TangemCard): Boolean { + val cardTransactionsInfo=getTransactions(card) + if( cardTransactionsInfo!=null ) return cardTransactionsInfo.transactions.count()>0 + return false + } + + fun removeTransaction(card: TangemCard, txId: String) + { + cardTransactions[card.cidDescription]?.transactions?.removeAll { it.tx==txId } + save() + } + + data class TransactionInfo( + val tx: String, + val sendDate: Date, + val expireDate: Date + ) { + fun isExpired(): Boolean { + return Date().after(expireDate) + } + } + + data class CardTransactionsInfo( + var transactions: MutableList + ) { + fun isEmpty(): Boolean { + return transactions.count()==0 + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java index 5fa7fd1f60..74e6afcffe 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java +++ b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java @@ -1,5 +1,6 @@ package com.tangem.domain.wallet; +import com.tangem.App; import com.tangem.tangemcommon.data.TangemCard; import com.tangem.wallet.R; @@ -7,6 +8,7 @@ public class BalanceValidator { private String firstLine; private String secondLine; private int score; + private boolean hasPending; public String getFirstLine() { return firstLine; @@ -38,6 +40,10 @@ public class BalanceValidator { } public int getColor() { + if( hasPending ) + { + return R.color.primary_dark; + } if (score > 89) { return R.color.confirmed; } else if (score > 74) { @@ -57,6 +63,15 @@ public class BalanceValidator { if (!engine.validateBalance(this)) return; + hasPending=App.pendingTransactionsStorage.hasTransactions(card); + + if( hasPending ) + { + firstLine = "Pending transaction..."; + secondLine = ""; + return; + } + // Verify card? if (attest) { diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java index 481f2afb2b..19fc78fe8c 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java @@ -366,4 +366,6 @@ public abstract class CoinEngine { } + public int pendingTransactionTimeoutInSeconds() { return 30; } + } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt index f29eb48e4e..4319763730 100644 --- a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.kt @@ -7,6 +7,7 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import android.view.KeyEvent import android.widget.Toast +import com.tangem.App import com.tangem.Constant import com.tangem.domain.wallet.CoinEngine import com.tangem.domain.wallet.CoinEngineFactory @@ -15,6 +16,7 @@ import com.tangem.presentation.event.TransactionFinishWithError import com.tangem.presentation.event.TransactionFinishWithSuccess import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver import com.tangem.tangemcard.android.reader.NfcManager +import com.tangem.tangemcommon.util.Util import com.tangem.util.UtilHelper import com.tangem.wallet.R import org.greenrobot.eventbus.EventBus @@ -42,9 +44,10 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { engine!!.requestSendTransaction( object : CoinEngine.BlockchainRequestsCallbacks { override fun onComplete(success: Boolean) { - if (success) + if (success) { + App.pendingTransactionsStorage.putTransaction(ctx.card, Util.bytesToHex(tx), engine.pendingTransactionTimeoutInSeconds()) finishWithSuccess() - else + }else finishWithError(ctx.error) }