Updated on 2026-08-14
4
.idea/gradle.xml
generated
|
|
@ -9,7 +9,9 @@
|
|||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/tangemcard" />
|
||||
<option value="$PROJECT_DIR$/tangemcard-android" />
|
||||
<option value="$PROJECT_DIR$/tangemcard-common" />
|
||||
<option value="$PROJECT_DIR$/tangemserver-android" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':tangemcard')
|
||||
implementation project(':tangemcard-common')
|
||||
implementation project(':tangemcard-android')
|
||||
implementation project(':tangemserver-android')
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
implementation 'com.android.support:support-compat:28.0.0'
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
android:required="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
|
|
|||
|
|
@ -3,13 +3,25 @@ package com.tangem;
|
|||
import android.app.Application;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tangem.tangemserver.android.data.LocalStorage;
|
||||
import com.tangem.di.DaggerNavigatorComponent;
|
||||
import com.tangem.di.DaggerNetworkComponent;
|
||||
import com.tangem.di.NavigatorComponent;
|
||||
import com.tangem.di.NetworkComponent;
|
||||
import com.tangem.tangemcard.data.Issuer;
|
||||
import com.tangem.tangemcard.data.local.Firmwares;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.android.data.Firmwares;
|
||||
import com.tangem.tangemcard.android.data.PINStorage;
|
||||
import com.tangem.tangemcard.data.external.FirmwaresDigestsProvider;
|
||||
import com.tangem.tangemcard.data.external.PINsProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
|
|
@ -33,6 +45,10 @@ public class App extends Application {
|
|||
return navigatorComponent;
|
||||
}
|
||||
|
||||
public static LocalStorage localStorage;
|
||||
public static PINsProvider pinStorage;
|
||||
public static FirmwaresDigestsProvider firmwaresStorage;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
|
@ -46,11 +62,13 @@ public class App extends Application {
|
|||
if (PINStorage.needInit())
|
||||
PINStorage.init(getApplicationContext());
|
||||
|
||||
if (Issuer.needInit())
|
||||
Issuer.init(getApplicationContext());
|
||||
initIssuers();
|
||||
|
||||
if (Firmwares.needInit())
|
||||
Firmwares.init(getApplicationContext());
|
||||
firmwaresStorage=new Firmwares(getApplicationContext());
|
||||
|
||||
localStorage=new LocalStorage(getApplicationContext());
|
||||
|
||||
pinStorage=new PINStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,4 +87,21 @@ public class App extends Application {
|
|||
.build();
|
||||
}
|
||||
|
||||
|
||||
public void initIssuers() {
|
||||
try {
|
||||
try (InputStream is = getApplicationContext().getAssets().open("issuers.json")) {
|
||||
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
Type listType = new TypeToken<List<Issuer>>() {
|
||||
}.getType();
|
||||
|
||||
|
||||
Issuer.fillIssuers(new Gson().fromJson(reader, listType));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard.data;
|
||||
package com.tangem.data;
|
||||
|
||||
import com.tangem.tangemcard.R;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ import android.security.keystore.KeyGenParameterSpec;
|
|||
import android.security.keystore.KeyPermanentlyInvalidatedException;
|
||||
import android.security.keystore.KeyProperties;
|
||||
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.android.data.PINStorage;
|
||||
import com.tangem.presentation.activity.PinRequestActivity;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
|||
|
|
@ -5,16 +5,7 @@ import android.support.annotation.NonNull;
|
|||
import android.util.Log;
|
||||
|
||||
import com.tangem.App;
|
||||
import com.tangem.tangemcard.data.network.TangemApi;
|
||||
import com.tangem.tangemcard.data.network.model.CardVerifyAndGetInfo;
|
||||
import com.tangem.data.network.model.RateInfoResponse;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem.data.network;
|
|||
import android.util.Log;
|
||||
|
||||
import com.tangem.App;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.domain.wallet.bch.BitcoinCashNode;
|
||||
import com.tangem.domain.wallet.btc.BitcoinNode;
|
||||
import com.tangem.domain.wallet.btc.BitcoinNodeTestNet;
|
||||
|
|
@ -62,9 +62,9 @@ public class ServerApiElectrum {
|
|||
electrumRequestDataListener = listener;
|
||||
}
|
||||
|
||||
public void electrumRequestData(TangemCard card, ElectrumRequest electrumRequest) {
|
||||
public void electrumRequestData(TangemContext ctx, ElectrumRequest electrumRequest) {
|
||||
Observable<ElectrumRequest> checkElectrumDataObserver = Observable.just(electrumRequest)
|
||||
.doOnNext(electrumRequest1 -> doElectrumRequest(card, electrumRequest))
|
||||
.doOnNext(electrumRequest1 -> doElectrumRequest(ctx, electrumRequest))
|
||||
|
||||
.flatMap(electrumRequest1 -> {
|
||||
if (electrumRequest1.answerData == null) {
|
||||
|
|
@ -106,11 +106,11 @@ public class ServerApiElectrum {
|
|||
});
|
||||
}
|
||||
|
||||
private List<ElectrumRequest> doElectrumRequest(TangemCard card, ElectrumRequest electrumRequest) {
|
||||
private List<ElectrumRequest> doElectrumRequest(TangemContext ctx, ElectrumRequest electrumRequest) {
|
||||
String host;
|
||||
int port;
|
||||
String proto;
|
||||
if (card.getBlockchain() == Blockchain.BitcoinTestNet) {
|
||||
if (ctx.getBlockchain() == Blockchain.BitcoinTestNet) {
|
||||
BitcoinNodeTestNet bitcoinNodeTestNet = BitcoinNodeTestNet.values()[new Random().nextInt(BitcoinNodeTestNet.values().length)];
|
||||
host = bitcoinNodeTestNet.getHost();
|
||||
port = bitcoinNodeTestNet.getPort();
|
||||
|
|
@ -120,7 +120,7 @@ public class ServerApiElectrum {
|
|||
|
||||
return doElectrumRequestTcp(electrumRequest, host, port);
|
||||
|
||||
} else if (card.getBlockchain() == Blockchain.BitcoinCash) {
|
||||
} else if (ctx.getBlockchain() == Blockchain.BitcoinCash) {
|
||||
BitcoinCashNode bitcoinCashNode = BitcoinCashNode.values()[new Random().nextInt(BitcoinCashNode.values().length)];
|
||||
host = bitcoinCashNode.getHost();
|
||||
port = bitcoinCashNode.getPort();
|
||||
|
|
@ -135,7 +135,7 @@ public class ServerApiElectrum {
|
|||
return doElectrumRequestSsl(electrumRequest, host, port);
|
||||
}
|
||||
|
||||
} else if (card.getBlockchain() == Blockchain.Bitcoin) {
|
||||
} else if (ctx.getBlockchain() == Blockchain.Bitcoin) {
|
||||
BitcoinNode bitcoinNode = BitcoinNode.values()[new Random().nextInt(BitcoinNode.values().length)];
|
||||
host = bitcoinNode.getHost();
|
||||
port = bitcoinNode.getPort();
|
||||
|
|
|
|||
|
|
@ -2,16 +2,12 @@ package com.tangem.di
|
|||
|
||||
import android.app.Activity
|
||||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import com.tangem.Constant
|
||||
import com.tangem.domain.wallet.CoinData
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.activity.EmptyWalletActivity
|
||||
import com.tangem.presentation.activity.LoadedWalletActivity
|
||||
import com.tangem.presentation.activity.MainActivity
|
||||
import com.tangem.presentation.activity.VerifyCardActivity
|
||||
import com.tangem.presentation.fragment.LoadedWallet
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.presentation.activity.*
|
||||
|
||||
class Navigator {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.domain.wallet;
|
|||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.data.Blockchain;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@ package com.tangem.domain.wallet;
|
|||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.tasks.SignTask;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.domain.wallet.btc.BtcEngine
|
|||
import com.tangem.domain.wallet.eth.EthEngine
|
||||
import com.tangem.domain.wallet.token.TokenEngine
|
||||
import com.tangem.domain.wallet.bch.BtcCashEngine
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.data.Blockchain
|
||||
|
||||
/**
|
||||
* Factory for create specific engine
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import android.content.Intent;
|
|||
import android.os.Bundle;
|
||||
|
||||
import com.tangem.Constant;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.tangemcard.data.TangemCardExtensionsKt;
|
||||
|
||||
|
||||
public class TangemContext {
|
||||
|
|
@ -17,7 +18,6 @@ public class TangemContext {
|
|||
private String error;
|
||||
private String message;
|
||||
|
||||
|
||||
public TangemContext() {
|
||||
|
||||
}
|
||||
|
|
@ -28,12 +28,29 @@ public class TangemContext {
|
|||
|
||||
public Blockchain getBlockchain() {
|
||||
if (card == null) return Blockchain.Unknown;
|
||||
return card.getBlockchain();
|
||||
Blockchain blockchain=Blockchain.fromId(card.getBlockchainID());
|
||||
if( (blockchain==Blockchain.Ethereum || blockchain==Blockchain.EthereumTestNet)&& card.isToken() )
|
||||
{
|
||||
return Blockchain.Token;
|
||||
}
|
||||
return blockchain;
|
||||
}
|
||||
|
||||
public void setBlockchain(Blockchain blockchain) {
|
||||
if (card == null) return;
|
||||
card.setBlockchain(blockchain);
|
||||
// public void setBlockchain(Blockchain blockchain) {
|
||||
// if (card == null) return;
|
||||
// card.setBlockchainID(blockchain.getID());
|
||||
// }
|
||||
|
||||
// private String blockchainName = "";
|
||||
|
||||
public String getBlockchainName() {
|
||||
Blockchain blockchain=getBlockchain();
|
||||
if( (blockchain==Blockchain.Ethereum || blockchain==Blockchain.EthereumTestNet)&& card.isToken() ) {
|
||||
String token = card.getTokenSymbol();
|
||||
return token + " <br><small><small> " + getBlockchain().getOfficialName() + " ERC20 token</small></small>";
|
||||
}else {
|
||||
return blockchain.getOfficialName();
|
||||
}
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
|
|
@ -85,9 +102,9 @@ public class TangemContext {
|
|||
TangemContext tangemContext = new TangemContext();
|
||||
tangemContext.setContext(context);
|
||||
|
||||
if (bundle.containsKey(TangemCard.EXTRA_UID)) {
|
||||
tangemContext.card = new TangemCard(bundle.getString(TangemCard.EXTRA_UID));
|
||||
tangemContext.card.loadFromBundle(bundle.getBundle(TangemCard.EXTRA_CARD));
|
||||
if (bundle.containsKey(TangemCardExtensionsKt.EXTRA_TANGEM_CARD_UID)) {
|
||||
tangemContext.card = new TangemCard(bundle.getString(TangemCardExtensionsKt.EXTRA_TANGEM_CARD_UID));
|
||||
TangemCardExtensionsKt.loadFromBundle(tangemContext.card, bundle.getBundle(TangemCardExtensionsKt.EXTRA_TANGEM_CARD));
|
||||
}
|
||||
|
||||
if (tangemContext.getBlockchain() != null) {
|
||||
|
|
@ -106,8 +123,8 @@ public class TangemContext {
|
|||
public void saveToIntent(Intent intent) {
|
||||
|
||||
if (card != null) {
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card.getUID());
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card.getAsBundle());
|
||||
intent.putExtra(TangemCardExtensionsKt.EXTRA_TANGEM_CARD_UID, card.getUID());
|
||||
intent.putExtra(TangemCardExtensionsKt.EXTRA_TANGEM_CARD, TangemCardExtensionsKt.getAsBundle(card));
|
||||
}
|
||||
|
||||
if (coinData != null) {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,9 @@ import android.net.Uri;
|
|||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.domain.wallet.BCHUtils;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.TLV;
|
||||
import com.tangem.domain.wallet.BalanceValidator;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.domain.wallet.CoinEngineFactory;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.domain.wallet.btc.BtcData;
|
||||
import com.tangem.domain.wallet.CoinData;
|
||||
import com.tangem.domain.wallet.CoinEngine;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@ package com.tangem.domain.wallet.btc;
|
|||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.TLV;
|
||||
import com.tangem.domain.wallet.BalanceValidator;
|
||||
import com.tangem.domain.wallet.Base58;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.domain.wallet.CoinData;
|
||||
import com.tangem.domain.wallet.CoinEngine;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,12 @@ import android.net.Uri;
|
|||
import android.text.InputFilter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.TLV;
|
||||
import com.tangem.domain.wallet.BalanceValidator;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.data.Blockchain;
|
||||
import com.tangem.domain.wallet.CoinData;
|
||||
import com.tangem.domain.wallet.CoinEngine;
|
||||
import com.tangem.domain.wallet.ECDSASignatureETH;
|
||||
import com.tangem.domain.wallet.EthTransaction;
|
||||
import com.tangem.tangemcard.data.Issuer;
|
||||
import com.tangem.domain.wallet.Keccak256;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
|
|
@ -236,7 +232,7 @@ public class EthEngine extends CoinEngine {
|
|||
|
||||
@Override
|
||||
public Uri getShareWalletUriExplorer() {
|
||||
if (ctx.getCard().getBlockchain() == Blockchain.EthereumTestNet)
|
||||
if (ctx.getBlockchain() == Blockchain.EthereumTestNet)
|
||||
return Uri.parse("https://rinkeby.etherscan.io/address/" + ctx.getCoinData().getWallet());
|
||||
else
|
||||
return Uri.parse("https://etherscan.io/address/" + ctx.getCoinData().getWallet());
|
||||
|
|
|
|||
|
|
@ -5,16 +5,11 @@ import android.text.InputFilter;
|
|||
import android.util.Log;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.tangem.tangemcard.data.Blockchain;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.TLV;
|
||||
import com.tangem.domain.wallet.BalanceValidator;
|
||||
import com.tangem.domain.wallet.CoinData;
|
||||
import com.tangem.domain.wallet.CoinEngine;
|
||||
import com.tangem.domain.wallet.ECDSASignatureETH;
|
||||
import com.tangem.domain.wallet.EthTransaction;
|
||||
import com.tangem.tangemcard.data.Issuer;
|
||||
import com.tangem.domain.wallet.Keccak256;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@ import com.tangem.data.network.ServerApiCommon
|
|||
import com.tangem.data.network.ServerApiElectrum
|
||||
import com.tangem.data.network.ServerApiInfura
|
||||
import com.tangem.data.network.model.InfuraResponse
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.domain.wallet.btc.BtcData
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.util.*
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -456,9 +457,9 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
return realTX.size
|
||||
}
|
||||
|
||||
private fun requestElectrum(card: TangemCard, electrumRequest: ElectrumRequest) {
|
||||
private fun requestElectrum(ctx: TangemContext, electrumRequest: ElectrumRequest) {
|
||||
if (UtilHelper.isOnline(this)) {
|
||||
serverApiElectrum.electrumRequestData(card, electrumRequest)
|
||||
serverApiElectrum.electrumRequestData(ctx, electrumRequest)
|
||||
} else
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,16 @@ import android.support.v7.app.AppCompatActivity
|
|||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.tangemcard.tasks.CreateNewWalletTask
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.tangemcard.data.asBundle
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_create_new_wallet.*
|
||||
|
||||
|
|
@ -31,7 +34,7 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
}
|
||||
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
|
||||
private var createNewWalletTask: CreateNewWalletTask? = null
|
||||
private var lastReadSuccess = true
|
||||
|
|
@ -70,7 +73,7 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
} else {
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
|
||||
}
|
||||
createNewWalletTask = CreateNewWalletTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
createNewWalletTask = CreateNewWalletTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage,this)
|
||||
createNewWalletTask!!.start()
|
||||
} else {
|
||||
// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
|
||||
|
|
@ -137,7 +140,7 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
val intent = Intent()
|
||||
intent.putExtra("message", "Cannot create wallet. Make sure you enter correct PIN2!")
|
||||
intent.putExtra("UID", cardProtocol.card.uid)
|
||||
intent.putExtra("Card", cardProtocol.card.asBundle)
|
||||
intent.putExtra("Card", cardProtocol.card!!.asBundle)
|
||||
setResult(RESULT_INVALID_PIN, intent)
|
||||
finish()
|
||||
} catch (e: Exception) {
|
||||
|
|
|
|||
|
|
@ -13,13 +13,18 @@ import android.support.v7.app.AppCompatActivity
|
|||
import android.text.Html
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.di.Navigator
|
||||
import com.tangem.tangemcard.tasks.VerifyCardTask
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.asBundle
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_empty_wallet.*
|
||||
|
|
@ -40,7 +45,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
}
|
||||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private lateinit var ctx: TangemContext
|
||||
private var lastReadSuccess = true
|
||||
private var verifyCardTask: VerifyCardTask? = null
|
||||
|
|
@ -59,15 +64,15 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
tvIssuer.text = ctx.card!!.issuerDescription
|
||||
//tvBlockchain.text = ctx.card!!.blockchainName
|
||||
if (ctx.card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
val html = Html.fromHtml(ctx.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
} else
|
||||
tvBlockchain.text = ctx.card!!.blockchainName
|
||||
tvBlockchain.text = ctx.blockchainName
|
||||
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
imgBlockchain.setImageResource(ctx.card!!.blockchain.getImageResource(this, ctx.card!!.tokenSymbol))
|
||||
imgBlockchain.setImageResource(ctx.blockchain.getImageResource(this, ctx.card!!.tokenSymbol))
|
||||
|
||||
if (ctx.card!!.useDefaultPIN1()!!) {
|
||||
if (ctx.card!!.useDefaultPIN1()) {
|
||||
imgPIN.setImageResource(R.drawable.unlock_pin1)
|
||||
imgPIN.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
@ -175,7 +180,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
isoDep.timeout = 65000
|
||||
}
|
||||
//lastTag = tag;
|
||||
verifyCardTask = VerifyCardTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
verifyCardTask = VerifyCardTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, App.firmwaresStorage, this)
|
||||
verifyCardTask!!.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -27,21 +27,21 @@ import com.scottyab.rootbeer.RootBeer
|
|||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.Logger
|
||||
import com.tangem.tangemcard.data.local.PINStorage
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.tangemcard.data.nfc.DeviceNFCAntennaLocation
|
||||
import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
|
||||
import com.tangem.tangemcard.tasks.ReadCardInfoTask
|
||||
import com.tangem.di.Navigator
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.data.local.Firmwares
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.RootFoundDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.data.Issuer
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.data.saveToBundle
|
||||
import com.tangem.util.CommonUtil
|
||||
import com.tangem.util.PhoneUtility
|
||||
import com.tangem.wallet.BuildConfig
|
||||
|
|
@ -70,7 +70,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
// }
|
||||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private var zipFile: File? = null
|
||||
private var antenna: DeviceNFCAntennaLocation? = null
|
||||
private var unsuccessReadCount = 0
|
||||
|
|
@ -264,7 +264,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
}
|
||||
lastTag = tag
|
||||
|
||||
readCardInfoTask = ReadCardInfoTask(this, nfcManager, isoDep, this)
|
||||
readCardInfoTask = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
readCardInfoTask!!.start()
|
||||
|
||||
// Log.i(TAG, "onTagDiscovered " + Arrays.toString(tag.getId()));
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@ import android.view.View
|
|||
import android.widget.Button
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.fingerprint.StartFingerprintReaderTask
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.data.fingerprint.FingerprintHelper
|
||||
import com.tangem.tangemcard.data.local.PINStorage
|
||||
import com.tangem.tangemcard.android.data.PINStorage
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_pin_request.*
|
||||
import kotlinx.android.synthetic.main.layout_pin_buttons.*
|
||||
|
|
@ -89,9 +92,9 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
|
|||
else if (mode == Mode.ConfirmNewPIN2)
|
||||
tvPinPrompt.setText(R.string.confirm_new_pin_2)
|
||||
else if (mode == Mode.RequestPIN2) {
|
||||
val uid = intent.getStringExtra(TangemCard.EXTRA_UID)
|
||||
val uid = intent.getStringExtra(EXTRA_TANGEM_CARD_UID)
|
||||
val card = TangemCard(uid)
|
||||
card.loadFromBundle(intent.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
card.loadFromBundle(intent.getBundleExtra(EXTRA_TANGEM_CARD))
|
||||
|
||||
if (card.PIN2 == TangemCard.PIN2_Mode.DefaultPIN2 || card.PIN2 == TangemCard.PIN2_Mode.Unchecked) {
|
||||
// if we know PIN2 or not try default previously - use it
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import android.widget.Toast
|
|||
import com.tangem.Constant
|
||||
import com.tangem.data.fingerprint.ConfirmWithFingerprintTask
|
||||
import com.tangem.data.fingerprint.FingerprintHelper
|
||||
import com.tangem.tangemcard.data.local.PINStorage
|
||||
import com.tangem.tangemcard.android.data.PINStorage
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_pin_save.*
|
||||
import kotlinx.android.synthetic.main.layout_pin_buttons.*
|
||||
|
|
|
|||
|
|
@ -13,13 +13,15 @@ import android.support.v7.app.AppCompatActivity
|
|||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.tangemcard.tasks.SwapPINTask
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.*
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_pin_swap.*
|
||||
|
|
@ -39,7 +41,7 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
|
|||
const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
|
||||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private var card: TangemCard? = null
|
||||
|
||||
private var newPIN: String? = null
|
||||
|
|
@ -57,8 +59,8 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
card = TangemCard(intent.getStringExtra(EXTRA_TANGEM_CARD_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(EXTRA_TANGEM_CARD))
|
||||
|
||||
newPIN = intent.getStringExtra(Constant.EXTRA_NEW_PIN)
|
||||
newPIN2 = intent.getStringExtra(Constant.EXTRA_NEW_PIN_2)
|
||||
|
|
@ -81,7 +83,7 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
|
|||
|
||||
if (sUID == card!!.uid) {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 65000
|
||||
swapPinTask = SwapPINTask(this, card, nfcManager, newPIN, newPIN2, isoDep, this)
|
||||
swapPinTask = SwapPINTask(card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this, newPIN, newPIN2)
|
||||
swapPinTask!!.start()
|
||||
} else {
|
||||
// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + mCard!!.uid + ")")
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import android.os.Bundle
|
|||
import android.support.v7.app.AppCompatActivity
|
||||
import android.view.View
|
||||
import com.tangem.data.network.CryptonitOtherApi
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.*
|
||||
import java.io.IOException
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import android.view.inputmethod.EditorInfo
|
|||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import com.tangem.data.network.Cryptonit
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
|
|
@ -145,7 +145,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
|
||||
tvError.visibility = View.INVISIBLE
|
||||
cryptonit!!.requestBalance(ctx.card!!.blockchain.currency)
|
||||
cryptonit!!.requestBalance(ctx.blockchain.currency)
|
||||
} else {
|
||||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = getString(R.string.cryptonit_not_enough_account_data)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import android.view.inputmethod.EditorInfo
|
|||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import com.tangem.data.network.Kraken
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.wallet.R
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import android.text.Html
|
|||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -50,7 +50,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
tvBalance.text = html
|
||||
|
||||
//TODO - to engine
|
||||
if (ctx.card!!.blockchain == Blockchain.Token && engine.balance.currency!="ETH") {
|
||||
if (ctx.blockchain == Blockchain.Token && engine.balance.currency!="ETH") {
|
||||
rgIncFee!!.visibility = View.INVISIBLE
|
||||
} else {
|
||||
rgIncFee!!.visibility = View.VISIBLE
|
||||
|
|
@ -152,7 +152,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
|
||||
var code = data.getStringExtra("QRCode")
|
||||
when (ctx.card!!.blockchain) {
|
||||
when (ctx.blockchain) {
|
||||
Blockchain.Bitcoin -> {
|
||||
if (code.contains("bitcoin:")) {
|
||||
val tmp = code.split("bitcoin:".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
|
|
|||
|
|
@ -12,12 +12,15 @@ import android.os.Bundle
|
|||
import android.support.v7.app.AppCompatActivity
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.tangemcard.tasks.PurgeTask
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.asBundle
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_purge.*
|
||||
|
|
@ -30,7 +33,7 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
|
|||
}
|
||||
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private var purgeTask: PurgeTask? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -79,7 +82,7 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
|
|||
|
||||
if (sUID == ctx.card!!.uid) {
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
|
||||
purgeTask = PurgeTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
purgeTask = PurgeTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
purgeTask!!.start()
|
||||
} else {
|
||||
// this Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card.getUID() + ")");
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@ import com.tangem.data.network.ElectrumRequest
|
|||
import com.tangem.data.network.ServerApiElectrum
|
||||
import com.tangem.data.network.ServerApiInfura
|
||||
import com.tangem.data.network.model.InfuraResponse
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.domain.wallet.eth.EthData
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.R
|
||||
import java.io.IOException
|
||||
|
|
@ -51,9 +50,9 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet || ctx.blockchain == Blockchain.Token)
|
||||
requestInfura(ServerApiInfura.INFURA_ETH_SEND_RAW_TRANSACTION, "")
|
||||
else if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet)
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.coinData!!.wallet, tx))
|
||||
requestElectrum(ctx, ElectrumRequest.broadcast(ctx.coinData!!.wallet, tx))
|
||||
else if (ctx.blockchain == Blockchain.BitcoinCash)
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.coinData!!.wallet, tx))
|
||||
requestElectrum(ctx, ElectrumRequest.broadcast(ctx.coinData!!.wallet, tx))
|
||||
|
||||
// request electrum listener
|
||||
val electrumBodyListener: ServerApiElectrum.ElectrumRequestDataListener = object : ServerApiElectrum.ElectrumRequestDataListener {
|
||||
|
|
@ -151,9 +150,9 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
finishWithError(getString(R.string.no_connection))
|
||||
}
|
||||
|
||||
private fun requestElectrum(card: TangemCard, electrumRequest: ElectrumRequest) {
|
||||
private fun requestElectrum(ctx: TangemContext, electrumRequest: ElectrumRequest) {
|
||||
if (UtilHelper.isOnline(this)) {
|
||||
serverApiElectrum.electrumRequestData(card, electrumRequest)
|
||||
serverApiElectrum.electrumRequestData(ctx, electrumRequest)
|
||||
} else
|
||||
finishWithError(getString(R.string.no_connection))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,18 @@ import android.view.KeyEvent
|
|||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.domain.wallet.BTCUtils
|
||||
import com.tangem.domain.wallet.CoinEngine
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.asBundle
|
||||
import com.tangem.tangemcard.tasks.SignTask
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -43,7 +46,7 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
|
||||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private lateinit var ctx: TangemContext
|
||||
|
||||
// private var signPaymentTask: SignPaymentTask? = null
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@ import android.support.v7.app.AppCompatActivity
|
|||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.di.Navigator
|
||||
import com.tangem.domain.wallet.CoinData
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.presentation.fragment.VerifyCard
|
||||
import com.tangem.wallet.R
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -19,18 +19,17 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.tangemcard.data.local.LocalStorage
|
||||
import com.tangem.tangemcard.data.local.PINStorage
|
||||
import com.tangem.data.network.ElectrumRequest
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.data.network.ServerApiElectrum
|
||||
import com.tangem.data.network.ServerApiInfura
|
||||
import com.tangem.tangemcard.data.network.model.CardVerifyAndGetInfo
|
||||
import com.tangem.tangemserver.android.model.CardVerifyAndGetInfo
|
||||
import com.tangem.data.network.model.InfuraResponse
|
||||
import com.tangem.tangemcard.tasks.VerifyCardTask
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.domain.wallet.bch.BtcCashEngine
|
||||
import com.tangem.domain.wallet.btc.BtcData
|
||||
|
|
@ -42,11 +41,14 @@ import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
|||
import com.tangem.presentation.dialog.PINSwapWarningDialog
|
||||
import com.tangem.presentation.dialog.ShowQRCodeDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.tangemcard.android.reader.NfcReader
|
||||
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.data.network.Server
|
||||
import com.tangem.tangemcard.data.network.ServerApiTangem
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.util.Util
|
||||
import com.tangem.tangemserver.android.ServerApiTangem
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fr_loaded_wallet.*
|
||||
|
|
@ -60,7 +62,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val TAG: String = LoadedWallet::class.java.simpleName
|
||||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private lateinit var nfcManager: NfcManager
|
||||
|
||||
private var serverApiCommon: ServerApiCommon = ServerApiCommon()
|
||||
private var serverApiInfura: ServerApiInfura = ServerApiInfura()
|
||||
|
|
@ -82,7 +84,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
private val activeColor: ColorStateList by lazy { resources.getColorStateList(R.color.colorAccent) }
|
||||
private var requestCounter = 0
|
||||
private var timerRepeatRefresh: Timer? = null
|
||||
private lateinit var localStorage: LocalStorage
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -92,7 +93,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
lastTag = activity?.intent?.getParcelableExtra(Constant.EXTRA_LAST_DISCOVERED_TAG)
|
||||
|
||||
localStorage = activity?.let { LocalStorage(it) }!!
|
||||
//localStorage = activity?.let { CardDataSubstitutionProvider(it) }!!
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
|
|
@ -105,7 +106,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (ctx.blockchain == Blockchain.Token)
|
||||
tvBalance.setSingleLine(false)
|
||||
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card))
|
||||
ivTangemCard.setImageBitmap(App.localStorage.getCardArtworkBitmap(ctx.card))
|
||||
|
||||
btnExtract.isEnabled = false
|
||||
btnExtract.backgroundTintList = inactiveColor
|
||||
|
|
@ -419,18 +420,20 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
if (!result.passed) return
|
||||
|
||||
if (localStorage.checkBatchInfoChanged(ctx.card!!, result)) {
|
||||
if (App.localStorage.checkBatchInfoChanged(ctx.card!!, result)) {
|
||||
Log.w(TAG, "Batch ${result.batch} info changed to '$result'")
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
localStorage.applySubstitution(ctx.card!!)
|
||||
if (ctx.card!!.blockchain == Blockchain.Token || ctx.card!!.blockchain == Blockchain.Ethereum) {
|
||||
ctx.card!!.setBlockchainIDFromCard(Blockchain.Ethereum.id)
|
||||
ivTangemCard.setImageBitmap(App.localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
App.localStorage.applySubstitution(ctx.card!!)
|
||||
//todo - check this is not need after refactoring
|
||||
// if (ctx.blockchain == Blockchain.Token || ctx.blockchain == Blockchain.Ethereum) {
|
||||
// ctx.card!!.setBlockchainIDFromCard(Blockchain.Ethereum.id)
|
||||
|
||||
//ctx.blockchain=Blockchain.Ethereum
|
||||
//engine=engine!!.swithToOtherEngine(Blockchain.Ethereum)
|
||||
}
|
||||
// }
|
||||
refresh()
|
||||
}
|
||||
if (result.artwork != null && localStorage.checkNeedUpdateArtwork(result.artwork)) {
|
||||
if (result.artwork != null && App.localStorage.checkNeedUpdateArtwork(result.artwork)) {
|
||||
Log.w(TAG, "Artwork '${result.artwork!!.id}' updated, need download")
|
||||
serverApiTangem.requestArtwork(result.artwork!!.id, result.artwork!!.getUpdateDate(), ctx.card!!)
|
||||
updateViews()
|
||||
|
|
@ -447,8 +450,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
// request artwork listener
|
||||
val artworkListener: ServerApiTangem.ArtworkListener = object : ServerApiTangem.ArtworkListener {
|
||||
override fun onSuccess(artworkId: String?, inputStream: InputStream?, updateDate: Date?) {
|
||||
localStorage.updateArtwork(artworkId!!, inputStream!!, updateDate!!)
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
App.localStorage.updateArtwork(artworkId!!, inputStream!!, updateDate!!)
|
||||
ivTangemCard.setImageBitmap(App.localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
}
|
||||
|
||||
override fun onFail(message: String?) {
|
||||
|
|
@ -538,12 +541,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
newPIN = ctx.card!!.pin
|
||||
|
||||
if (newPIN2 == "")
|
||||
newPIN2 = PINStorage.getPIN2()
|
||||
newPIN2 = App.pinStorage.piN2
|
||||
|
||||
val pinSwapWarningDialog = PINSwapWarningDialog()
|
||||
pinSwapWarningDialog.setOnRefreshPage { (activity as LoadedWalletActivity).navigator.showPinSwap(context as Activity, newPIN, newPIN2) }
|
||||
val bundle = Bundle()
|
||||
if (!PINStorage.isDefaultPIN(newPIN) || !PINStorage.isDefaultPIN2(newPIN2))
|
||||
if (!CardProtocol.isDefaultPIN(newPIN) || !CardProtocol.isDefaultPIN2(newPIN2))
|
||||
bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_forget))
|
||||
else
|
||||
bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
|
||||
|
|
@ -563,9 +566,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
activity?.finish()
|
||||
|
||||
} else {
|
||||
if (data != null && data.extras != null && data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
if (data != null && data.extras != null && data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
|
|
@ -599,9 +602,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
activity?.finish()
|
||||
|
||||
} else {
|
||||
if (data != null && data.extras != null && data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
if (data != null && data.extras != null && data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
|
|
@ -627,9 +630,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
}
|
||||
|
||||
if (data != null && data.extras != null) {
|
||||
if (data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
if (data.extras!!.containsKey(EXTRA_TANGEM_CARD_UID) && data.extras!!.containsKey(EXTRA_TANGEM_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(EXTRA_TANGEM_CARD_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(EXTRA_TANGEM_CARD))
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (data.extras!!.containsKey("message")) {
|
||||
|
|
@ -773,10 +776,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
tvWallet.text = ctx.coinData!!.wallet
|
||||
|
||||
if (ctx.card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
val html = Html.fromHtml(ctx.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
} else
|
||||
tvBlockchain.text = ctx.card!!.blockchainName
|
||||
tvBlockchain.text = ctx.blockchainName
|
||||
|
||||
if (engine.hasBalanceInfo()) {
|
||||
btnExtract.isEnabled = true
|
||||
|
|
@ -842,7 +845,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
private fun requestElectrum(electrumRequest: ElectrumRequest) {
|
||||
if (UtilHelper.isOnline(context as Activity)) {
|
||||
requestCounter++
|
||||
serverApiElectrum.electrumRequestData(ctx.card, electrumRequest)
|
||||
serverApiElectrum.electrumRequestData(ctx, electrumRequest)
|
||||
} else {
|
||||
Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
|
||||
srl?.isRefreshing = false
|
||||
|
|
@ -898,7 +901,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
else
|
||||
isoDep.timeout = 65000
|
||||
|
||||
verifyCardTask = VerifyCardTask(activity, ctx.card, nfcManager, isoDep, this)
|
||||
verifyCardTask = VerifyCardTask(ctx.card, NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, App.firmwaresStorage, this)
|
||||
verifyCardTask?.start()
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
|
|
|||
|
|
@ -8,19 +8,23 @@ import android.os.Bundle
|
|||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.Html
|
||||
import android.text.format.DateUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.Toast
|
||||
import com.tangem.tangemcard.data.local.PINStorage
|
||||
import com.tangem.tangemcard.reader.NfcManager
|
||||
import com.tangem.App
|
||||
import com.tangem.tangemcard.android.data.PINStorage
|
||||
import com.tangem.tangemcard.android.reader.NfcManager
|
||||
import com.tangem.Constant
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.presentation.activity.*
|
||||
import com.tangem.presentation.dialog.PINSwapWarningDialog
|
||||
import com.tangem.tangemcard.data.Blockchain
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.tangemcard.data.TangemCard
|
||||
import com.tangem.tangemcard.data.loadFromBundle
|
||||
import com.tangem.tangemcard.reader.CardProtocol
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fr_verify_card.*
|
||||
|
|
@ -123,12 +127,12 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
Constant.REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (newPIN == "") newPIN = ctx.card!!.pin
|
||||
|
||||
if (newPIN2 == "") newPIN2 = PINStorage.getPIN2()
|
||||
if (newPIN2 == "") newPIN2 = App.pinStorage.getPIN2()
|
||||
|
||||
val pinSwapWarningDialog = PINSwapWarningDialog()
|
||||
pinSwapWarningDialog.setOnRefreshPage { (activity as VerifyCardActivity).navigator.showPinSwap(context as Activity, newPIN, newPIN2) }
|
||||
val bundle = Bundle()
|
||||
if (!PINStorage.isDefaultPIN(newPIN) || !PINStorage.isDefaultPIN2(newPIN2))
|
||||
if (!CardProtocol.isDefaultPIN(newPIN) || !CardProtocol.isDefaultPIN2(newPIN2))
|
||||
bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_forget))
|
||||
else
|
||||
bundle.putString(PINSwapWarningDialog.EXTRA_MESSAGE, getString(R.string.if_you_use_default))
|
||||
|
|
@ -203,7 +207,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (resultCode == Activity.RESULT_OK) {
|
||||
srlVerifyCard.isRefreshing = true
|
||||
ctx.coinData!!.clearInfo()
|
||||
ctx.card!!.switchToInitialBlockchain()
|
||||
//ctx.card!!.switchToInitialBlockchain()
|
||||
updateViews()
|
||||
}
|
||||
|
||||
|
|
@ -269,8 +273,9 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
|
||||
tvIssuer.text = ctx.card!!.issuerDescription
|
||||
tvCardRegistredDate.text = ctx.card!!.personalizationDateTimeDescription
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
|
||||
tvCardRegistredDate.text = DateUtils.formatDateTime(null, ctx.card!!.personalizationDateTime.time, DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NUMERIC_DATE or DateUtils.FORMAT_SHOW_YEAR)
|
||||
val html = Html.fromHtml(ctx.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
|
||||
tvValidationNode.text = ctx.coinData!!.validationNodeDescription
|
||||
|
|
@ -350,7 +355,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
|
||||
tvFeatures.text = features
|
||||
|
||||
if (ctx.card!!.useDefaultPIN1()!!) {
|
||||
if (ctx.card!!.useDefaultPIN1()) {
|
||||
imgPIN.setImageResource(R.drawable.unlock_pin1)
|
||||
imgPIN.setOnClickListener { Toast.makeText(context, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
include ':app', ':tangemcard'
|
||||
include ':app', ':tangemcard-android', ':tangemserver-android', ':tangemcard-common'
|
||||
|
|
|
|||
|
|
@ -23,25 +23,25 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':tangemcard-common')
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
// implementation 'com.android.support:design:28.0.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.madgag.spongycastle:core:1.56.0.0'
|
||||
implementation 'com.madgag.spongycastle:prov:1.56.0.0'
|
||||
implementation 'com.scottyab:rootbeer-lib:0.0.7'
|
||||
|
||||
// implementation 'com.android.support:support-compat:28.0.0'
|
||||
// implementation 'com.android.support:support-v4:28.0.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
||||
// implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
|
||||
// implementation 'com.squareup.retrofit2:retrofit:2.5.0'
|
||||
// implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
||||
// implementation 'com.skyfishjy.ripplebackground:library:1.0.1'
|
||||
// implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
|
||||
implementation 'com.google.dagger:dagger:2.16'
|
||||
implementation 'org.bitcoinj:bitcoinj-parent:0.14.7'
|
||||
implementation 'org.bitcoinj:bitcoinj-core:0.14.7'
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
|
||||
// implementation 'com.google.dagger:dagger:2.16'
|
||||
// implementation 'org.bitcoinj:bitcoinj-parent:0.14.7'
|
||||
// implementation 'org.bitcoinj:bitcoinj-core:0.14.7'
|
||||
// annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
|
||||
// implementation 'info.hoang8f:android-segmented:1.0.6'
|
||||
// implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
|
||||
// implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard;
|
||||
package com.tangem.tangemcard.android;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
8
tangemcard-android/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tangem.tangemcard" >
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
</manifest>
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package com.tangem.tangemcard.data.local;
|
||||
package com.tangem.tangemcard.android.data;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.tangem.tangemcard.data.external.FirmwaresDigestsProvider;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -12,14 +13,10 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class Firmwares {
|
||||
public class Firmwares implements FirmwaresDigestsProvider {
|
||||
private static JsonArray jaFirmwares = null;
|
||||
|
||||
public static boolean needInit() {
|
||||
return jaFirmwares == null;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
public Firmwares(Context context) {
|
||||
try (InputStream is = context.getAssets().open("fw_hashes.json")) {
|
||||
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
JsonParser parser = new JsonParser();
|
||||
|
|
@ -30,21 +27,14 @@ public class Firmwares {
|
|||
}
|
||||
}
|
||||
|
||||
public static class VerifyCodeRecord {
|
||||
public String hashAlg;
|
||||
public int blockIndex;
|
||||
public int blockCount;
|
||||
public byte[] challenge;
|
||||
public byte[] digest;
|
||||
}
|
||||
|
||||
public static VerifyCodeRecord selectRandomVerifyCodeBlock(String firmwareVersion) throws IOException {
|
||||
@Override
|
||||
public FirmwaresDigestsProvider.VerifyCodeRecord selectRandomVerifyCodeBlock(String firmwareVersion) {
|
||||
|
||||
try {
|
||||
for (int i = 0; i < jaFirmwares.size(); i++) {
|
||||
JsonObject jsVersion = jaFirmwares.get(i).getAsJsonObject();
|
||||
if (jsVersion.get("fw").getAsString().equals(firmwareVersion)) {
|
||||
VerifyCodeRecord result = new VerifyCodeRecord();
|
||||
FirmwaresDigestsProvider.VerifyCodeRecord result = new FirmwaresDigestsProvider.VerifyCodeRecord();
|
||||
result.hashAlg = "sha-256";
|
||||
JsonArray jsHashes = jsVersion.get(result.hashAlg).getAsJsonArray();
|
||||
result.challenge = Util.hexToBytes(jsVersion.get("challenge").getAsString());
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package com.tangem.tangemcard.data.local;
|
||||
package com.tangem.tangemcard.android.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.tangem.tangemcard.data.external.PINsProvider;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -17,7 +18,7 @@ import javax.crypto.Cipher;
|
|||
* Global PIN Storage
|
||||
*/
|
||||
|
||||
public class PINStorage {
|
||||
public class PINStorage implements PINsProvider {
|
||||
private static String mSavedPIN, mUserPIN, mLastUsedPIN, mEncryptedPIN, mPIN2;
|
||||
private static SharedPreferences sharedPreferences = null;
|
||||
|
||||
|
|
@ -30,8 +31,8 @@ public class PINStorage {
|
|||
mPIN2 = null;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> getPINs() {
|
||||
@Override
|
||||
public List<String> getPINs() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if (mLastUsedPIN != null) result.add(mLastUsedPIN);
|
||||
if (mEncryptedPIN != null && !result.contains(mEncryptedPIN)) result.add(mEncryptedPIN);
|
||||
|
|
@ -41,7 +42,7 @@ public class PINStorage {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static void setLastUsedPIN(String PIN) {
|
||||
public void setLastUsedPIN(String PIN) {
|
||||
mLastUsedPIN = PIN;
|
||||
}
|
||||
|
||||
|
|
@ -177,18 +178,10 @@ public class PINStorage {
|
|||
editor.apply();
|
||||
}
|
||||
|
||||
public static String getPIN2() {
|
||||
public String getPIN2() {
|
||||
return mPIN2;
|
||||
}
|
||||
|
||||
public static boolean isDefaultPIN(String pin) {
|
||||
return (CardProtocol.DefaultPIN.equals(pin));
|
||||
}
|
||||
|
||||
public static boolean isDefaultPIN2(String pin2) {
|
||||
return (CardProtocol.DefaultPIN2.equals(pin2));
|
||||
}
|
||||
|
||||
public static String getDefaultPIN() {
|
||||
return CardProtocol.DefaultPIN;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard.data.nfc
|
||||
package com.tangem.tangemcard.android.nfc
|
||||
|
||||
import android.os.Build
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard.data.nfc
|
||||
package com.tangem.tangemcard.android.nfc
|
||||
|
||||
enum class NFCLocation(val codename: String, val fullName: String, val orientation: Int, val x: Int, val y: Int, val z: Int) {
|
||||
model1("sailfish", "Google Pixel", 0, 65, 25, 0),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard.presentation.dialog
|
||||
package com.tangem.tangemcard.android.presentation.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangemcard.reader;
|
||||
package com.tangem.tangemcard.android.reader;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.TargetApi;
|
||||
|
|
@ -16,7 +16,7 @@ import android.os.Bundle;
|
|||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import com.tangem.tangemcard.presentation.dialog.NfcEnableDialog;
|
||||
import com.tangem.tangemcard.android.presentation.dialog.NfcEnableDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.tangemcard.android.reader
|
||||
|
||||
import android.nfc.tech.IsoDep
|
||||
|
||||
data class NfcReader(
|
||||
val nfcManager: NfcManager,
|
||||
val isoDep: IsoDep
|
||||
) : com.tangem.tangemcard.reader.NfcReader {
|
||||
override fun getId(): ByteArray {
|
||||
return isoDep.tag.id
|
||||
}
|
||||
|
||||
override fun setTimeout(timeout: Int) {
|
||||
isoDep.timeout = timeout
|
||||
}
|
||||
|
||||
override fun getTimeout(): Int {
|
||||
return isoDep.timeout
|
||||
}
|
||||
|
||||
override fun transceive(data: ByteArray?): ByteArray {
|
||||
return isoDep.transceive(data)
|
||||
}
|
||||
|
||||
override fun ignoreTag() {
|
||||
nfcManager.ignoreTag(isoDep.tag)
|
||||
}
|
||||
|
||||
override fun notifyReadResult(success: Boolean) {
|
||||
nfcManager.notifyReadResult(success)
|
||||
}
|
||||
|
||||
override fun connect() {
|
||||
val timeout = isoDep.timeout
|
||||
isoDep.connect()
|
||||
isoDep.close()
|
||||
isoDep.connect()
|
||||
isoDep.timeout = timeout
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
package com.tangem.tangemcard.data
|
||||
|
||||
import android.os.Bundle
|
||||
import com.tangem.tangemcard.util.Log
|
||||
import java.util.*
|
||||
|
||||
const val EXTRA_TANGEM_CARD = "Card"
|
||||
const val EXTRA_TANGEM_CARD_UID = "UID"
|
||||
|
||||
fun TangemCard.loadFromBundle(B: Bundle) {
|
||||
uid = B.getString("UID")
|
||||
cid = B.getByteArray("CID")
|
||||
pin = B.getString("PIN")
|
||||
PIN2 = TangemCard.PIN2_Mode.valueOf(B.getString("PIN2")!!)
|
||||
status = TangemCard.Status.valueOf(B.getString("Status")!!)
|
||||
blockchainID = B.getString("Blockchain")
|
||||
tokensDecimal = B.getInt("TokensDecimal", 18)
|
||||
tokenSymbol = B.getString("TokenSymbol", "")
|
||||
contractAddress = B.getString("ContractAddress", "")
|
||||
// if (B.containsKey("BlockchainName"))
|
||||
// blockchainName = B.getString("BlockchainName", "");
|
||||
if (B.containsKey("dtPersonalization")) {
|
||||
personalizationDateTime = Date(B.getLong("dtPersonalization"))
|
||||
}
|
||||
remainingSignatures = B.getInt("RemainingSignatures")
|
||||
maxSignatures = B.getInt("MaxSignatures")
|
||||
health = B.getInt("health")
|
||||
if (B.containsKey("settingsMask")) settingsMask = B.getInt("settingsMask")
|
||||
pauseBeforePIN2 = B.getInt("pauseBeforePIN2")
|
||||
if (B.containsKey("signingMethod"))
|
||||
setSigningMethod(TangemCard.SigningMethod.valueOf(B.getString("signingMethod")!!).ID)
|
||||
if (B.containsKey("Manufacturer"))
|
||||
setManufacturer(Manufacturer.valueOf(B.getString("Manufacturer")!!), B.getBoolean("ManufacturerConfirmed", false))
|
||||
if (B.containsKey("EncryptionMode"))
|
||||
encryptionMode = TangemCard.EncryptionMode.valueOf(B.getString("EncryptionMode")!!)
|
||||
else
|
||||
encryptionMode = null
|
||||
|
||||
if (B.containsKey("SignedHashes")) signedHashes = B.getInt("SignedHashes")
|
||||
|
||||
if (B.containsKey("Issuer")) setIssuer(B.getString("Issuer"), B.getByteArray("IssuerPublicDataKey"))
|
||||
|
||||
if (B.containsKey("FirmwareVersion")) firmwareVersion = B.getString("FirmwareVersion")
|
||||
if (B.containsKey("Batch")) batch = B.getString("Batch")
|
||||
|
||||
isCardPublicKeyValid = B.getBoolean("CardPublicKeyValid")
|
||||
if (B.containsKey("CardPublicKey")) cardPublicKey = B.getByteArray("CardPublicKey")
|
||||
|
||||
if (B.containsKey("OfflineBalance")) offlineBalance = B.getByteArray("OfflineBalance")
|
||||
else clearOfflineBalance()
|
||||
|
||||
if (B.containsKey("Denomination") && B.containsKey("DenominationText")) {
|
||||
setDenomination(B.getByteArray("Denomination"), B.getString("DenominationText"))
|
||||
} else if (B.containsKey("Denomination")) {
|
||||
setDenomination(B.getByteArray("Denomination"), "N/A")
|
||||
} else clearDenomination()
|
||||
|
||||
if (B.containsKey("IssuerData") && B.containsKey("IssuerDataSignature"))
|
||||
setIssuerData(B.getByteArray("IssuerData"), B.getByteArray("IssuerDataSignature"))
|
||||
else setIssuerData(null, null)
|
||||
|
||||
if (B.containsKey("NeedWriteIssuerData"))
|
||||
needWriteIssuerData = B.getBoolean("NeedWriteIssuerData")
|
||||
|
||||
isWalletPublicKeyValid = B.getBoolean("WalletPublicKeyValid")
|
||||
if (B.containsKey("PublicKey")) {
|
||||
walletPublicKey = B.getByteArray("PublicKey")
|
||||
}
|
||||
if (B.containsKey("PublicKeyRar")) {
|
||||
walletPublicKeyRar = B.getByteArray("PublicKeyRar")
|
||||
}
|
||||
|
||||
if (B.containsKey("codeConfirmed"))
|
||||
isCodeConfirmed = B.getBoolean("codeConfirmed")
|
||||
|
||||
if (B.containsKey("onlineVerified"))
|
||||
isOnlineVerified = B.getBoolean("onlineVerified")
|
||||
|
||||
if (B.containsKey("onlineValidated"))
|
||||
isOnlineValidated = B.getBoolean("onlineValidated")
|
||||
|
||||
}
|
||||
|
||||
val TangemCard.asBundle: Bundle
|
||||
get() {
|
||||
val bundle = Bundle()
|
||||
saveToBundle(bundle)
|
||||
return bundle
|
||||
}
|
||||
|
||||
fun TangemCard.saveToBundle(B: Bundle) {
|
||||
try {
|
||||
B.putString("UID", uid)
|
||||
B.putByteArray("CID", cid)
|
||||
B.putString("PIN", pin)
|
||||
B.putString("PIN2", PIN2.name)
|
||||
B.putString("Status", status.name)
|
||||
B.putString("Blockchain", blockchainID)
|
||||
B.putInt("TokensDecimal", tokensDecimal)
|
||||
B.putString("TokenSymbol", tokenSymbol)
|
||||
B.putString("ContractAddress", contractAddress)
|
||||
if (personalizationDateTime != null) B.putLong("dtPersonalization", personalizationDateTime.time)
|
||||
|
||||
B.putInt("RemainingSignatures", remainingSignatures)
|
||||
B.putInt("MaxSignatures", maxSignatures)
|
||||
B.putInt("Health", health)
|
||||
if (settingsMask != null) B.putInt("settingsMask", settingsMask)
|
||||
B.putInt("pauseBeforePIN2", pauseBeforePIN2)
|
||||
if (signingMethod != null) B.putString("signingMethod", signingMethod.name)
|
||||
if (manufacturer != null) B.putString("Manufacturer", manufacturer.name)
|
||||
if (encryptionMode != null) B.putString("EncryptionMode", encryptionMode.name)
|
||||
if (issuer != null) B.putString("Issuer", issuer.getID())
|
||||
if (issuerPublicDataKey != null) B.putByteArray("IssuerPublicDataKey", issuerPublicDataKey)
|
||||
if (firmwareVersion != null) B.putString("FirmwareVersion", firmwareVersion)
|
||||
if (batch != null) B.putString("Batch", batch)
|
||||
B.putBoolean("ManufacturerConfirmed", isManufacturerConfirmed)
|
||||
B.putBoolean("CardPublicKeyValid", isCardPublicKeyValid)
|
||||
B.putByteArray("CardPublicKey", cardPublicKey)
|
||||
|
||||
B.putInt("SignedHashes", signedHashes)
|
||||
B.putBoolean("WalletPublicKeyValid", isWalletPublicKeyValid)
|
||||
if (walletPublicKey != null)
|
||||
B.putByteArray("PublicKey", walletPublicKey)
|
||||
if (walletPublicKeyRar != null)
|
||||
B.putByteArray("PublicKeyRar", walletPublicKeyRar)
|
||||
|
||||
if (offlineBalance != null) B.putByteArray("OfflineBalance", offlineBalance)
|
||||
|
||||
if (denomination != null) B.putByteArray("Denomination", denomination)
|
||||
if (denominationText != null) B.putString("DenominationText", denominationText)
|
||||
|
||||
if (issuerData != null && issuerDataSignature != null) {
|
||||
B.putByteArray("IssuerData", issuerData)
|
||||
B.putByteArray("IssuerDataSignature", issuerDataSignature)
|
||||
B.putBoolean("NeedWriteIssuerData", needWriteIssuerData)
|
||||
}
|
||||
|
||||
if (isCodeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", isCodeConfirmed)
|
||||
|
||||
if (isOnlineVerified != null)
|
||||
B.putBoolean("onlineVerified", isOnlineVerified)
|
||||
|
||||
if (isOnlineValidated != null)
|
||||
B.putBoolean("onlineValidated", isOnlineValidated)
|
||||
} catch (e: Exception) {
|
||||
Log.e("Can't save to bundle ", e.message)
|
||||
}
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 536 B After Width: | Height: | Size: 536 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.tangemcard.android;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
1
tangemcard-common/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
12
tangemcard-common/build.gradle
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation 'com.madgag.spongycastle:core:1.56.0.0'
|
||||
implementation 'com.madgag.spongycastle:prov:1.56.0.0'
|
||||
|
||||
}
|
||||
|
||||
sourceCompatibility = "7"
|
||||
targetCompatibility = "7"
|
||||
|
|
@ -1,16 +1,8 @@
|
|||
package com.tangem.tangemcard.data;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tangem.tangemcard.reader.CardCrypto;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
|
@ -27,7 +19,7 @@ public class Issuer {
|
|||
|
||||
byte[] getPrivateKey() throws Exception {
|
||||
if (privateKey != null) {
|
||||
return CardCrypto.GeneratePublicKey(Util.hexToBytes(privateKey));
|
||||
return Util.hexToBytes(privateKey);
|
||||
} else {
|
||||
throw new Exception("No private key!");
|
||||
}
|
||||
|
|
@ -47,8 +39,8 @@ public class Issuer {
|
|||
|
||||
}
|
||||
|
||||
private String id;
|
||||
private String officialName;
|
||||
public String id;
|
||||
public String officialName;
|
||||
private KeyPair dataKey;
|
||||
private KeyPair transactionKey;
|
||||
|
||||
|
|
@ -58,27 +50,16 @@ public class Issuer {
|
|||
|
||||
private static List<Issuer> instances = new ArrayList<>();
|
||||
|
||||
public static boolean needInit() {
|
||||
return instances.size() == 0;
|
||||
static {
|
||||
Issuer unknown = new Issuer();
|
||||
unknown.id = "UNKNOWN";
|
||||
unknown.officialName = "UNKNOWN";
|
||||
instances.add(unknown);
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
try {
|
||||
Issuer unknown = new Issuer();
|
||||
unknown.id = "UNKNOWN";
|
||||
unknown.officialName = "UNKNOWN";
|
||||
|
||||
try (InputStream is = context.getAssets().open("issuers.json")) {
|
||||
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
Type listType = new TypeToken<List<Issuer>>() {
|
||||
}.getType();
|
||||
instances = new Gson().fromJson(reader, listType);
|
||||
}
|
||||
}
|
||||
instances.add(0, unknown);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public static void fillIssuers(List<Issuer> issuers)
|
||||
{
|
||||
instances.addAll(issuers);
|
||||
}
|
||||
|
||||
public byte[] getPublicDataKey() throws Exception {
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
package com.tangem.tangemcard.data;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.SettingsMask;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
|
|
@ -16,9 +12,6 @@ import java.util.Date;
|
|||
|
||||
public class TangemCard {
|
||||
|
||||
public static final String EXTRA_CARD = "Card";
|
||||
public static final String EXTRA_UID = "UID";
|
||||
|
||||
private byte[] CID;
|
||||
private Status status;
|
||||
private String UID;
|
||||
|
|
@ -37,50 +30,10 @@ public class TangemCard {
|
|||
return blockchainID;
|
||||
}
|
||||
|
||||
public Blockchain getBlockchain() {
|
||||
return Blockchain.fromId(blockchainID);
|
||||
}
|
||||
|
||||
public void setBlockchain(Blockchain blockchain) {
|
||||
blockchainID = blockchain.getID();
|
||||
}
|
||||
|
||||
public void setBlockchainID(String blockchainID) {
|
||||
this.blockchainID = blockchainID;
|
||||
}
|
||||
|
||||
public void addTokenToBlockchainName() {
|
||||
String token = getTokenSymbol();
|
||||
if (Strings.isNullOrEmpty(token))
|
||||
return;
|
||||
String oldName = getBlockchain().getOfficialName();
|
||||
//String newName = String.format("%s - %s ERC20 token", token, oldName);
|
||||
String newName = token + " <br><small><small> " + oldName + " ERC20 token</small></small>";
|
||||
blockchainName = newName;
|
||||
|
||||
}
|
||||
|
||||
private String blockchainName = "";
|
||||
|
||||
public String getBlockchainName() {
|
||||
if (Strings.isNullOrEmpty(blockchainName))
|
||||
return getBlockchain().getOfficialName();
|
||||
return blockchainName;
|
||||
}
|
||||
|
||||
public void setBlockchainIDFromCard(String blockchainID) {
|
||||
|
||||
if (Blockchain.fromId(blockchainID) != Blockchain.Ethereum && Blockchain.fromId(blockchainID) != Blockchain.EthereumTestNet)
|
||||
this.blockchainID = blockchainID;
|
||||
|
||||
if (isToken()) {
|
||||
this.blockchainID = Blockchain.Token.getID();
|
||||
addTokenToBlockchainName();
|
||||
} else {
|
||||
this.blockchainID = blockchainID;
|
||||
}
|
||||
}
|
||||
|
||||
public void setWalletPublicKey(byte[] publicKey) {
|
||||
pbWalletKey = publicKey;
|
||||
}
|
||||
|
|
@ -189,10 +142,10 @@ public class TangemCard {
|
|||
this.PIN = PIN;
|
||||
}
|
||||
|
||||
public void switchToInitialBlockchain() {
|
||||
if (tokenSymbol.length() > 1)
|
||||
blockchainID = Blockchain.Token.getID(); // Reset blockchain to Token from ETH for token cards with zero token balance on it
|
||||
}
|
||||
// public void switchToInitialBlockchain() {
|
||||
// if (tokenSymbol.length() > 1)
|
||||
// blockchainID = Blockchain.Token.getID(); // Reset blockchain to Token from ETH for token cards with zero token balance on it
|
||||
// }
|
||||
|
||||
public Date getPersonalizationDateTime() {
|
||||
return dtPersonalization;
|
||||
|
|
@ -202,12 +155,12 @@ public class TangemCard {
|
|||
this.dtPersonalization = dtPersonalization;
|
||||
}
|
||||
|
||||
public String getPersonalizationDateTimeDescription() {
|
||||
return Util.formatDate(dtPersonalization);
|
||||
}
|
||||
|
||||
private int health = 0;
|
||||
|
||||
public int getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public void setHealth(int health) {
|
||||
if (health > this.health) this.health = health;
|
||||
}
|
||||
|
|
@ -216,15 +169,19 @@ public class TangemCard {
|
|||
return health == 0;
|
||||
}
|
||||
|
||||
private Issuer issuer = Issuer.Unknown();
|
||||
private byte[] issuerPublicDataKey = null;
|
||||
private String issuerID = null;
|
||||
|
||||
// public void setIssuer(Issuer issuer) {
|
||||
// this.issuer = issuer;
|
||||
// }
|
||||
|
||||
public byte[] getIssuerPublicDataKey() {
|
||||
return issuerPublicDataKey;
|
||||
}
|
||||
|
||||
private Issuer issuer = Issuer.Unknown();
|
||||
|
||||
public void setIssuer(String issuerID, byte[] issuerPublicDataKey) {
|
||||
this.issuerPublicDataKey = issuerPublicDataKey;
|
||||
this.issuerID = issuerID;
|
||||
this.issuer = Issuer.FindIssuer(issuerID, issuerPublicDataKey);
|
||||
}
|
||||
|
||||
|
|
@ -232,14 +189,11 @@ public class TangemCard {
|
|||
return issuer;
|
||||
}
|
||||
|
||||
public byte[] getIssuerPublicDataKey() {
|
||||
return issuerPublicDataKey;
|
||||
}
|
||||
|
||||
public String getIssuerDescription() {
|
||||
return issuer.getOfficialName();
|
||||
}
|
||||
|
||||
|
||||
String contractAddress = "";
|
||||
|
||||
public void setContractAddress(String address) {
|
||||
|
|
@ -261,7 +215,7 @@ public class TangemCard {
|
|||
}
|
||||
|
||||
public boolean isToken() {
|
||||
return !Strings.isNullOrEmpty(tokenSymbol);
|
||||
return !(tokenSymbol == null || tokenSymbol.isEmpty());
|
||||
}
|
||||
|
||||
int tokensDecimal = 18;
|
||||
|
|
@ -317,6 +271,10 @@ public class TangemCard {
|
|||
|
||||
private Integer settingsMask = null;
|
||||
|
||||
public Integer getSettingsMask() {
|
||||
return settingsMask;
|
||||
}
|
||||
|
||||
public void setSettingsMask(int settingsMask) {
|
||||
this.settingsMask = settingsMask;
|
||||
}
|
||||
|
|
@ -341,15 +299,15 @@ public class TangemCard {
|
|||
return (settingsMask & SettingsMask.UseCVC) != 0;
|
||||
}
|
||||
|
||||
public Boolean useDefaultPIN1() {
|
||||
return PINStorage.isDefaultPIN(getPIN());
|
||||
}
|
||||
|
||||
public Boolean useSmartSecurityDelay() {
|
||||
if (settingsMask == null) return null;
|
||||
return (settingsMask & SettingsMask.SmartSecurityDelay) != 0;
|
||||
}
|
||||
|
||||
public Boolean useDefaultPIN1() {
|
||||
return CardProtocol.isDefaultPIN(getPIN());
|
||||
}
|
||||
|
||||
public enum PIN2_Mode {Unchecked, DefaultPIN2, CustomPIN2}
|
||||
|
||||
public PIN2_Mode PIN2 = PIN2_Mode.Unchecked;
|
||||
|
|
@ -609,163 +567,163 @@ public class TangemCard {
|
|||
DenominationText = null;
|
||||
}
|
||||
|
||||
public Bundle getAsBundle() {
|
||||
Bundle B = new Bundle();
|
||||
saveToBundle(B);
|
||||
return B;
|
||||
}
|
||||
|
||||
public void saveToBundle(Bundle B) {
|
||||
try {
|
||||
B.putString("UID", UID);
|
||||
B.putByteArray("CID", CID);
|
||||
B.putString("PIN", PIN);
|
||||
B.putString("PIN2", PIN2.name());
|
||||
B.putString("Status", status.name());
|
||||
B.putString("Blockchain", blockchainID);
|
||||
B.putString("BlockchainName", blockchainName);
|
||||
B.putInt("TokensDecimal", tokensDecimal);
|
||||
B.putString("TokenSymbol", tokenSymbol);
|
||||
B.putString("ContractAddress", contractAddress);
|
||||
if (dtPersonalization != null) B.putLong("dtPersonalization", dtPersonalization.getTime());
|
||||
B.putInt("RemainingSignatures", remainingSignatures);
|
||||
B.putInt("MaxSignatures", maxSignatures);
|
||||
B.putInt("Health", health);
|
||||
if (settingsMask != null) B.putInt("settingsMask", settingsMask);
|
||||
B.putInt("pauseBeforePIN2", pauseBeforePIN2);
|
||||
if (signingMethod != null) B.putString("signingMethod", signingMethod.name());
|
||||
if (manufacturer != null) B.putString("Manufacturer", manufacturer.name());
|
||||
if (encryptionMode != null) B.putString("EncryptionMode", encryptionMode.name());
|
||||
if (issuer != null) B.putString("Issuer", issuer.getID());
|
||||
if (issuerPublicDataKey != null) B.putByteArray("IssuerPublicDataKey", issuerPublicDataKey);
|
||||
if (firmwareVersion != null) B.putString("FirmwareVersion", firmwareVersion);
|
||||
if (batch != null) B.putString("Batch", batch);
|
||||
B.putBoolean("ManufacturerConfirmed", manufacturerConfirmed);
|
||||
B.putBoolean("CardPublicKeyValid", isCardPublicKeyValid());
|
||||
B.putByteArray("CardPublicKey", getCardPublicKey());
|
||||
|
||||
B.putInt("SignedHashes", getSignedHashes());
|
||||
B.putBoolean("WalletPublicKeyValid", isWalletPublicKeyValid());
|
||||
if (pbWalletKey != null)
|
||||
B.putByteArray("PublicKey", pbWalletKey);
|
||||
if (pbWalletKeyRar != null)
|
||||
B.putByteArray("PublicKeyRar", pbWalletKeyRar);
|
||||
|
||||
if (getOfflineBalance() != null) B.putByteArray("OfflineBalance", getOfflineBalance());
|
||||
|
||||
if (getDenomination() != null) B.putByteArray("Denomination", getDenomination());
|
||||
if (getDenominationText() != null) B.putString("DenominationText", getDenominationText());
|
||||
|
||||
if (getIssuerData() != null && getIssuerDataSignature() != null) {
|
||||
B.putByteArray("IssuerData", getIssuerData());
|
||||
B.putByteArray("IssuerDataSignature", getIssuerDataSignature());
|
||||
B.putBoolean("NeedWriteIssuerData", getNeedWriteIssuerData());
|
||||
}
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
if (onlineVerified != null)
|
||||
B.putBoolean("onlineVerified", onlineVerified);
|
||||
|
||||
if (onlineValidated != null)
|
||||
B.putBoolean("onlineValidated", onlineValidated);
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
if (onlineVerified != null)
|
||||
B.putBoolean("onlineVerified", onlineVerified);
|
||||
|
||||
if (onlineValidated != null)
|
||||
B.putBoolean("onlineValidated", onlineValidated);
|
||||
} catch (Exception e) {
|
||||
Log.e("Can't save to bundle ", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadFromBundle(Bundle B) {
|
||||
UID = B.getString("UID");
|
||||
CID = B.getByteArray("CID");
|
||||
PIN = B.getString("PIN");
|
||||
PIN2 = PIN2_Mode.valueOf(B.getString("PIN2"));
|
||||
status = Status.valueOf(B.getString("Status"));
|
||||
blockchainID = B.getString("Blockchain");
|
||||
tokensDecimal = B.getInt("TokensDecimal", 18);
|
||||
tokenSymbol = B.getString("TokenSymbol", "");
|
||||
contractAddress = B.getString("ContractAddress", "");
|
||||
if (B.containsKey("BlockchainName"))
|
||||
blockchainName = B.getString("BlockchainName", "");
|
||||
if (B.containsKey("dtPersonalization")) {
|
||||
dtPersonalization = new Date(B.getLong("dtPersonalization"));
|
||||
}
|
||||
remainingSignatures = B.getInt("RemainingSignatures");
|
||||
maxSignatures = B.getInt("MaxSignatures");
|
||||
health = B.getInt("health");
|
||||
if (B.containsKey("settingsMask")) settingsMask = B.getInt("settingsMask");
|
||||
pauseBeforePIN2 = B.getInt("pauseBeforePIN2");
|
||||
if (B.containsKey("signingMethod"))
|
||||
signingMethod = SigningMethod.valueOf(B.getString("signingMethod"));
|
||||
if (B.containsKey("Manufacturer"))
|
||||
manufacturer = Manufacturer.valueOf(B.getString("Manufacturer"));
|
||||
manufacturerConfirmed = B.getBoolean("ManufacturerConfirmed");
|
||||
if (B.containsKey("EncryptionMode"))
|
||||
encryptionMode = EncryptionMode.valueOf(B.getString("EncryptionMode"));
|
||||
else
|
||||
encryptionMode = null;
|
||||
|
||||
if (B.containsKey("SignedHashes")) setSignedHashes(B.getInt("SignedHashes"));
|
||||
|
||||
if (B.containsKey("Issuer")) issuer = Issuer.FindIssuer(B.getString("Issuer"));
|
||||
if (B.containsKey("IssuerPublicDataKey"))
|
||||
issuerPublicDataKey = B.getByteArray("IssuerPublicDataKey");
|
||||
|
||||
if (B.containsKey("FirmwareVersion")) firmwareVersion = B.getString("FirmwareVersion");
|
||||
if (B.containsKey("Batch")) batch = B.getString("Batch");
|
||||
|
||||
cardPublicKeyValid = B.getBoolean("CardPublicKeyValid");
|
||||
if (B.containsKey("CardPublicKey")) setCardPublicKey(B.getByteArray("CardPublicKey"));
|
||||
|
||||
if (B.containsKey("OfflineBalance")) setOfflineBalance(B.getByteArray("OfflineBalance"));
|
||||
else clearOfflineBalance();
|
||||
|
||||
if (B.containsKey("Denomination") && B.containsKey("DenominationText")) {
|
||||
setDenomination(B.getByteArray("Denomination"), B.getString("DenominationText"));
|
||||
} else if (B.containsKey("Denomination")) {
|
||||
setDenomination(B.getByteArray("Denomination"), "N/A");
|
||||
} else clearDenomination();
|
||||
|
||||
if (B.containsKey("IssuerData") && B.containsKey("IssuerDataSignature"))
|
||||
setIssuerData(B.getByteArray("IssuerData"), B.getByteArray("IssuerDataSignature"));
|
||||
else setIssuerData(null, null);
|
||||
|
||||
if (B.containsKey("NeedWriteIssuerData"))
|
||||
setNeedWriteIssuerData(B.getBoolean("NeedWriteIssuerData"));
|
||||
|
||||
walletPublicKeyValid = B.getBoolean("WalletPublicKeyValid");
|
||||
if (B.containsKey("PublicKey")) {
|
||||
pbWalletKey = B.getByteArray("PublicKey");
|
||||
}
|
||||
if (B.containsKey("PublicKeyRar")) {
|
||||
pbWalletKeyRar = B.getByteArray("PublicKeyRar");
|
||||
}
|
||||
|
||||
if (B.containsKey("codeConfirmed"))
|
||||
codeConfirmed = B.getBoolean("codeConfirmed");
|
||||
|
||||
if (B.containsKey("onlineVerified"))
|
||||
onlineVerified = B.getBoolean("onlineVerified");
|
||||
|
||||
if (B.containsKey("onlineValidated"))
|
||||
onlineValidated = B.getBoolean("onlineValidated");
|
||||
}
|
||||
// public Bundle getAsBundle() {
|
||||
// Bundle B = new Bundle();
|
||||
// saveToBundle(B);
|
||||
// return B;
|
||||
// }
|
||||
//
|
||||
// public void saveToBundle(Bundle B) {
|
||||
// try {
|
||||
// B.putString("UID", UID);
|
||||
// B.putByteArray("CID", CID);
|
||||
// B.putString("PIN", PIN);
|
||||
// B.putString("PIN2", PIN2.name());
|
||||
// B.putString("Status", status.name());
|
||||
// B.putString("Blockchain", blockchainID);
|
||||
// B.putString("BlockchainName", blockchainName);
|
||||
// B.putInt("TokensDecimal", tokensDecimal);
|
||||
// B.putString("TokenSymbol", tokenSymbol);
|
||||
// B.putString("ContractAddress", contractAddress);
|
||||
// if (dtPersonalization != null) B.putLong("dtPersonalization", dtPersonalization.getTime());
|
||||
// B.putInt("RemainingSignatures", remainingSignatures);
|
||||
// B.putInt("MaxSignatures", maxSignatures);
|
||||
// B.putInt("Health", health);
|
||||
// if (settingsMask != null) B.putInt("settingsMask", settingsMask);
|
||||
// B.putInt("pauseBeforePIN2", pauseBeforePIN2);
|
||||
// if (signingMethod != null) B.putString("signingMethod", signingMethod.name());
|
||||
// if (manufacturer != null) B.putString("Manufacturer", manufacturer.name());
|
||||
// if (encryptionMode != null) B.putString("EncryptionMode", encryptionMode.name());
|
||||
// if (issuer != null) B.putString("Issuer", issuer.getID());
|
||||
// if (issuerPublicDataKey != null) B.putByteArray("IssuerPublicDataKey", issuerPublicDataKey);
|
||||
// if (firmwareVersion != null) B.putString("FirmwareVersion", firmwareVersion);
|
||||
// if (batch != null) B.putString("Batch", batch);
|
||||
// B.putBoolean("ManufacturerConfirmed", manufacturerConfirmed);
|
||||
// B.putBoolean("CardPublicKeyValid", isCardPublicKeyValid());
|
||||
// B.putByteArray("CardPublicKey", getCardPublicKey());
|
||||
//
|
||||
// B.putInt("SignedHashes", getSignedHashes());
|
||||
// B.putBoolean("WalletPublicKeyValid", isWalletPublicKeyValid());
|
||||
// if (pbWalletKey != null)
|
||||
// B.putByteArray("PublicKey", pbWalletKey);
|
||||
// if (pbWalletKeyRar != null)
|
||||
// B.putByteArray("PublicKeyRar", pbWalletKeyRar);
|
||||
//
|
||||
// if (getOfflineBalance() != null) B.putByteArray("OfflineBalance", getOfflineBalance());
|
||||
//
|
||||
// if (getDenomination() != null) B.putByteArray("Denomination", getDenomination());
|
||||
// if (getDenominationText() != null) B.putString("DenominationText", getDenominationText());
|
||||
//
|
||||
// if (getIssuerData() != null && getIssuerDataSignature() != null) {
|
||||
// B.putByteArray("IssuerData", getIssuerData());
|
||||
// B.putByteArray("IssuerDataSignature", getIssuerDataSignature());
|
||||
// B.putBoolean("NeedWriteIssuerData", getNeedWriteIssuerData());
|
||||
// }
|
||||
//
|
||||
// if (codeConfirmed != null)
|
||||
// B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
//
|
||||
// if (codeConfirmed != null)
|
||||
// B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
//
|
||||
// if (onlineVerified != null)
|
||||
// B.putBoolean("onlineVerified", onlineVerified);
|
||||
//
|
||||
// if (onlineValidated != null)
|
||||
// B.putBoolean("onlineValidated", onlineValidated);
|
||||
//
|
||||
// if (codeConfirmed != null)
|
||||
// B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
//
|
||||
// if (codeConfirmed != null)
|
||||
// B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
//
|
||||
// if (onlineVerified != null)
|
||||
// B.putBoolean("onlineVerified", onlineVerified);
|
||||
//
|
||||
// if (onlineValidated != null)
|
||||
// B.putBoolean("onlineValidated", onlineValidated);
|
||||
// } catch (Exception e) {
|
||||
// Log.e("Can't save to bundle ", e.getMessage());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void loadFromBundle(Bundle B) {
|
||||
// UID = B.getString("UID");
|
||||
// CID = B.getByteArray("CID");
|
||||
// PIN = B.getString("PIN");
|
||||
// PIN2 = PIN2_Mode.valueOf(B.getString("PIN2"));
|
||||
// status = Status.valueOf(B.getString("Status"));
|
||||
// blockchainID = B.getString("Blockchain");
|
||||
// tokensDecimal = B.getInt("TokensDecimal", 18);
|
||||
// tokenSymbol = B.getString("TokenSymbol", "");
|
||||
// contractAddress = B.getString("ContractAddress", "");
|
||||
// if (B.containsKey("BlockchainName"))
|
||||
// blockchainName = B.getString("BlockchainName", "");
|
||||
// if (B.containsKey("dtPersonalization")) {
|
||||
// dtPersonalization = new Date(B.getLong("dtPersonalization"));
|
||||
// }
|
||||
// remainingSignatures = B.getInt("RemainingSignatures");
|
||||
// maxSignatures = B.getInt("MaxSignatures");
|
||||
// health = B.getInt("health");
|
||||
// if (B.containsKey("settingsMask")) settingsMask = B.getInt("settingsMask");
|
||||
// pauseBeforePIN2 = B.getInt("pauseBeforePIN2");
|
||||
// if (B.containsKey("signingMethod"))
|
||||
// signingMethod = SigningMethod.valueOf(B.getString("signingMethod"));
|
||||
// if (B.containsKey("Manufacturer"))
|
||||
// manufacturer = Manufacturer.valueOf(B.getString("Manufacturer"));
|
||||
// manufacturerConfirmed = B.getBoolean("ManufacturerConfirmed");
|
||||
// if (B.containsKey("EncryptionMode"))
|
||||
// encryptionMode = EncryptionMode.valueOf(B.getString("EncryptionMode"));
|
||||
// else
|
||||
// encryptionMode = null;
|
||||
//
|
||||
// if (B.containsKey("SignedHashes")) setSignedHashes(B.getInt("SignedHashes"));
|
||||
//
|
||||
// if (B.containsKey("Issuer")) issuer = Issuer.FindIssuer(B.getString("Issuer"));
|
||||
// if (B.containsKey("IssuerPublicDataKey"))
|
||||
// issuerPublicDataKey = B.getByteArray("IssuerPublicDataKey");
|
||||
//
|
||||
// if (B.containsKey("FirmwareVersion")) firmwareVersion = B.getString("FirmwareVersion");
|
||||
// if (B.containsKey("Batch")) batch = B.getString("Batch");
|
||||
//
|
||||
// cardPublicKeyValid = B.getBoolean("CardPublicKeyValid");
|
||||
// if (B.containsKey("CardPublicKey")) setCardPublicKey(B.getByteArray("CardPublicKey"));
|
||||
//
|
||||
// if (B.containsKey("OfflineBalance")) setOfflineBalance(B.getByteArray("OfflineBalance"));
|
||||
// else clearOfflineBalance();
|
||||
//
|
||||
// if (B.containsKey("Denomination") && B.containsKey("DenominationText")) {
|
||||
// setDenomination(B.getByteArray("Denomination"), B.getString("DenominationText"));
|
||||
// } else if (B.containsKey("Denomination")) {
|
||||
// setDenomination(B.getByteArray("Denomination"), "N/A");
|
||||
// } else clearDenomination();
|
||||
//
|
||||
// if (B.containsKey("IssuerData") && B.containsKey("IssuerDataSignature"))
|
||||
// setIssuerData(B.getByteArray("IssuerData"), B.getByteArray("IssuerDataSignature"));
|
||||
// else setIssuerData(null, null);
|
||||
//
|
||||
// if (B.containsKey("NeedWriteIssuerData"))
|
||||
// setNeedWriteIssuerData(B.getBoolean("NeedWriteIssuerData"));
|
||||
//
|
||||
// walletPublicKeyValid = B.getBoolean("WalletPublicKeyValid");
|
||||
// if (B.containsKey("PublicKey")) {
|
||||
// pbWalletKey = B.getByteArray("PublicKey");
|
||||
// }
|
||||
// if (B.containsKey("PublicKeyRar")) {
|
||||
// pbWalletKeyRar = B.getByteArray("PublicKeyRar");
|
||||
// }
|
||||
//
|
||||
// if (B.containsKey("codeConfirmed"))
|
||||
// codeConfirmed = B.getBoolean("codeConfirmed");
|
||||
//
|
||||
// if (B.containsKey("onlineVerified"))
|
||||
// onlineVerified = B.getBoolean("onlineVerified");
|
||||
//
|
||||
// if (B.containsKey("onlineValidated"))
|
||||
// onlineValidated = B.getBoolean("onlineValidated");
|
||||
// }
|
||||
|
||||
public enum EncryptionMode {
|
||||
None((byte) 0x0), Fast((byte) 0x1), Strong((byte) 0x2);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.tangemcard.data.external;
|
||||
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
|
||||
public interface CardDataSubstitutionProvider {
|
||||
void applySubstitution(TangemCard card);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.tangemcard.data.external;
|
||||
|
||||
public interface FirmwaresDigestsProvider {
|
||||
VerifyCodeRecord selectRandomVerifyCodeBlock(String firmwareVersion);
|
||||
|
||||
class VerifyCodeRecord {
|
||||
public String hashAlg;
|
||||
public int blockIndex;
|
||||
public int blockCount;
|
||||
public byte[] challenge;
|
||||
public byte[] digest;
|
||||
}
|
||||
|
||||
}
|
||||
11
tangemcard-common/src/main/java/com/tangem/tangemcard/data/external/PINsProvider.java
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.tangemcard.data.external;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PINsProvider {
|
||||
String getPIN2();
|
||||
|
||||
void setLastUsedPIN(String pin);
|
||||
|
||||
List<String> getPINs();
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.tangemcard.reader;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.util.Log;
|
||||
import com.tangem.tangemcard.util.PBKDF2;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
|
|
@ -1,14 +1,8 @@
|
|||
package com.tangem.tangemcard.reader;
|
||||
|
||||
import android.content.Context;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.TagLostException;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.tangemcard.data.local.Firmwares;
|
||||
import com.tangem.tangemcard.data.Manufacturer;
|
||||
import com.tangem.tangemcard.util.Log;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import org.spongycastle.jce.ECNamedCurveTable;
|
||||
|
|
@ -103,14 +97,8 @@ public class CardProtocol {
|
|||
|
||||
private static final int SW_PIN_ERROR = SW.INVALID_PARAMS;
|
||||
|
||||
private IsoDep mIsoDep;
|
||||
private NfcReader mIsoDep;
|
||||
|
||||
/**
|
||||
* @return Android NFC tag object
|
||||
*/
|
||||
public Tag getTag() {
|
||||
return mIsoDep.getTag();
|
||||
}
|
||||
|
||||
public static final String DefaultPIN = "000000";
|
||||
public static final String DefaultPIN2 = "000";
|
||||
|
|
@ -124,9 +112,17 @@ public class CardProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isDefaultPIN(String pin) {
|
||||
return (DefaultPIN.equals(pin));
|
||||
}
|
||||
|
||||
public static boolean isDefaultPIN2(String pin2) {
|
||||
return (DefaultPIN2.equals(pin2));
|
||||
}
|
||||
|
||||
|
||||
private TangemCard mCard;
|
||||
private Exception mError;
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* Set occurred error
|
||||
|
|
@ -148,15 +144,12 @@ public class CardProtocol {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context - Android context
|
||||
* @param isoDep - Android NFC tag
|
||||
* @param reader - NFC Reader interface
|
||||
* @param card - TangemCard object, stored data from previous reading or null for reading a card for the first time
|
||||
* @param notifications - UI notification callbacks
|
||||
*/
|
||||
public CardProtocol(Context context, IsoDep isoDep, TangemCard card, Notifications notifications) {
|
||||
mContext = context;
|
||||
mIsoDep = isoDep;
|
||||
public CardProtocol(NfcReader reader, TangemCard card, Notifications notifications) {
|
||||
mIsoDep = reader;
|
||||
mNotifications = notifications;
|
||||
if (card != null)
|
||||
{
|
||||
|
|
@ -164,7 +157,7 @@ public class CardProtocol {
|
|||
mCard = card;
|
||||
}else{
|
||||
mPIN = null;
|
||||
mCard = new TangemCard(Util.byteArrayToHexString(mIsoDep.getTag().getId()));
|
||||
mCard = new TangemCard(Util.byteArrayToHexString(mIsoDep.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,6 +170,19 @@ public class CardProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base exception class for exceptions on card reading
|
||||
*/
|
||||
public static class TangemException_TagLost extends Exception {
|
||||
public TangemException_TagLost() {
|
||||
super("Tag lost");
|
||||
}
|
||||
public TangemException_TagLost(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thrown on failed attempt of reading with possible wrong PIN
|
||||
*/
|
||||
|
|
@ -225,15 +231,15 @@ public class CardProtocol {
|
|||
* @return UID byte array
|
||||
*/
|
||||
public byte[] GetUID() {
|
||||
if (mIsoDep == null || mIsoDep.getTag() == null) return null;
|
||||
return mIsoDep.getTag().getId();
|
||||
if (mIsoDep == null ) return null;
|
||||
return mIsoDep.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ISO 14443-3 tag reading timeout
|
||||
*/
|
||||
public int getTimeout() {
|
||||
if (mIsoDep == null || mIsoDep.getTag() == null) return 60000;
|
||||
if (mIsoDep == null ) return 60000;
|
||||
return mIsoDep.getTimeout();
|
||||
}
|
||||
|
||||
|
|
@ -299,7 +305,7 @@ public class CardProtocol {
|
|||
|
||||
try {
|
||||
if (mIsoDep == null) {
|
||||
throw new TagLostException();
|
||||
throw new TangemException_TagLost();
|
||||
}
|
||||
byte[] cmdBytes = cmdApdu.toBytes();
|
||||
String cmdStr = CommandApdu.toString(cmdBytes, cmdApdu.getLc());
|
||||
|
|
@ -353,7 +359,7 @@ public class CardProtocol {
|
|||
|
||||
try {
|
||||
if (mIsoDep == null) {
|
||||
throw new TagLostException();
|
||||
throw new TangemException_TagLost();
|
||||
}
|
||||
//mIsoDep.setTimeout(msTimeout);
|
||||
|
||||
|
|
@ -933,12 +939,12 @@ public class CardProtocol {
|
|||
* by Tangem. It may contains ~150.000 precalculated hashes of COS binary code segments.
|
||||
* VERIFY_CODE command internally reads a segment of COS binary code beginning at Code_Page_Address and having length of [64 x Code_Page_Count] bytes.
|
||||
* Then it appends Challenge to the code segment, calculates resulting hash and returns it in the response.
|
||||
* The application needs to ensure that returned hash coincides with the one stored in the hash library (see {@link Firmwares}).
|
||||
* The application needs to ensure that returned hash coincides with the one stored in the hash library (see {@see Firmwares}).
|
||||
* @param hashAlgID - ‘sha-256’, ‘sha-1’, ‘sha-224’, ‘sha-384’, ‘sha-512’, ‘crc-16’
|
||||
* @param codePageAddress - Value from 0 to ~3000, take from {@link Firmwares}
|
||||
* @param codePageCount - Number of 32-byte pages to read: from 1 to 5, take from {@link Firmwares}
|
||||
* @param challenge - Additional challenge value from 1 to 10, take from {@link Firmwares}
|
||||
* @return digest bytes to compare with one stored in {@link Firmwares}
|
||||
* @param codePageAddress - Value from 0 to ~3000, take from {@see Firmwares}
|
||||
* @param codePageCount - Number of 32-byte pages to read: from 1 to 5, take from {@see Firmwares}
|
||||
* @param challenge - Additional challenge value from 1 to 10, take from {@see Firmwares}
|
||||
* @return digest bytes to compare with one stored in {@see Firmwares}
|
||||
* @throws Exception - if something went wrong
|
||||
*/
|
||||
public byte[] run_VerifyCode(String hashAlgID, int codePageAddress, int codePageCount, byte[] challenge) throws Exception {
|
||||
|
|
@ -1059,7 +1065,7 @@ public class CardProtocol {
|
|||
bsDataToVerify.write(issuerDataCounter.Value);
|
||||
}
|
||||
try {
|
||||
if (CardCrypto.VerifySignature(mCard.getIssuer().getPublicDataKey(), bsDataToVerify.toByteArray(), issuerDataSignature.Value)) {
|
||||
if (CardCrypto.VerifySignature(mCard.getIssuerPublicDataKey(), bsDataToVerify.toByteArray(), issuerDataSignature.Value)) {
|
||||
mCard.setIssuerData(issuerData.Value, issuerDataSignature.Value);
|
||||
return TLVList.fromBytes(issuerData.Value);
|
||||
} else {
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.tangemcard.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface NfcReader {
|
||||
byte[] getId();
|
||||
|
||||
void setTimeout(int timeout)throws IOException;
|
||||
|
||||
int getTimeout();
|
||||
|
||||
byte[] transceive(byte[] data) throws IOException;
|
||||
|
||||
void ignoreTag() throws IOException;
|
||||
|
||||
void notifyReadResult(boolean success);
|
||||
|
||||
void connect();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.tangem.tangemcard.reader;
|
||||
|
||||
/**
|
||||
* Created by dvol on 07.03.2018.
|
||||
*/
|
||||
|
||||
public class SettingsMask {
|
||||
public static final int IsReusable = 0x0001;
|
||||
public static final int UseActivation = 0x0002;
|
||||
public static final int ForbidPurgeWallet = 0x0004;
|
||||
public static final int UseBlock = 0x0008;
|
||||
|
||||
public static final int AllowSwapPIN = 0x0010;
|
||||
public static final int AllowSwapPIN2 = 0x0020;
|
||||
public static final int UseCVC = 0x0040;
|
||||
public static final int ForbidDefaultPIN = 0x0080;
|
||||
|
||||
public static final int UseOneCommandAtTime = 0x0100;
|
||||
public static final int UseNDEF = 0x0200;
|
||||
public static final int UseDynamicNDEF = 0x0400;
|
||||
public static final int SmartSecurityDelay = 0x0800;
|
||||
|
||||
public static final int Protocol_AllowUnencrypted = 0x1000;
|
||||
public static final int Protocol_AllowStaticEncryption = 0x2000;
|
||||
|
||||
public static final int ProtectIssuerDataAgainstReplay = 0x4000;
|
||||
|
||||
public static final int AllowSelectBlockchain = 0x8000;
|
||||
|
||||
public static final int DisablePrecomputedNDEF = 0x00010000;
|
||||
|
||||
public static String getDescription(int iValue) {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append("[");
|
||||
if ((iValue & SettingsMask.AllowSwapPIN) != 0) sb.append("AllowSwapPIN, ");
|
||||
if ((iValue & SettingsMask.AllowSwapPIN2) != 0)
|
||||
sb.append("AllowSwapPIN2, ");
|
||||
if ((iValue & SettingsMask.ForbidDefaultPIN) != 0)
|
||||
sb.append("ForbidDefaultPIN, ");
|
||||
if ((iValue & SettingsMask.IsReusable) != 0) sb.append("IsReusable, ");
|
||||
if ((iValue & SettingsMask.Protocol_AllowStaticEncryption) != 0)
|
||||
sb.append("Protocol_AllowStaticEncryption, ");
|
||||
if ((iValue & SettingsMask.Protocol_AllowUnencrypted) != 0)
|
||||
sb.append("Protocol_AllowUnencrypted, ");
|
||||
if ((iValue & SettingsMask.SmartSecurityDelay) != 0)
|
||||
sb.append("SmartSecurityDelay, ");
|
||||
if ((iValue & SettingsMask.UseActivation) != 0)
|
||||
sb.append("UseActivation, ");
|
||||
if ((iValue & SettingsMask.UseBlock) != 0) sb.append("UseBlock, ");
|
||||
if ((iValue & SettingsMask.UseCVC) != 0) sb.append("UseCVC, ");
|
||||
if ((iValue & SettingsMask.UseDynamicNDEF) != 0)
|
||||
sb.append("UseDynamicNDEF, ");
|
||||
if ((iValue & SettingsMask.UseNDEF) != 0) sb.append("UseNDEF, ");
|
||||
if ((iValue & SettingsMask.UseOneCommandAtTime) != 0)
|
||||
sb.append("UseOneCommandAtTime, ");
|
||||
if ((iValue & SettingsMask.ProtectIssuerDataAgainstReplay) != 0)
|
||||
sb.append("ProtectIssuerDataAgainstReplay, ");
|
||||
if ((iValue & SettingsMask.ForbidPurgeWallet) != 0) sb.append("ForbidPurgeWallet, ");
|
||||
if ((iValue & SettingsMask.AllowSelectBlockchain) != 0) sb.append("AllowSelectBlockchain, ");
|
||||
if ((iValue & SettingsMask.DisablePrecomputedNDEF) != 0) sb.append("DisablePrecomputedNDEF, ");
|
||||
|
||||
if (sb.length() > 1) sb.delete(sb.length() - 2, sb.length());
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -215,34 +215,7 @@ public class TLV {
|
|||
if( Value!=null ) {
|
||||
try {
|
||||
int iValue = Util.byteArrayToInt(Value);
|
||||
sb.append("[");
|
||||
if ((iValue & SettingsMask.AllowSwapPIN) != 0) sb.append("AllowSwapPIN, ");
|
||||
if ((iValue & SettingsMask.AllowSwapPIN2) != 0)
|
||||
sb.append("AllowSwapPIN2, ");
|
||||
if ((iValue & SettingsMask.ForbidDefaultPIN) != 0)
|
||||
sb.append("ForbidDefaultPIN, ");
|
||||
if ((iValue & SettingsMask.IsReusable) != 0) sb.append("IsReusable, ");
|
||||
if ((iValue & SettingsMask.Protocol_AllowStaticEncryption) != 0)
|
||||
sb.append("Protocol_AllowStaticEncryption, ");
|
||||
if ((iValue & SettingsMask.Protocol_AllowUnencrypted) != 0)
|
||||
sb.append("Protocol_AllowUnencrypted, ");
|
||||
if ((iValue & SettingsMask.SmartSecurityDelay) != 0)
|
||||
sb.append("SmartSecurityDelay, ");
|
||||
if ((iValue & SettingsMask.UseActivation) != 0)
|
||||
sb.append("UseActivation, ");
|
||||
if ((iValue & SettingsMask.UseBlock) != 0) sb.append("UseBlock, ");
|
||||
if ((iValue & SettingsMask.UseCVC) != 0) sb.append("UseCVC, ");
|
||||
if ((iValue & SettingsMask.UseDynamicNDEF) != 0)
|
||||
sb.append("UseDynamicNDEF, ");
|
||||
if ((iValue & SettingsMask.UseNDEF) != 0) sb.append("UseNDEF, ");
|
||||
if ((iValue & SettingsMask.UseOneCommandAtTime) != 0)
|
||||
sb.append("UseOneCommandAtTime, ");
|
||||
if ((iValue & SettingsMask.ProtectIssuerDataAgainstReplay) != 0)
|
||||
sb.append("ProtectIssuerDataAgainstReplay, ");
|
||||
|
||||
if (sb.length() > 1) sb.delete(sb.length() - 2, sb.length());
|
||||
sb.append("]");
|
||||
return String.format("%s[%d]: %s (%s)", tag.name(), Value.length, Util.bytesToHex(Value), sb.toString());
|
||||
return String.format("%s[%d]: %s (%s)", tag.name(), Value.length, Util.bytesToHex(Value), SettingsMask.getDescription(iValue));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -4,8 +4,6 @@ package com.tangem.tangemcard.reader;
|
|||
* Created by dvol on 23.06.2017.
|
||||
*/
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
|
@ -27,7 +25,7 @@ public class TLVList extends ArrayList<TLV> {
|
|||
super();
|
||||
}
|
||||
|
||||
public TLVList(@NonNull Collection<? extends TLV> c) {
|
||||
public TLVList(Collection<? extends TLV> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
|
|
@ -1,19 +1,18 @@
|
|||
package com.tangem.tangemcard.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.data.external.CardDataSubstitutionProvider;
|
||||
import com.tangem.tangemcard.data.external.PINsProvider;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.NfcManager;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.tangemcard.reader.NfcReader;
|
||||
import com.tangem.tangemcard.util.Log;
|
||||
|
||||
public class CreateNewWalletTask extends CustomReadCardTask {
|
||||
public static final String TAG = CreateNewWalletTask.class.getSimpleName();
|
||||
|
||||
public CreateNewWalletTask(Context context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
|
||||
super(context, card, nfcManager, isoDep, notifications);
|
||||
public CreateNewWalletTask(TangemCard card, NfcReader reader, CardDataSubstitutionProvider cardDataSubstitutionProvider, PINsProvider pinsProvider, CardProtocol.Notifications notifications) {
|
||||
super(card, reader, cardDataSubstitutionProvider, pinsProvider, notifications);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -25,7 +24,7 @@ public class CreateNewWalletTask extends CustomReadCardTask {
|
|||
|
||||
mNotifications.onReadProgress(protocol, 30);
|
||||
if (isCancelled) return;
|
||||
protocol.run_CreateWallet(PINStorage.getPIN2());
|
||||
protocol.run_CreateWallet(pinsProvider.getPIN2());
|
||||
mNotifications.onReadProgress(protocol, 60);
|
||||
if (isCancelled) return;
|
||||
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package com.tangem.tangemcard.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.tangemcard.data.Issuer;
|
||||
import com.tangem.tangemcard.data.local.LocalStorage;
|
||||
import com.tangem.tangemcard.data.external.CardDataSubstitutionProvider;
|
||||
import com.tangem.tangemcard.data.Manufacturer;
|
||||
import com.tangem.tangemcard.data.local.PINStorage;
|
||||
import com.tangem.tangemcard.data.external.PINsProvider;
|
||||
import com.tangem.tangemcard.data.TangemCard;
|
||||
import com.tangem.tangemcard.reader.CardProtocol;
|
||||
import com.tangem.tangemcard.reader.NfcManager;
|
||||
import com.tangem.tangemcard.reader.NfcReader;
|
||||
import com.tangem.tangemcard.reader.TLV;
|
||||
import com.tangem.tangemcard.reader.TLVException;
|
||||
import com.tangem.tangemcard.reader.TLVList;
|
||||
import com.tangem.tangemcard.util.Log;
|
||||
import com.tangem.tangemcard.util.Util;
|
||||
|
||||
import org.spongycastle.jce.ECNamedCurveTable;
|
||||
|
|
@ -30,12 +26,12 @@ import java.util.Calendar;
|
|||
public class CustomReadCardTask extends Thread {
|
||||
public static final String TAG = CustomReadCardTask.class.getSimpleName();
|
||||
|
||||
protected IsoDep mIsoDep;
|
||||
protected NfcReader mIsoDep;
|
||||
protected CardProtocol.Notifications mNotifications;
|
||||
protected boolean isCancelled = false;
|
||||
protected Context mContext;
|
||||
protected NfcManager mNfcManager;
|
||||
protected TangemCard mCard ;
|
||||
CardDataSubstitutionProvider localStorage;
|
||||
PINsProvider pinsProvider;
|
||||
CardProtocol protocol;
|
||||
|
||||
// this fields are static to optimize process when need enter pin and scan card again
|
||||
|
|
@ -49,11 +45,11 @@ public class CustomReadCardTask extends Thread {
|
|||
lastRead_UnsuccessfullPINs.clear();
|
||||
}
|
||||
|
||||
public CustomReadCardTask(Context context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
|
||||
mContext = context;
|
||||
mIsoDep = isoDep;
|
||||
public CustomReadCardTask(TangemCard card, NfcReader reader, CardDataSubstitutionProvider cardDataSubstitutionProvider, PINsProvider pinsProvider, CardProtocol.Notifications notifications) {
|
||||
mIsoDep = reader;
|
||||
mNotifications = notifications;
|
||||
mNfcManager = nfcManager;
|
||||
localStorage= cardDataSubstitutionProvider;
|
||||
this.pinsProvider=pinsProvider;
|
||||
mCard=card;
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +170,7 @@ public class CustomReadCardTask extends Thread {
|
|||
try {
|
||||
if (mCard.getFirmwareVersion().compareTo("1.05") < 0) {
|
||||
// In FW ver 1.05, the issuer has one key pair used as both DataKey and TransactionKey, see [1] 3.3.1 and [1] 3.3.2
|
||||
//mCard.setIssuer(tlvCardData.getTLV(TLV.Tag.TAG_Issuer_ID).getAsString(), protocol.getReadResult().getTLV(TLV.Tag.TAG_Issuer_Transaction_PublicKey).Value);
|
||||
mCard.setIssuer(tlvCardData.getTLV(TLV.Tag.TAG_Issuer_ID).getAsString(), protocol.getReadResult().getTLV(TLV.Tag.TAG_Issuer_Transaction_PublicKey).Value);
|
||||
} else {
|
||||
// In newer FW versions, the issuer has two different key pairs - DataKey and TransactionKey, see [1] 3.3.1 and [1] 3.3.2
|
||||
|
|
@ -188,7 +185,7 @@ public class CustomReadCardTask extends Thread {
|
|||
} catch (Exception ee) {
|
||||
ee.printStackTrace();
|
||||
Log.e(TAG, "Cannot get issuer");
|
||||
mCard.setIssuer(Issuer.Unknown().getID(), null);
|
||||
mCard.setIssuer("Unknown", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,15 +198,15 @@ public class CustomReadCardTask extends Thread {
|
|||
} else if (mCard.getBatch().equals("0019")) {
|
||||
mCard.setContractAddress("0x0c056b0cda0763cc14b8b2d6c02465c91e33ec72");
|
||||
} else {
|
||||
LocalStorage localStorage = new LocalStorage(mContext);
|
||||
localStorage.applySubstitution(mCard);
|
||||
//CardDataSubstitutionProvider localStorage = new CardDataSubstitutionProvider(mContext);
|
||||
if( localStorage!=null ) localStorage.applySubstitution(mCard);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Can't apply card data substitution");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mCard.setBlockchainIDFromCard(tlvCardData.getTLV(TLV.Tag.TAG_Blockchain_ID).getAsString());
|
||||
mCard.setBlockchainID(tlvCardData.getTLV(TLV.Tag.TAG_Blockchain_ID).getAsString());
|
||||
|
||||
try {
|
||||
mCard.setSettingsMask(protocol.getReadResult().getTagAsInt(TLV.Tag.TAG_SettingsMask));
|
||||
|
|
@ -279,7 +276,7 @@ public class CustomReadCardTask extends Thread {
|
|||
public void run_FirstTimeRead() throws Exception {
|
||||
|
||||
|
||||
byte[] UID = mIsoDep.getTag().getId();
|
||||
byte[] UID = mIsoDep.getId();
|
||||
String sUID = Util.byteArrayToHexString(UID);
|
||||
if (!lastRead_UID.equals(sUID)) {
|
||||
resetLastReadInfo();
|
||||
|
|
@ -289,7 +286,7 @@ public class CustomReadCardTask extends Thread {
|
|||
|
||||
if (isCancelled) return;
|
||||
|
||||
protocol.setPIN(PINStorage.getDefaultPIN());
|
||||
protocol.setPIN(CardProtocol.DefaultPIN);
|
||||
protocol.clearReadResult();
|
||||
|
||||
if (lastRead_Encryption == null) {
|
||||
|
|
@ -303,7 +300,7 @@ public class CustomReadCardTask extends Thread {
|
|||
if (protocol.haveReadResult()) {
|
||||
//already have read result (obtained while get supported encryption), only read issuer data and define offline balance
|
||||
parseReadResult();
|
||||
PINStorage.setLastUsedPIN(protocol.getCard().getPIN());
|
||||
pinsProvider.setLastUsedPIN(protocol.getCard().getPIN());
|
||||
} else {
|
||||
//don't have read result - may be don't get supported encryption on this try, need encryption or need another PIN
|
||||
if (lastRead_Encryption == null) {
|
||||
|
|
@ -311,12 +308,12 @@ public class CustomReadCardTask extends Thread {
|
|||
lastRead_Encryption = protocol.getCard().encryptionMode;
|
||||
if (protocol.getCard().encryptionMode == TangemCard.EncryptionMode.None) {
|
||||
// default pin not accepted
|
||||
lastRead_UnsuccessfullPINs.add(PINStorage.getDefaultPIN());
|
||||
lastRead_UnsuccessfullPINs.add(CardProtocol.DefaultPIN);
|
||||
}
|
||||
}
|
||||
|
||||
boolean pinFound = false;
|
||||
for (String PIN : PINStorage.getPINs()) {
|
||||
for (String PIN : pinsProvider.getPINs()) {
|
||||
Log.e(TAG, "PIN: " + PIN);
|
||||
|
||||
boolean skipPin = false;
|
||||
|
|
@ -341,7 +338,7 @@ public class CustomReadCardTask extends Thread {
|
|||
// After first successful read, data will be parsed into TangemCard object
|
||||
parseReadResult();
|
||||
|
||||
PINStorage.setLastUsedPIN(PIN);
|
||||
pinsProvider.setLastUsedPIN(PIN);
|
||||
pinFound = true;
|
||||
protocol.getCard().setPIN(PIN);
|
||||
break;
|
||||
|
|
@ -365,7 +362,7 @@ public class CustomReadCardTask extends Thread {
|
|||
String PIN = mCard.getPIN();
|
||||
protocol.setPIN(PIN);
|
||||
protocol.run_Read();
|
||||
PINStorage.setLastUsedPIN(PIN);
|
||||
pinsProvider.setLastUsedPIN(PIN);
|
||||
if (!Arrays.equals(mCard.getCID(),protocol.getReadResult().getTLV(TLV.Tag.TAG_CardID).Value)) {
|
||||
throw new CardProtocol.TangemException("Card must be the same. Reading attempt on different card!");
|
||||
}
|
||||
|
|
@ -388,13 +385,10 @@ public class CustomReadCardTask extends Thread {
|
|||
// for Samsung's bugs -
|
||||
// Workaround for the Samsung Galaxy S5 (since the
|
||||
// first connection always hangs on transceive).
|
||||
int timeout = mIsoDep.getTimeout();
|
||||
|
||||
mIsoDep.connect();
|
||||
mIsoDep.close();
|
||||
mIsoDep.connect();
|
||||
mIsoDep.setTimeout(timeout);
|
||||
try {
|
||||
protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
|
||||
protocol = new CardProtocol(mIsoDep, mCard, mNotifications);
|
||||
mNotifications.onReadStart(protocol);
|
||||
try {
|
||||
Log.i(TAG, String.format("[-- Start task -- %s --]", getClass().getSimpleName()));
|
||||
|
|
@ -416,11 +410,11 @@ public class CustomReadCardTask extends Thread {
|
|||
mNotifications.onReadFinish(protocol);
|
||||
}
|
||||
} finally {
|
||||
mNfcManager.ignoreTag(mIsoDep.getTag());
|
||||
mIsoDep.ignoreTag();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
mNfcManager.notifyReadResult(false);
|
||||
mIsoDep.notifyReadResult(false);
|
||||
}
|
||||
}
|
||||
|
||||