diff --git a/app/build.gradle b/app/build.gradle
index 3ca01aaf09..37203672f4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,6 +30,7 @@ android {
debuggable true
minifyEnabled false
applicationIdSuffix ".debug"
+ versionNameSuffix '-DEBUG'
signingConfig signingConfigs.debug
}
}
@@ -90,6 +91,8 @@ dependencies {
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation "com.orhanobut:hawk:2.0.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
implementation 'org.bitcoinj:bitcoinj-parent:0.14.7'
implementation 'org.bitcoinj:bitcoinj-core:0.14.7'
implementation 'org.greenrobot:eventbus:3.1.1'
@@ -98,7 +101,4 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
- //implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.22.5"
}
\ No newline at end of file
diff --git a/app/src/debug/res/values/strings.xml b/app/src/debug/res/values/strings.xml
index 9ef8838437..ec5cc446df 100644
--- a/app/src/debug/res/values/strings.xml
+++ b/app/src/debug/res/values/strings.xml
@@ -1,6 +1,6 @@
- DEBUG
+
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt b/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt
index 25fa8f21d3..f6c1538c21 100644
--- a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt
+++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.kt
@@ -81,6 +81,17 @@ object CoinEngineFactory {
Log.e(TAG, "Can't create Cardano CoinEngine!")
}
return result
+
+// var result: EthEngine?
+// try {
+// result = EthEngine(context)
+//
+// } catch (e: Exception) {
+// e.printStackTrace()
+// result = null
+// Log.e(TAG, "Can't create Cardano CoinEngine!")
+// }
+// return result
}
}
\ No newline at end of file
diff --git a/app/src/tangemAccess/java/com/tangem/ui/SignTransactionActivity.kt b/app/src/tangemAccess/java/com/tangem/ui/SignTransactionActivity.kt
new file mode 100644
index 0000000000..089fe31274
--- /dev/null
+++ b/app/src/tangemAccess/java/com/tangem/ui/SignTransactionActivity.kt
@@ -0,0 +1,301 @@
+package com.tangem.ui.activity
+
+import android.app.Activity
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.media.MediaPlayer
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.nfc.tech.IsoDep
+import android.os.Bundle
+import android.view.KeyEvent
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.tangem.App
+import com.tangem.Constant
+import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
+import com.tangem.card_android.android.nfc.NfcLifecycleObserver
+import com.tangem.card_android.android.reader.NfcManager
+import com.tangem.card_android.android.reader.NfcReader
+import com.tangem.card_common.reader.CardProtocol
+import com.tangem.card_common.tasks.SignTask
+import com.tangem.card_common.util.Util
+import com.tangem.domain.wallet.CoinEngine
+import com.tangem.domain.wallet.CoinEngineFactory
+import com.tangem.domain.wallet.TangemContext
+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
+
+class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
+
+ companion object {
+ val TAG: String = SignTransactionActivity::class.java.simpleName
+ }
+
+ private lateinit var nfcManager: NfcManager
+ private lateinit var ctx: TangemContext
+ private lateinit var mpFinishSignSound: MediaPlayer
+
+ private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
+
+ private var signTransactionTask: SignTask? = null
+
+ private lateinit var amount: CoinEngine.Amount
+ private lateinit var fee: CoinEngine.Amount
+ private var isIncludeFee = true
+ private var outAddressStr: String? = null
+ private var lastReadSuccess = true
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_sign_transaction)
+
+ nfcManager = NfcManager(this, this)
+ lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
+
+ ctx = TangemContext.loadFromBundle(this, intent.extras)
+
+ mpFinishSignSound = MediaPlayer.create(this, R.raw.scan_card_sound)
+
+ // init NFC Antenna
+ nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
+ nfcDeviceAntenna.init()
+
+ amount = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_AMOUNT), intent.getStringExtra(Constant.EXTRA_AMOUNT_CURRENCY))
+ fee = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_FEE), intent.getStringExtra(Constant.EXTRA_FEE_CURRENCY))
+ isIncludeFee = intent.getBooleanExtra(Constant.EXTRA_FEE_INCLUDED, true)
+ outAddressStr = intent.getStringExtra(Constant.EXTRA_TARGET_ADDRESS)
+
+ tvCardID.text = ctx.card!!.cidDescription
+ progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar.visibility = View.INVISIBLE
+ }
+
+ public override fun onPause() {
+ signTransactionTask?.cancel(true)
+ super.onPause()
+ }
+
+ public override fun onStop() {
+ signTransactionTask?.cancel(true)
+ super.onStop()
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if (requestCode == Constant.REQUEST_CODE_SEND_TRANSACTION_) {
+ setResult(resultCode, data)
+ finish()
+ return
+ }
+ super.onActivityResult(requestCode, resultCode, data)
+ }
+
+ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+ when (keyCode) {
+ KeyEvent.KEYCODE_BACK -> {
+ val intent = Intent()
+ setResult(Activity.RESULT_CANCELED, intent)
+ finish()
+ return true
+ }
+ }
+ return super.onKeyDown(keyCode, event)
+ }
+
+ override fun onTagDiscovered(tag: Tag) {
+ try {
+ // get IsoDep handle and run cardReader thread
+ val isoDep = IsoDep.get(tag)
+ val uid = tag.id
+ 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
+
+ val coinEngine = CoinEngineFactory.create(ctx)
+ coinEngine?.setOnNeedSendTransaction { tx ->
+ if (tx != null) {
+ val intent = Intent(this, SendTransactionActivity::class.java)
+ ctx.saveToIntent(intent)
+ intent.putExtra(Constant.EXTRA_TX, tx)
+ startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_)
+ }
+ }
+ val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
+
+ signTransactionTask = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, transactionToSign)
+ signTransactionTask?.start()
+ } else
+ nfcManager.ignoreTag(isoDep.tag)
+
+ } catch (e: CardProtocol.TangemException_WrongAmount) {
+ try {
+ val intent = Intent()
+ intent.putExtra(Constant.EXTRA_MESSAGE, getString(R.string.cannot_sign_transaction_wrong_amount))
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, ctx.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, ctx.card.asBundle)
+ setResult(Activity.RESULT_CANCELED, intent)
+ finish()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun onReadStart(cardProtocol: CardProtocol) {
+ rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
+
+ progressBar?.post {
+ progressBar?.visibility = View.VISIBLE
+ progressBar?.progress = 5
+ }
+ }
+
+ override fun onReadProgress(protocol: CardProtocol, progress: Int) {
+ progressBar?.post { progressBar!!.progress = progress }
+ }
+
+ override fun onReadFinish(cardProtocol: CardProtocol?) {
+ signTransactionTask = null
+ if (cardProtocol != null) {
+ if (cardProtocol.error == null) {
+ rlProgressBar.post { rlProgressBar.visibility = View.GONE }
+
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.GREEN)
+ }
+
+ mpFinishSignSound.start()
+ } else {
+ lastReadSuccess = false
+ if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) {
+ progressBar?.post {
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ val intent = Intent()
+ intent.putExtra(Constant.EXTRA_MESSAGE, getString(R.string.cannot_sign_transaction_make_sure_you_enter_correct_pin_2))
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
+ setResult(Constant.RESULT_INVALID_PIN_, intent)
+ finish()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ } else {
+ if (cardProtocol.error is CardProtocol.TangemException_WrongAmount) {
+ try {
+ val intent = Intent()
+ intent.putExtra(Constant.EXTRA_MESSAGE, getString(R.string.cannot_sign_transaction_wrong_amount))
+ intent.putExtra(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
+ intent.putExtra(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
+ setResult(Activity.RESULT_CANCELED, intent)
+ finish()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ progressBar?.post {
+ if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
+ if (!NoExtendedLengthSupportDialog.allReadyShowed) {
+ NoExtendedLengthSupportDialog.message = getText(R.string.the_nfc_adapter_length_apdu).toString() + "\n" + getText(R.string.the_nfc_adapter_length_apdu_advice).toString()
+ NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
+ }
+ } else {
+ Toast.makeText(baseContext, R.string.try_to_scan_again, Toast.LENGTH_LONG).show()
+ }
+ progressBar?.progress = 100
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
+ }
+ }
+ }
+ }
+
+ rlProgressBar.postDelayed({
+ try {
+ rlProgressBar.visibility = View.GONE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+ override fun onReadCancel() {
+ signTransactionTask = null
+
+ progressBar?.postDelayed({
+ try {
+ progressBar?.progress = 0
+ progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
+ progressBar?.visibility = View.INVISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 500)
+ }
+
+// private val waitSecurityDelayDialogNew = WaitSecurityDelayDialogNew()
+
+ override fun onReadBeforeRequest(timeout: Int) {
+ LOG.i(TAG, "onReadBeforeRequest timeout $timeout")
+ WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout)
+
+// if (!waitSecurityDelayDialogNew.isAdded)
+// waitSecurityDelayDialogNew.show(supportFragmentManager, WaitSecurityDelayDialogNew.TAG)
+
+
+// val readBeforeRequest = ReadBeforeRequest()
+// readBeforeRequest.timeout = timeout
+// EventBus.getDefault().post(readBeforeRequest)
+ }
+
+ override fun onReadAfterRequest() {
+ LOG.i(TAG, "onReadAfterRequest")
+ WaitSecurityDelayDialog.onReadAfterRequest(this)
+
+// val readAfterRequest = ReadAfterRequest()
+// EventBus.getDefault().post(readAfterRequest)
+ }
+
+ override fun onReadWait(msec: Int) {
+ LOG.i(TAG, "onReadWait msec $msec")
+ WaitSecurityDelayDialog.onReadWait(this, msec)
+
+// val readWait = ReadWait()
+// readWait.msec = msec
+// EventBus.getDefault().post(readWait)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt b/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt
index 588a5af413..dee2044bd2 100644
--- a/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt
+++ b/app/src/tangemCardano/java/com/tangem/ui/SignTransactionActivity.kt
@@ -86,7 +86,7 @@ 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
}
@@ -133,55 +133,54 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
// if (lastReadSuccess)
// isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000
// else
- isoDep.timeout = 65000
+ isoDep.timeout = 65000
- val coinEngine=CoinEngineFactory.createCardano(ctx!!)!!
- coinEngine?.setOnNeedSendTransaction { tx ->
- if (tx != null) {
- val intent = Intent(this, SendTransactionActivity::class.java)
- ctx.saveToIntent(intent)
- intent.putExtra(Constant.EXTRA_TX, tx)
- startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_)
- }
+ val coinEngine = CoinEngineFactory.createCardano(ctx!!)!!
+ coinEngine.setOnNeedSendTransaction { tx ->
+ if (tx != null) {
+ val intent = Intent(this, SendTransactionActivity::class.java)
+ ctx.saveToIntent(intent)
+ intent.putExtra(Constant.EXTRA_TX, tx)
+ startActivityForResult(intent, Constant.REQUEST_CODE_SEND_TRANSACTION_)
}
+ }
// val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
//
// task = SignTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, transactionToSign)
// task?.start()
- 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!!)
- }
+ 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 onProgress() {
+ }
- override fun allowAdvance(): Boolean {
- return true
- }
- })
- }
+ override fun allowAdvance(): Boolean {
+ return true
+ }
+ })
+ }
- fun initData(card: TangemCard)
- {
+ 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")
+ 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) {
@@ -192,43 +191,43 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
// }
// }
- }
- 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)
- }
-
+ if (txToSign == null) txToSign = coinEngine!!.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
}
- task = OneTouchSignTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, tx)
- task!!.start()
+
+ 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)