Updated on 2026-08-14
This commit is contained in:
parent
fa43c17155
commit
e8123e3455
5 changed files with 131 additions and 2 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<String, CardTransactionsInfo>
|
||||
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<HashMap<String, CardTransactionsInfo>>() {}.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<TransactionInfo>
|
||||
) {
|
||||
fun isEmpty(): Boolean {
|
||||
return transactions.count()==0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -366,4 +366,6 @@ public abstract class CoinEngine {
|
|||
}
|
||||
|
||||
|
||||
public int pendingTransactionTimeoutInSeconds() { return 30; }
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue