From 052daf6642202b40757693f718aaf5fbebc33a1a Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Apr 2019 13:27:50 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/src/main/AndroidManifest.xml | 2 +- .../domain/wallet/cardano/CardanoEngine.java | 12 +- .../res/layout/activity_sign_transaction.xml | 2 +- .../tangem/ui/ConfirmTransactionActivity.kt | 78 ++++++----- .../com/tangem/ui}/SignTransactionActivity.kt | 132 +++++++++++++++--- .../card_common/tasks/CustomReadCardTask.java | 2 +- 6 files changed, 168 insertions(+), 60 deletions(-) rename app/src/{main/java/com/tangem/ui/activity => tangemCardano/java/com/tangem/ui}/SignTransactionActivity.kt (68%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 99a29f4097..ea530e48e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -109,7 +109,7 @@ android:theme="@style/AppTheme.NoActionBar" /> diff --git a/app/src/main/java/com/tangem/domain/wallet/cardano/CardanoEngine.java b/app/src/main/java/com/tangem/domain/wallet/cardano/CardanoEngine.java index 089f8e9624..09da5a5765 100644 --- a/app/src/main/java/com/tangem/domain/wallet/cardano/CardanoEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/cardano/CardanoEngine.java @@ -6,6 +6,7 @@ import android.util.Base64; import android.util.Log; import com.tangem.App; +import com.tangem.Constant; import com.tangem.data.local.PendingTransactionsStorage; import com.tangem.data.network.ServerApiAdalite; import com.tangem.data.network.model.AdaliteResponse; @@ -23,6 +24,7 @@ import com.tangem.card_common.reader.CardProtocol; import com.tangem.card_common.tasks.SignTask; import com.tangem.card_common.util.Util; import com.tangem.util.DecimalDigitsInputFilter; +import com.tangem.wallet.BuildConfig; import com.tangem.wallet.R; import org.spongycastle.crypto.Digest; @@ -198,6 +200,9 @@ public class CardanoEngine extends CoinEngine { @Override public boolean checkNewTransactionAmount(Amount amount) { + if( BuildConfig.FLAVOR==Constant.FLAVOR_TANGEM_CARDANO ) { + return true; + } if (coinData == null) return false; if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) { return false; @@ -424,9 +429,10 @@ public class CardanoEngine extends CoinEngine { final long amountFinal = amount; final long changeFinal = change; - if (amount + fees > fullAmount) { - throw new CardProtocol.TangemException_WrongAmount(String.format("Balance (%d) < change (%d) + amount (%d)", fullAmount, change, amount)); - } + //TODO - uncomment +// if (amount + fees > fullAmount) { +// throw new CardProtocol.TangemException_WrongAmount(String.format("Balance (%d) < change (%d) + amount (%d)", fullAmount, change, amount)); +// } CborBuilder cborBuilder = new CborBuilder(); ArrayBuilder txArray = cborBuilder.addArray(); diff --git a/app/src/main/res/layout/activity_sign_transaction.xml b/app/src/main/res/layout/activity_sign_transaction.xml index 0dce2fc630..6d06ec0585 100644 --- a/app/src/main/res/layout/activity_sign_transaction.xml +++ b/app/src/main/res/layout/activity_sign_transaction.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.tangem.ui.activity.SignTransactionActivity"> + tools:context="com.tangem.ui.SignTransactionActivity"> = Build.VERSION_CODES.N) Html.fromHtml(engine!!.balanceHTML, Html.FROM_HTML_MODE_LEGACY) @@ -76,17 +75,17 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac else tvIncFee.visibility = View.INVISIBLE - if (ctx.card.blockchainID == Blockchain.Token.id) { - // for Blockchain.Token limit decimals - etAmount.setText(amount.toValueString(ctx.card.tokensDecimal)) - } else { +// if (ctx.card.blockchainID == Blockchain.Token.id) { +// // for Blockchain.Token limit decimals +// etAmount.setText(amount.toValueString(ctx.card.tokensDecimal)) +// } else { // for others etAmount.setText(amount.toValueString()) - } +// } tvCurrency.text = engine.balanceCurrency tvCurrency2.text = engine.feeCurrency - tvCardID.text = ctx.card.cidDescription +// tvCardID.text = ctx.card.cidDescription etWallet.setText(intent.getStringExtra(Constant.EXTRA_TARGET_ADDRESS)) btnSend.visibility = View.INVISIBLE @@ -134,7 +133,7 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac return@setOnClickListener } - val engineCoin = CoinEngineFactory.create(ctx) + val engineCoin = CoinEngineFactory.createCardano(ctx) if (engineCoin!!.isNeedCheckNode && !nodeCheck) { Toast.makeText(baseContext, getString(R.string.cannot_reach_current_active_blockchain_node_try_again), Toast.LENGTH_LONG).show() @@ -144,39 +143,50 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac val txFee = engineCoin.convertToAmount(etFee.text.toString(), tvCurrency2.text.toString()) val txAmount = engineCoin.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString()) - if (!engineCoin.hasBalanceInfo()) { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_check_balance_no_connection_with_blockchain_nodes)) - return@setOnClickListener - - } else if (!engineCoin.isBalanceNotZero) { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.the_wallet_is_empty)) - return@setOnClickListener - - } else if (!engineCoin.isExtractPossible) { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.please_wait_for_confirmation_of_incoming_transaction)) - return@setOnClickListener - } - - if (!engineCoin.checkNewTransactionAmountAndFee(txAmount, txFee, isIncludeFee)) { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.not_enough_funds_on_your_card)) - return@setOnClickListener - } +// if (!engineCoin.hasBalanceInfo()) { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_check_balance_no_connection_with_blockchain_nodes)) +// return@setOnClickListener +// +// } else if (!engineCoin.isBalanceNotZero) { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.the_wallet_is_empty)) +// return@setOnClickListener +// +// } else if (!engineCoin.isExtractPossible) { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.please_wait_for_confirmation_of_incoming_transaction)) +// return@setOnClickListener +// } +// +// if (!engineCoin.checkNewTransactionAmountAndFee(txAmount, txFee, isIncludeFee)) { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.not_enough_funds_on_your_card)) +// return@setOnClickListener +// } requestPIN2Count = 0 - val intent = Intent(baseContext, PinRequestActivity::class.java) - intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString()) +// val intent = Intent(baseContext, PinRequestActivity::class.java) +// intent.putExtra(Constant.EXTRA_MODE, PinRequestActivity.Mode.RequestPIN2.toString()) +// ctx.saveToIntent(intent) +// intent.putExtra(Constant.EXTRA_FEE_INCLUDED, isIncludeFee) +// startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_) + + //TODO - PIN2 workaround + PINStorage.setPIN2(PINStorage.getDefaultPIN2()) + val intent = Intent(baseContext, SignTransactionActivity::class.java) ctx.saveToIntent(intent) + intent.putExtra(Constant.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString()) + intent.putExtra(Constant.EXTRA_AMOUNT, etAmount.text.toString()) + intent.putExtra(Constant.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString()) + intent.putExtra(Constant.EXTRA_FEE, etFee.text.toString()) + intent.putExtra(Constant.EXTRA_FEE_CURRENCY, tvCurrency2.text.toString()) intent.putExtra(Constant.EXTRA_FEE_INCLUDED, isIncludeFee) - startActivityForResult(intent, Constant.REQUEST_CODE_REQUEST_PIN2_) + startActivityForResult(intent, Constant.REQUEST_CODE_SIGN_TRANSACTION) + } else Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() } - val coinEngine = CoinEngineFactory.create(ctx) - progressBar.visibility = View.VISIBLE - coinEngine!!.requestFee( + engine!!.requestFee( object : CoinEngine.BlockchainRequestsCallbacks { override fun onComplete(success: Boolean) { if (success) { diff --git a/app/src/main/java/com/tangem/ui/activity/SignTransactionActivity.kt b/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt similarity index 68% rename from app/src/main/java/com/tangem/ui/activity/SignTransactionActivity.kt rename to app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt index 089fe31274..588a5af413 100644 --- a/app/src/main/java/com/tangem/ui/activity/SignTransactionActivity.kt +++ b/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt @@ -1,4 +1,4 @@ -package com.tangem.ui.activity +package com.tangem.ui import android.app.Activity import android.content.Intent @@ -29,12 +29,22 @@ import com.tangem.ui.dialog.NoExtendedLengthSupportDialog import com.tangem.ui.dialog.WaitSecurityDelayDialog import com.tangem.util.LOG import com.tangem.wallet.R -import kotlinx.android.synthetic.main.activity_sign_transaction.* import kotlinx.android.synthetic.main.layout_progress_horizontal.* import kotlinx.android.synthetic.main.layout_touch_card.* import com.tangem.card_android.data.asBundle import com.tangem.card_android.data.EXTRA_TANGEM_CARD import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID +import com.tangem.card_common.data.TangemCard +import com.tangem.card_common.tasks.CustomReadCardTask +import com.tangem.card_common.tasks.OneTouchSignTask +import com.tangem.card_common.util.Log +import com.tangem.data.Blockchain +import com.tangem.domain.wallet.cardano.CardanoData +import com.tangem.ui.activity.MainActivity +import com.tangem.ui.activity.SendTransactionActivity +import kotlinx.coroutines.runBlocking +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications { @@ -48,7 +58,7 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation - private var signTransactionTask: SignTask? = null + private var task: CustomReadCardTask? = null private lateinit var amount: CoinEngine.Amount private lateinit var fee: CoinEngine.Amount @@ -76,18 +86,18 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, isIncludeFee = intent.getBooleanExtra(Constant.EXTRA_FEE_INCLUDED, true) outAddressStr = intent.getStringExtra(Constant.EXTRA_TARGET_ADDRESS) - tvCardID.text = ctx.card!!.cidDescription + // tvCardID.text = ctx.card!!.cidDescription progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY) progressBar.visibility = View.INVISIBLE } public override fun onPause() { - signTransactionTask?.cancel(true) + task?.cancel(true) super.onPause() } public override fun onStop() { - signTransactionTask?.cancel(true) + task?.cancel(true) super.onStop() } @@ -117,15 +127,15 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, // get IsoDep handle and run cardReader thread val isoDep = IsoDep.get(tag) val uid = tag.id - val sUID = Util.byteArrayToHexString(uid) +// val sUID = Util.byteArrayToHexString(uid) - if (sUID == ctx.card.uid) { - if (lastReadSuccess) - isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000 - else - isoDep.timeout = ctx.card.pauseBeforePIN2 + 65000 +// if (sUID == ctx.card.uid){ +// if (lastReadSuccess) +// isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000 +// else + isoDep.timeout = 65000 - val coinEngine = CoinEngineFactory.create(ctx) + val coinEngine=CoinEngineFactory.createCardano(ctx!!)!! coinEngine?.setOnNeedSendTransaction { tx -> if (tx != null) { val intent = Intent(this, SendTransactionActivity::class.java) @@ -134,12 +144,94 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_) } } - val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr) +// val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr) +// +// task = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, transactionToSign) +// task?.start() - signTransactionTask = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, transactionToSign) - signTransactionTask?.start() - } else - nfcManager.ignoreTag(isoDep.tag) + + val tx: OneTouchSignTask.TransactionToSign = object : OneTouchSignTask.TransactionToSign { + var txToSign: SignTask.TransactionToSign?=null + suspend fun requestBalanceAndUnspentTransactions(): Boolean = suspendCoroutine { cont -> + coinEngine!!.requestBalanceAndUnspentTransactions(object : CoinEngine.BlockchainRequestsCallbacks { + override fun onComplete(success: Boolean?) { + cont.resume(success!!) + } + + override fun onProgress() { + } + + override fun allowAdvance(): Boolean { + return true + } + }) + } + + fun initData(card: TangemCard) + { +// if( ctx==null ){ +// ctx=TangemContext(card) +// } + if( ctx.card==null ){ + ctx.card=card + } + if( ctx.coinData==null ) { + ctx.coinData = CardanoData() + } + if( ctx.coinData.wallet.isNullOrEmpty() ) { + coinEngine!!.defineWallet() + runBlocking { requestBalanceAndUnspentTransactions() } + Log.e(MainActivity.TAG, "requestBalanceAndUnspentTransactions completed") + +// coinEngine?.setOnNeedSendTransaction { tx -> +// if (tx != null) { +// val intent = Intent(this@SignTransactionActivity, SendTransactionActivity::class.java) +// ctx!!.saveToIntent(intent) +// intent.putExtra(Constant.EXTRA_TX, tx) +// startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_) +// } +// } + + } + if( txToSign==null ) txToSign=coinEngine!!.constructTransaction(amount,fee,isIncludeFee,outAddressStr) + } + + override fun isSigningOnCardSupported(card: TangemCard?): Boolean { + initData(card!!) + return (card?.blockchainID== Blockchain.Cardano.id)and(txToSign!!.isSigningMethodSupported(card?.signingMethod)) + } + + override fun getHashesToSign(card: TangemCard?): Array { + initData(card!!) + return txToSign!!.hashesToSign + } + + override fun getRawDataToSign(card: TangemCard?): ByteArray { + initData(card!!) + return txToSign!!.rawDataToSign + } + + override fun getHashAlgToSign(card: TangemCard?): String { + initData(card!!) + return txToSign!!.hashAlgToSign + } + + override fun getIssuerTransactionSignature(card: TangemCard?, dataToSignByIssuer: ByteArray?): ByteArray { + initData(card!!) + return txToSign!!.getIssuerTransactionSignature(dataToSignByIssuer) + } + + override fun onSignCompleted(card: TangemCard?, signature: ByteArray?) { + initData(card!!) + txToSign!!.onSignCompleted(signature) + } + + } + task = OneTouchSignTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, tx) + task!!.start() + +// } else +// nfcManager.ignoreTag(isoDep.tag) } catch (e: CardProtocol.TangemException_WrongAmount) { try { @@ -171,7 +263,7 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, } override fun onReadFinish(cardProtocol: CardProtocol?) { - signTransactionTask = null + task = null if (cardProtocol != null) { if (cardProtocol.error == null) { rlProgressBar.post { rlProgressBar.visibility = View.GONE } @@ -253,7 +345,7 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, } override fun onReadCancel() { - signTransactionTask = null + task = null progressBar?.postDelayed({ try { diff --git a/card-common/src/main/java/com/tangem/card_common/tasks/CustomReadCardTask.java b/card-common/src/main/java/com/tangem/card_common/tasks/CustomReadCardTask.java index e93ac10832..221aa29dd9 100644 --- a/card-common/src/main/java/com/tangem/card_common/tasks/CustomReadCardTask.java +++ b/card-common/src/main/java/com/tangem/card_common/tasks/CustomReadCardTask.java @@ -38,7 +38,7 @@ public class CustomReadCardTask extends Thread { // this fields are static to optimize process when need enter pin and scan card again private static ArrayList lastRead_UnsuccessfullPINs = new ArrayList<>(); private static TangemCard.EncryptionMode lastRead_Encryption = null; - private static String lastRead_UID; + private static String lastRead_UID = ""; public static void resetLastReadInfo() { lastRead_UID = "";