Updated on 2026-08-14
This commit is contained in:
parent
ce7b5e9f84
commit
517d3e1ccd
5 changed files with 198 additions and 21 deletions
|
|
@ -55,6 +55,10 @@ android {
|
|||
buildToolsVersion '28.0.3'
|
||||
}
|
||||
|
||||
configurations {
|
||||
all*.exclude group: 'com.google.guava', module: 'listenablefuture'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':card-common')
|
||||
implementation project(':card-android')
|
||||
|
|
@ -64,12 +68,12 @@ dependencies {
|
|||
// implementation 'com.github.TangemCash:card-android:0.1.3'
|
||||
// implementation 'com.github.TangemCash:server-android:0.1.4'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
|
||||
implementation 'androidx.biometric:biometric:1.0.0-alpha03'
|
||||
implementation 'co.nstant.in:cbor:0.8'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha02'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha05'
|
||||
implementation 'com.google.dagger:dagger:2.21'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.21'
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.21'
|
||||
|
|
@ -94,5 +98,7 @@ 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"
|
||||
}
|
||||
|
|
@ -61,14 +61,14 @@ class LogoActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun hide() {
|
||||
when (BuildConfig.FLAVOR) {
|
||||
Constant.FLAVOR_TANGEM_CARDANO -> {
|
||||
navigator.showPrepareTransaction(this)
|
||||
}
|
||||
else -> {
|
||||
// when (BuildConfig.FLAVOR) {
|
||||
// Constant.FLAVOR_TANGEM_CARDANO -> {
|
||||
// navigator.showPrepareTransaction(this)
|
||||
// }
|
||||
// else -> {
|
||||
navigator.showMain(this)
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
|
||||
finish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
@file:Suppress("ObsoleteExperimentalCoroutines")
|
||||
|
||||
package com.tangem.ui.activity
|
||||
|
||||
import android.Manifest
|
||||
|
|
@ -25,14 +27,23 @@ 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_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.card_android.data.loadFromBundle
|
||||
import com.tangem.card_android.data.saveToBundle
|
||||
import com.tangem.card_common.data.TangemCard
|
||||
import com.tangem.card_common.reader.CardProtocol
|
||||
import com.tangem.card_common.tasks.CustomReadCardTask
|
||||
import com.tangem.card_common.tasks.OneTouchSignTask
|
||||
import com.tangem.card_common.tasks.ReadCardInfoTask
|
||||
import com.tangem.card_common.tasks.SignTask
|
||||
import com.tangem.card_common.util.Log
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.data.Logger
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.di.Navigator
|
||||
import com.tangem.di.ToastHelper
|
||||
import com.tangem.domain.wallet.CoinEngine
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
|
||||
|
|
@ -48,9 +59,9 @@ import kotlinx.android.synthetic.main.layout_touch_card.*
|
|||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.di.ToastHelper
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
|
|
@ -70,7 +81,8 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
|
||||
private var unsuccessReadCount = 0
|
||||
private var lastTag: Tag? = null
|
||||
private var readCardInfoTask: ReadCardInfoTask? = null
|
||||
// private var readCardInfoTask: ReadCardInfoTask? = null
|
||||
private var task: CustomReadCardTask? = null
|
||||
private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = null
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
|
|
@ -234,8 +246,77 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
|
||||
lastTag = tag
|
||||
|
||||
readCardInfoTask = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
readCardInfoTask?.start()
|
||||
// readCardInfoTask = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
//readCardInfoTask?.start()
|
||||
val tx: OneTouchSignTask.TransactionToSign = object : OneTouchSignTask.TransactionToSign {
|
||||
var txToSign: SignTask.TransactionToSign?=null
|
||||
var ctx: TangemContext?=null
|
||||
var coinEngine: CoinEngine?=null
|
||||
val amount: CoinEngine.Amount=CoinEngine.Amount(10,"")
|
||||
val fee: CoinEngine.Amount=CoinEngine.Amount(1,"")
|
||||
val incFee: Boolean = true
|
||||
val targetAddress: String = "aaaa"
|
||||
|
||||
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( coinEngine==null ) {
|
||||
coinEngine=CoinEngineFactory.createCardano(ctx!!)!!
|
||||
coinEngine!!.defineWallet()
|
||||
runBlocking { requestBalanceAndUnspentTransactions() }
|
||||
Log.e(TAG, "requestBalanceAndUnspentTransactions completed")
|
||||
}
|
||||
if( txToSign==null ) txToSign=coinEngine!!.constructTransaction(amount,fee,true, targetAddress)
|
||||
}
|
||||
|
||||
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()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
nfcManager.notifyReadResult(false)
|
||||
|
|
@ -249,12 +330,12 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
}
|
||||
|
||||
public override fun onPause() {
|
||||
readCardInfoTask?.cancel(true)
|
||||
task?.cancel(true)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
public override fun onStop() {
|
||||
readCardInfoTask?.cancel(true)
|
||||
task?.cancel(true)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +348,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
}
|
||||
|
||||
override fun onReadFinish(cardProtocol: CardProtocol?) {
|
||||
readCardInfoTask = null
|
||||
task = null
|
||||
if (cardProtocol != null) {
|
||||
if (cardProtocol.error == null) {
|
||||
nfcManager.notifyReadResult(true)
|
||||
|
|
@ -333,7 +414,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
}
|
||||
|
||||
override fun onReadCancel() {
|
||||
readCardInfoTask = null
|
||||
task = null
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
rlProgressBar.postDelayed({
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
package com.tangem.card_common.tasks;
|
||||
|
||||
import com.tangem.card_common.data.TangemCard;
|
||||
import com.tangem.card_common.data.external.CardDataSubstitutionProvider;
|
||||
import com.tangem.card_common.data.external.PINsProvider;
|
||||
import com.tangem.card_common.reader.CardProtocol;
|
||||
import com.tangem.card_common.reader.NfcReader;
|
||||
import com.tangem.card_common.reader.TLV;
|
||||
import com.tangem.card_common.reader.TLVList;
|
||||
import com.tangem.card_common.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class OneTouchSignTask extends ReadCardInfoTask {
|
||||
public static final String TAG = OneTouchSignTask.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Transaction Engine request/notifications during sign process
|
||||
*/
|
||||
public interface TransactionToSign {
|
||||
boolean isSigningOnCardSupported(TangemCard card);
|
||||
|
||||
byte[][] getHashesToSign(TangemCard card) throws Exception;
|
||||
|
||||
byte[] getRawDataToSign(TangemCard card) throws Exception;
|
||||
|
||||
String getHashAlgToSign(TangemCard card) throws Exception;
|
||||
|
||||
byte[] getIssuerTransactionSignature(TangemCard card, byte[] dataToSignByIssuer) throws Exception;
|
||||
|
||||
void onSignCompleted(TangemCard card, byte[] signature) throws Exception;
|
||||
}
|
||||
|
||||
private TransactionToSign transactionToSign;
|
||||
|
||||
public OneTouchSignTask(NfcReader reader, CardDataSubstitutionProvider cardDataSubstitutionProvider, PINsProvider pinsProvider, CardProtocol.Notifications notifications, TransactionToSign transactionToSign) {
|
||||
super(reader, cardDataSubstitutionProvider, pinsProvider, notifications);
|
||||
this.transactionToSign = transactionToSign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run_Task() throws Exception {
|
||||
super.run_Task();
|
||||
Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
|
||||
|
||||
mNotifications.onReadProgress(protocol, 30);
|
||||
if (isCancelled) return;
|
||||
|
||||
if (mCard.getPauseBeforePIN2() > 0) {
|
||||
mNotifications.onReadWait(mCard.getPauseBeforePIN2());
|
||||
}
|
||||
|
||||
if (!transactionToSign.isSigningOnCardSupported(mCard)) {
|
||||
throw new CardProtocol.TangemException("Signing method isn't supported!");
|
||||
}
|
||||
|
||||
TLVList signResult;
|
||||
switch (mCard.getSigningMethod()) {
|
||||
case Sign_Hash:
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), transactionToSign.getHashesToSign(mCard), null, null, null);
|
||||
break;
|
||||
case Sign_Hash_Validated_By_Issuer:
|
||||
case Sign_Hash_Validated_By_Issuer_And_WriteIssuerData:
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
byte[][] hashes = transactionToSign.getHashesToSign(mCard);
|
||||
if (hashes.length > 10) throw new CardProtocol.TangemException("To much hashes in one transaction!");
|
||||
for (int i = 0; i < hashes.length; i++) {
|
||||
if (i != 0 && hashes[0].length != hashes[i].length)
|
||||
throw new CardProtocol.TangemException("Hashes length must be identical!");
|
||||
bs.write(hashes[i]);
|
||||
}
|
||||
signResult = protocol.run_SignHashes(pinsProvider.getPIN2(), hashes, transactionToSign.getIssuerTransactionSignature(mCard, bs.toByteArray()), null, null);
|
||||
break;
|
||||
case Sign_Raw:
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), transactionToSign.getRawDataToSign(mCard), null, null, null);
|
||||
break;
|
||||
case Sign_Raw_Validated_By_Issuer:
|
||||
case Sign_Raw_Validated_By_Issuer_And_WriteIssuerData:
|
||||
byte[] txOut = transactionToSign.getRawDataToSign(mCard);
|
||||
signResult = protocol.run_SignRaw(pinsProvider.getPIN2(), transactionToSign.getHashAlgToSign(mCard), txOut, transactionToSign.getIssuerTransactionSignature(mCard, txOut), null, null);
|
||||
break;
|
||||
default:
|
||||
throw new CardProtocol.TangemException("Signing method isn't supported!");
|
||||
}
|
||||
|
||||
transactionToSign.onSignCompleted(mCard, signResult.getTLV(TLV.Tag.TAG_Signature).Value);
|
||||
mNotifications.onReadProgress(protocol, 100);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ dependencies {
|
|||
implementation project(':card-common')
|
||||
// implementation 'com.github.TangemCash.card_android-common:card_android-android:0.1.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue