Updated on 2026-08-14
This commit is contained in:
parent
1c288123ea
commit
052daf6642
6 changed files with 168 additions and 60 deletions
|
|
@ -109,7 +109,7 @@
|
|||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.tangem.ui.activity.SignTransactionActivity"
|
||||
android:name="com.tangem.ui.SignTransactionActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
|
||||
|
|
|
|||
|
|
@ -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<CborBuilder> txArray = cborBuilder.addArray();
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
||||
<include
|
||||
layout="@layout/layout_touch_card"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import android.view.KeyEvent
|
|||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.card_android.android.data.PINStorage
|
||||
import com.tangem.domain.wallet.CoinEngine
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
|
|
@ -31,7 +31,6 @@ import java.util.*
|
|||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.ui.activity.PinRequestActivity
|
||||
import com.tangem.ui.activity.SignTransactionActivity
|
||||
import kotlinx.android.synthetic.tangemCardano.activity_confirm_transaction.*
|
||||
|
||||
class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
||||
|
|
@ -52,9 +51,9 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
|
|||
nfcManager = NfcManager(this, this)
|
||||
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
|
||||
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
ctx = TangemContext();//.loadFromBundle(this, intent.extras)
|
||||
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
val engine = CoinEngineFactory.createCardano(ctx) //create(ctx)
|
||||
|
||||
@Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= 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) {
|
||||
|
|
|
|||
|
|
@ -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<ByteArray> {
|
||||
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 {
|
||||
|
|
@ -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<String> 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 = "";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue