Updated on 2026-08-14

This commit is contained in:
Tangem 2018-07-19 12:47:55 +03:00
parent 2cc9082d38
commit d04f0d6d45
6 changed files with 904 additions and 1004 deletions

View file

@ -40,11 +40,11 @@ public class ETHRequestTask extends InfuraTask {
BigInteger d = l.divide(new BigInteger("1000000000000000000", 10));
Long balance = d.longValue();
loadedWallet.mCard.setBalanceConfirmed(balance);
loadedWallet.mCard.setBalanceUnconfirmed(0L);
if (loadedWallet.mCard.getBlockchain() != Blockchain.Token)
loadedWallet.mCard.setDecimalBalance(l.toString(10));
loadedWallet.mCard.setDecimalBalanceAlter(l.toString(10));
loadedWallet.getMCard().setBalanceConfirmed(balance);
loadedWallet.getMCard().setBalanceUnconfirmed(0L);
if (loadedWallet.getMCard().getBlockchain() != Blockchain.Token)
loadedWallet.getMCard().setDecimalBalance(l.toString(10));
loadedWallet.getMCard().setDecimalBalanceAlter(l.toString(10));
} catch (JSONException e) {
e.printStackTrace();
@ -57,16 +57,16 @@ public class ETHRequestTask extends InfuraTask {
Long balance = l.longValue();
if (l.compareTo(BigInteger.ZERO) == 0) {
loadedWallet.mCard.setBlockchainID(Blockchain.Ethereum.getID());
loadedWallet.mCard.addTokenToBlockchainName();
loadedWallet.srlLoadedWallet.setRefreshing(false);
loadedWallet.getMCard().setBlockchainID(Blockchain.Ethereum.getID());
loadedWallet.getMCard().addTokenToBlockchainName();
loadedWallet.getSrlLoadedWallet().setRefreshing(false);
loadedWallet.refresh();
return;
}
loadedWallet.mCard.setBalanceConfirmed(balance);
loadedWallet.mCard.setBalanceUnconfirmed(0L);
loadedWallet.mCard.setDecimalBalance(l.toString(10));
loadedWallet.getMCard().setBalanceConfirmed(balance);
loadedWallet.getMCard().setBalanceUnconfirmed(0L);
loadedWallet.getMCard().setDecimalBalance(l.toString(10));
} catch (JSONException e) {
e.printStackTrace();
@ -77,7 +77,7 @@ public class ETHRequestTask extends InfuraTask {
nonce = nonce.substring(2);
BigInteger count = new BigInteger(nonce, 16);
loadedWallet.mCard.SetConfirmTXCount(count);
loadedWallet.getMCard().SetConfirmTXCount(count);
} catch (JSONException e) {
e.printStackTrace();
}
@ -92,7 +92,7 @@ public class ETHRequestTask extends InfuraTask {
JSONObject msg = request.getAnswer();
JSONObject err = msg.getJSONObject("error");
hashTX = err.getString("message");
LastSignStorage.setLastMessage(loadedWallet.mCard.getWallet(), hashTX);
LastSignStorage.setLastMessage(loadedWallet.getMCard().getWallet(), hashTX);
return;
}
@ -100,14 +100,14 @@ public class ETHRequestTask extends InfuraTask {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(loadedWallet.mCard.getWallet());
LastSignStorage.setLastMessage(loadedWallet.mCard.getWallet(), "");
LastSignStorage.setTxWasSend(loadedWallet.getMCard().getWallet());
LastSignStorage.setLastMessage(loadedWallet.getMCard().getWallet(), "");
Log.e("TX_RESULT", hashTX);
BigInteger nonce = loadedWallet.mCard.GetConfirmTXCount();
BigInteger nonce = loadedWallet.getMCard().GetConfirmTXCount();
nonce.add(BigInteger.valueOf(1));
loadedWallet.mCard.SetConfirmTXCount(nonce);
loadedWallet.getMCard().SetConfirmTXCount(nonce);
Log.e("TX_RESULT", hashTX);
} catch (Exception e) {
@ -123,6 +123,6 @@ public class ETHRequestTask extends InfuraTask {
}
}
loadedWallet.srlLoadedWallet.setRefreshing(false);
loadedWallet.getSrlLoadedWallet().setRefreshing(false);
}
}

View file

@ -39,7 +39,7 @@ public class RateInfoTask extends ExchangeTask {
String usd = obj.getString("price_usd");
Float rate = Float.valueOf(usd);
loadedWallet.mCard.setRate(rate);
loadedWallet.getMCard().setRate(rate);
loadedWallet.updateViews();
stop = true;
}
@ -48,7 +48,7 @@ public class RateInfoTask extends ExchangeTask {
String usd = obj.getString("price_usd");
Float rate = Float.valueOf(usd);
loadedWallet.mCard.setRateAlter(rate);
loadedWallet.getMCard().setRateAlter(rate);
loadedWallet.updateViews();
stopAlter = true;
}

View file

@ -60,8 +60,7 @@ public class UpdateWalletInfoTask extends ElectrumTask {
try {
CoinEngine engine = CoinEngineFactory.Create(
loadedWallet.
mCard.getBlockchain());
loadedWallet.getMCard().getBlockchain());
for (ElectrumRequest request : requests) {
try {
@ -71,12 +70,12 @@ public class UpdateWalletInfoTask extends ElectrumTask {
String mWalletAddress = request.getParams().getString(0);
Long confBalance = request.getResult().getLong("confirmed");
Long unconf = request.getResult().getLong("unconfirmed");
loadedWallet.mCard.setBalanceRecieved(true);
loadedWallet.getMCard().setBalanceRecieved(true);
if (sharedCounter != null) {
boolean notEqualBalance = sharedCounter.UpdatePayload(new BigDecimal(String.valueOf(confBalance)));
if (notEqualBalance)
loadedWallet.mCard.setIsBalanceEqual(false);
loadedWallet.getMCard().setIsBalanceEqual(false);
int counter = sharedCounter.requestCounter.incrementAndGet();
if (counter != 1) {
continue;
@ -84,22 +83,22 @@ public class UpdateWalletInfoTask extends ElectrumTask {
}
loadedWallet.mCard.setBalanceConfirmed(confBalance);
loadedWallet.mCard.setBalanceUnconfirmed(unconf);
loadedWallet.mCard.setDecimalBalance(String.valueOf(confBalance));
loadedWallet.getMCard().setBalanceConfirmed(confBalance);
loadedWallet.getMCard().setBalanceUnconfirmed(unconf);
loadedWallet.getMCard().setDecimalBalance(String.valueOf(confBalance));
loadedWallet.mCard.setValidationNodeDescription(getValidationNodeDescription());
loadedWallet.getMCard().setValidationNodeDescription(getValidationNodeDescription());
} catch (JSONException e) {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
loadedWallet.mCard.incFailedBalanceRequestCounter();
loadedWallet.getMCard().incFailedBalanceRequestCounter();
if (errCounter >= sharedCounter.allRequest) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
}
} else if (request.isMethod(ElectrumRequest.METHOD_SendTransaction)) {
@ -107,22 +106,22 @@ public class UpdateWalletInfoTask extends ElectrumTask {
String hashTX = request.getResultString();
try {
LastSignStorage.setLastMessage(loadedWallet.mCard.getWallet(), hashTX);
LastSignStorage.setLastMessage(loadedWallet.getMCard().getWallet(), hashTX);
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(loadedWallet.mCard.getWallet());
LastSignStorage.setLastMessage(loadedWallet.mCard.getWallet(), "");
LastSignStorage.setTxWasSend(loadedWallet.getMCard().getWallet());
LastSignStorage.setLastMessage(loadedWallet.getMCard().getWallet(), "");
// Log.e("TX_RESULT", hashTX);
} catch (Exception e) {
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else if (request.isMethod(ElectrumRequest.METHOD_ListUnspent)) {
try {
@ -130,18 +129,18 @@ public class UpdateWalletInfoTask extends ElectrumTask {
JSONArray jsUnspentArray = request.getResultArray();
try {
loadedWallet.mCard.getUnspentTransactions().clear();
loadedWallet.getMCard().getUnspentTransactions().clear();
for (int i = 0; i < jsUnspentArray.length(); i++) {
JSONObject jsUnspent = jsUnspentArray.getJSONObject(i);
TangemCard.UnspentTransaction trUnspent = new TangemCard.UnspentTransaction();
trUnspent.txID = jsUnspent.getString("tx_hash");
trUnspent.Amount = jsUnspent.getInt("value");
trUnspent.Height = jsUnspent.getInt("height");
loadedWallet.mCard.getUnspentTransactions().add(trUnspent);
loadedWallet.getMCard().getUnspentTransactions().add(trUnspent);
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
for (int i = 0; i < jsUnspentArray.length(); i++) {
@ -149,8 +148,8 @@ public class UpdateWalletInfoTask extends ElectrumTask {
Integer height = jsUnspent.getInt("height");
String hash = jsUnspent.getString("tx_hash");
if (height != -1) {
String nodeAddress = engine.GetNextNode(loadedWallet.mCard);
int nodePort = engine.GetNextNodePort(loadedWallet.mCard);
String nodeAddress = engine.GetNextNode(loadedWallet.getMCard());
int nodePort = engine.GetNextNodePort(loadedWallet.getMCard());
UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(loadedWallet, nodeAddress, nodePort);
// loadedWallet.updateTasks.add(updateWalletInfoTask);
@ -161,7 +160,7 @@ public class UpdateWalletInfoTask extends ElectrumTask {
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else if (request.isMethod(ElectrumRequest.METHOD_GetHistory)) {
try {
@ -169,17 +168,17 @@ public class UpdateWalletInfoTask extends ElectrumTask {
JSONArray jsHistoryArray = request.getResultArray();
try {
loadedWallet.mCard.getHistoryTransactions().clear();
loadedWallet.getMCard().getHistoryTransactions().clear();
for (int i = 0; i < jsHistoryArray.length(); i++) {
JSONObject jsUnspent = jsHistoryArray.getJSONObject(i);
TangemCard.HistoryTransaction trHistory = new TangemCard.HistoryTransaction();
trHistory.txID = jsUnspent.getString("tx_hash");
trHistory.Height = jsUnspent.getInt("height");
loadedWallet.mCard.getHistoryTransactions().add(trHistory);
loadedWallet.getMCard().getHistoryTransactions().add(trHistory);
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
for (int i = 0; i < jsHistoryArray.length(); i++) {
@ -188,8 +187,8 @@ public class UpdateWalletInfoTask extends ElectrumTask {
String hash = jsUnspent.getString("tx_hash");
if (height != -1) {
String nodeAddress = engine.GetNode(loadedWallet.mCard);
int nodePort = engine.GetNodePort(loadedWallet.mCard);
String nodeAddress = engine.GetNode(loadedWallet.getMCard());
int nodePort = engine.GetNodePort(loadedWallet.getMCard());
UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(loadedWallet, nodeAddress, nodePort);
// loadedWallet.updateTasks.add(updateWalletInfoTask);
@ -200,25 +199,25 @@ public class UpdateWalletInfoTask extends ElectrumTask {
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else if (request.isMethod(ElectrumRequest.METHOD_GetHeader)) {
try {
JSONObject jsHeader = request.getResult();
try {
loadedWallet.mCard.getHaedersInfo();
loadedWallet.mCard.UpdateHeaderInfo(new TangemCard.HeaderInfo(
loadedWallet.getMCard().getHaedersInfo();
loadedWallet.getMCard().UpdateHeaderInfo(new TangemCard.HeaderInfo(
jsHeader.getInt("block_height"),
jsHeader.getInt("timestamp")));
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else if (request.isMethod(ElectrumRequest.METHOD_GetTransaction)) {
@ -227,14 +226,14 @@ public class UpdateWalletInfoTask extends ElectrumTask {
String txHash = request.TxHash;
String raw = request.getResultString();
List<TangemCard.UnspentTransaction> listTx = loadedWallet.mCard.getUnspentTransactions();
List<TangemCard.UnspentTransaction> listTx = loadedWallet.getMCard().getUnspentTransactions();
for (TangemCard.UnspentTransaction tx : listTx) {
if (tx.txID.equals(txHash)) {
tx.Raw = raw;
}
}
List<TangemCard.HistoryTransaction> listHTx = loadedWallet.mCard.getHistoryTransactions();
List<TangemCard.HistoryTransaction> listHTx = loadedWallet.getMCard().getHistoryTransactions();
for (TangemCard.HistoryTransaction tx : listHTx) {
if (tx.txID.equals(txHash)) {
tx.Raw = raw;
@ -261,20 +260,20 @@ public class UpdateWalletInfoTask extends ElectrumTask {
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
}
loadedWallet.updateViews();
} else {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
loadedWallet.mCard.incFailedBalanceRequestCounter();
loadedWallet.getMCard().incFailedBalanceRequestCounter();
if (errCounter >= sharedCounter.allRequest) {
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
} else {
engine.SwitchNode(loadedWallet.mCard);
engine.SwitchNode(loadedWallet.getMCard());
}
@ -282,7 +281,7 @@ public class UpdateWalletInfoTask extends ElectrumTask {
} catch (JSONException e) {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
loadedWallet.mCard.incFailedBalanceRequestCounter();
loadedWallet.getMCard().incFailedBalanceRequestCounter();
if (errCounter >= sharedCounter.allRequest) {
e.printStackTrace();
}
@ -292,13 +291,13 @@ public class UpdateWalletInfoTask extends ElectrumTask {
}
}
loadedWallet.srlLoadedWallet.setRefreshing(false);
loadedWallet.getSrlLoadedWallet().setRefreshing(false);
} catch (NullPointerException e) {
e.printStackTrace();
if (reference.get() != null) {
reference.get().srlLoadedWallet.setRefreshing(false);
reference.get().getSrlLoadedWallet().setRefreshing(false);
}
}

View file

@ -1,918 +0,0 @@
package com.tangem.presentation.fragment;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.AppCompatButton;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.WriterException;
import com.tangem.data.network.Server;
import com.tangem.data.network.VolleyHelper;
import com.tangem.data.network.request.ElectrumRequest;
import com.tangem.data.network.request.ExchangeRequest;
import com.tangem.data.network.request.InfuraRequest;
import com.tangem.data.network.request.VerificationServerProtocol;
import com.tangem.data.network.task.VerificationServerTask;
import com.tangem.data.network.task.loaded_wallet.ETHRequestTask;
import com.tangem.data.network.task.loaded_wallet.RateInfoTask;
import com.tangem.data.network.task.loaded_wallet.UpdateWalletInfoTask;
import com.tangem.data.nfc.VerifyCardTask;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.BalanceValidator;
import com.tangem.domain.wallet.Blockchain;
import com.tangem.domain.wallet.CoinEngine;
import com.tangem.domain.wallet.CoinEngineFactory;
import com.tangem.domain.wallet.LastSignStorage;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.SharedData;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.presentation.activity.CreateNewWalletActivity;
import com.tangem.presentation.activity.MainActivity;
import com.tangem.presentation.activity.PreparePaymentActivity;
import com.tangem.presentation.activity.PurgeActivity;
import com.tangem.presentation.activity.RequestPINActivity;
import com.tangem.presentation.activity.SwapPINActivity;
import com.tangem.presentation.activity.VerifyCardActivity;
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog;
import com.tangem.presentation.dialog.PINSwapWarningDialog;
import com.tangem.presentation.dialog.WaitSecurityDelayDialog;
import com.tangem.util.Util;
import com.tangem.util.UtilHelper;
import com.tangem.wallet.R;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import static android.content.Context.CLIPBOARD_SERVICE;
public class LoadedWallet extends Fragment implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final String TAG = LoadedWallet.class.getSimpleName();
private static final int REQUEST_CODE_SEND_PAYMENT = 1;
private static final int REQUEST_CODE_VERIFY_CARD = 4;
private static final int REQUEST_CODE_PURGE = 2;
private static final int REQUEST_CODE_REQUEST_PIN2_FOR_PURGE = 3;
private static final int REQUEST_CODE_ENTER_NEW_PIN = 5;
private static final int REQUEST_CODE_ENTER_NEW_PIN2 = 6;
private static final int REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN = 7;
private static final int REQUEST_CODE_SWAP_PIN = 8;
private NfcManager mNfcManager;
public TangemCard mCard;
private Tag lastTag;
public SwipeRefreshLayout srlLoadedWallet;
private RelativeLayout rlProgressBar;
private TextView tvCardID, tvBalance, tvBalanceLine1, tvBalanceLine2, tvOffline, tvBalanceEquivalent, tvWallet, tvInputs, tvError, tvMessage, tvIssuer, tvBlockchain, tvValidationNode, tvHeader, tvCaution;
private ImageView ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion;
private AppCompatButton btnExtract;
private boolean lastReadSuccess = true;
private VerifyCardTask verifyCardTask = null;
private int requestPIN2Count = 0;
private Timer timerHideErrorAndMessage = null;
private String newPIN = "", newPIN2 = "";
private CardProtocol mCardProtocol;
private OnlineVerifyTask onlineVerifyTask;
private static final String URL_CARD_VALIDATE = Server.API.Method.CARD_VALIDATE;
public LoadedWallet() {
}
private class OnlineVerifyTask extends VerificationServerTask {
@Override
protected void onPostExecute(List<VerificationServerProtocol.Request> requests) {
super.onPostExecute(requests);
onlineVerifyTask = null;
for (VerificationServerProtocol.Request request : requests) {
if (request.error == null) {
VerificationServerProtocol.Verify.Answer answer = (VerificationServerProtocol.Verify.Answer) request.answer;
if (answer.error == null) {
mCard.setOnlineVerified(answer.results[0].passed);
} else {
mCard.setOnlineVerified(null);
}
} else {
mCard.setOnlineVerified(null);
}
}
srlLoadedWallet.setRefreshing(false);
}
}
private void requestCardValidate() {
Map<String, String> params = new HashMap<>();
params.put("CID", Util.bytesToHex(mCard.getCID()));
params.put("publicKey", Util.bytesToHex(mCard.getCardPublicKey()));
new VolleyHelper().doRequest(getContext(), URL_CARD_VALIDATE, params);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNfcManager = new NfcManager(getActivity(), this);
mCard = new TangemCard(getActivity().getIntent().getStringExtra(TangemCard.EXTRA_CARD));
mCard.LoadFromBundle(getActivity().getIntent().getExtras().getBundle(TangemCard.EXTRA_CARD));
lastTag = getActivity().getIntent().getParcelableExtra(Main.EXTRA_LAST_DISCOVERED_TAG);
// requestCardValidate();
}
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fr_loaded_wallet, container, false);
srlLoadedWallet = v.findViewById(R.id.srlLoadedWallet);
rlProgressBar = v.findViewById(R.id.rlProgressBar);
ImageView ivTangemCard = v.findViewById(R.id.ivTangemCard);
tvBalance = v.findViewById(R.id.tvBalance);
tvBalanceLine1 = v.findViewById(R.id.tvBalanceLine1);
tvBalanceLine2 = v.findViewById(R.id.tvBalanceLine2);
tvOffline = v.findViewById(R.id.tvOffline);
tvCardID = v.findViewById(R.id.tvCardID);
tvWallet = v.findViewById(R.id.tvWallet);
tvInputs = v.findViewById(R.id.tvInputs);
tvError = v.findViewById(R.id.tvError);
tvMessage = v.findViewById(R.id.tvMessage);
tvIssuer = v.findViewById(R.id.tvIssuer);
tvHeader = v.findViewById(R.id.tvHeader);
tvCaution = v.findViewById(R.id.tvCaution);
ImageView imgLookup = v.findViewById(R.id.imgLookup);
ImageView ivCopy = v.findViewById(R.id.ivCopy);
tvValidationNode = v.findViewById(R.id.tvValidationNode);
tvBlockchain = v.findViewById(R.id.tvBlockchain);
ivPIN = v.findViewById(R.id.imgPIN);
ivPIN2orSecurityDelay = v.findViewById(R.id.imgPIN2orSecurityDelay);
ivDeveloperVersion = v.findViewById(R.id.imgDeveloperVersion);
ImageView ivQR = v.findViewById(R.id.qrWallet);
FloatingActionButton fabInfo = v.findViewById(R.id.fabInfo);
FloatingActionButton fabNFC = v.findViewById(R.id.fabNFC);
AppCompatButton btnLoad = v.findViewById(R.id.btnLoad);
btnExtract = v.findViewById(R.id.btnExtract);
tvBalanceEquivalent = v.findViewById(R.id.tvBalanceEquivalent);
if (mCard.getBlockchain() == Blockchain.Token)
tvBalance.setSingleLine(false);
ivTangemCard.setImageResource(mCard.getCardImageResource());
final CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
boolean visibleFlag = engine != null ? engine.InOutPutVisible() : true;
int visibleIOPuts = visibleFlag ? View.VISIBLE : View.GONE;
tvInputs.setVisibility(visibleIOPuts);
try {
ivQR.setImageBitmap(UtilHelper.INSTANCE.generateQrCode(engine.getShareWalletURI(mCard).toString()));
} catch (WriterException e) {
e.printStackTrace();
}
updateViews();
if (!mCard.hasBalanceInfo()) {
srlLoadedWallet.setRefreshing(true);
srlLoadedWallet.postDelayed(this::refresh, 1000);
}
if ((mCard.isOnlineVerified() == null || !mCard.isOnlineVerified()) && onlineVerifyTask == null) {
onlineVerifyTask = new OnlineVerifyTask();
onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard));
}
startVerify(lastTag);
tvWallet.setText(mCard.getWallet());
// set listeners
srlLoadedWallet.setOnRefreshListener(this::refresh);
imgLookup.setOnClickListener(v15 -> {
if (!mCard.hasBalanceInfo()) return;
CoinEngine engineClick = CoinEngineFactory.Create(mCard.getBlockchain());
Intent browserIntent = new Intent(Intent.ACTION_VIEW, engineClick.getShareWalletURIExplorer(mCard));
startActivity(browserIntent);
});
ivCopy.setOnClickListener(v14 -> doShareWallet(false));
tvWallet.setOnClickListener(v12 -> doShareWallet(false));
ivQR.setOnClickListener(v1 -> doShareWallet(true));
btnLoad.setOnClickListener(v1 -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, CoinEngineFactory.Create(mCard.getBlockchain()).getShareWalletURI(mCard));
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
);
fabInfo.setOnClickListener(v16 -> {
if (mCardProtocol != null)
openVerifyCard(mCardProtocol);
else
Toast.makeText(getContext(), R.string.need_attach_card_again, Toast.LENGTH_LONG).show();
});
fabNFC.setOnClickListener(view -> {
Intent intent = new Intent(getContext(), MainActivity.class);
startActivity(intent);
});
btnExtract.setOnClickListener(v13 -> {
if (!mCard.hasBalanceInfo()) {
return;
} else if (!engine.IsBalanceNotZero(mCard)) {
Toast.makeText(getContext(), R.string.wallet_empty, Toast.LENGTH_LONG).show();
return;
} else if (!engine.IsBalanceAlterNotZero(mCard)) {
Toast.makeText(getContext(), R.string.not_enough_funds, Toast.LENGTH_LONG).show();
return;
} else if (engine.AwaitingConfirmation(mCard)) {
Toast.makeText(getContext(), R.string.please_wait_while_previous, Toast.LENGTH_LONG).show();
return;
} else if (!engine.CheckUnspentTransaction(mCard)) {
Toast.makeText(getContext(), R.string.please_wait_for_confirmation, Toast.LENGTH_LONG).show();
return;
} else if (mCard.getRemainingSignatures() == 0) {
Toast.makeText(getContext(), R.string.card_hasn_t_remaining_signature, Toast.LENGTH_LONG).show();
return;
}
Intent intent = new Intent(getContext(), PreparePaymentActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT);
});
return v;
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_VERIFY_CARD:
// action when erase wallet
if (resultCode == Activity.RESULT_OK) {
if (getActivity() != null)
getActivity().finish();
}
break;
case REQUEST_CODE_ENTER_NEW_PIN:
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
if (data.getExtras() != null && data.getExtras().containsKey("confirmPIN")) {
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
newPIN = data.getStringExtra("newPIN");
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN);
} else {
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("newPIN", data.getStringExtra("newPIN"));
intent.putExtra("mode", RequestPINActivity.Mode.ConfirmNewPIN.toString());
startActivityForResult(intent, REQUEST_CODE_ENTER_NEW_PIN);
}
}
}
break;
case REQUEST_CODE_ENTER_NEW_PIN2:
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
if (data.getExtras() != null && data.getExtras().containsKey("confirmPIN2")) {
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
newPIN2 = data.getStringExtra("newPIN2");
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN);
} else {
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("newPIN2", data.getStringExtra("newPIN2"));
intent.putExtra("mode", RequestPINActivity.Mode.ConfirmNewPIN2.toString());
startActivityForResult(intent, REQUEST_CODE_ENTER_NEW_PIN2);
}
}
}
break;
case REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN:
if (resultCode == Activity.RESULT_OK) {
if (newPIN.equals(""))
newPIN = mCard.getPIN();
if (newPIN2.equals(""))
newPIN2 = PINStorage.getPIN2();
PINSwapWarningDialog pinSwapWarningDialog = new PINSwapWarningDialog();
pinSwapWarningDialog.setOnRefreshPage(this::startSwapPINActivity);
Bundle bundle = new Bundle();
if (!PINStorage.isDefaultPIN(newPIN) || !PINStorage.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));
pinSwapWarningDialog.setArguments(bundle);
pinSwapWarningDialog.show(getActivity().getFragmentManager(), PINSwapWarningDialog.TAG);
}
break;
case REQUEST_CODE_SWAP_PIN:
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = new Intent();
data.putExtra("UID", mCard.getUID());
data.putExtra("Card", mCard.getAsBundle());
data.putExtra("modification", "delete");
} else
data.putExtra("modification", "update");
if (getActivity() != null) {
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
} else {
if (data != null && data.getExtras() != null && data.getExtras().containsKey("UID") && data.getExtras().containsKey("Card")) {
TangemCard updatedCard = new TangemCard(data.getStringExtra("UID"));
updatedCard.LoadFromBundle(data.getBundleExtra("Card"));
mCard = updatedCard;
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++;
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN);
return;
} else {
if (data != null && data.getExtras().containsKey("message")) {
mCard.setError(data.getStringExtra("message"));
}
}
}
break;
case REQUEST_CODE_REQUEST_PIN2_FOR_PURGE:
if (resultCode == Activity.RESULT_OK) {
Intent intent = new Intent(getContext(), PurgeActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_PURGE);
}
break;
case REQUEST_CODE_PURGE:
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = new Intent();
data.putExtra("UID", mCard.getUID());
data.putExtra("Card", mCard.getAsBundle());
data.putExtra("modification", "delete");
} else {
data.putExtra("modification", "update");
}
if (getActivity() != null) {
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
} else {
if (data != null && data.getExtras() != null && data.getExtras().containsKey("UID") && data.getExtras().containsKey("Card")) {
TangemCard updatedCard = new TangemCard(data.getStringExtra("UID"));
updatedCard.LoadFromBundle(data.getBundleExtra("Card"));
mCard = updatedCard;
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++;
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE);
return;
} else {
if (data != null && data.getExtras().containsKey("message")) {
mCard.setError(data.getStringExtra("message"));
}
}
updateViews();
}
break;
case REQUEST_CODE_SEND_PAYMENT:
if (resultCode == Activity.RESULT_OK) {
srlLoadedWallet.postDelayed(this::refresh, 10000);
srlLoadedWallet.setRefreshing(true);
mCard.clearInfo();
updateViews();
}
if (data != null && data.getExtras() != null) {
if (data.getExtras().containsKey("UID") && data.getExtras().containsKey("Card")) {
TangemCard updatedCard = new TangemCard(data.getStringExtra("UID"));
updatedCard.LoadFromBundle(data.getBundleExtra("Card"));
mCard = updatedCard;
}
if (data.getExtras().containsKey("message")) {
if (resultCode == Activity.RESULT_OK) {
mCard.setMessage(data.getStringExtra("message"));
} else {
mCard.setError(data.getStringExtra("message"));
}
}
updateViews();
}
break;
}
}
public void refresh() {
srlLoadedWallet.setRefreshing(true);
mCard.clearInfo();
mCard.setError(null);
mCard.setMessage(null);
boolean needResendTX = LastSignStorage.getNeedTxSend(mCard.getWallet());
updateViews();
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if ((mCard.isOnlineVerified() == null || !mCard.isOnlineVerified()) && onlineVerifyTask == null) {
onlineVerifyTask = new OnlineVerifyTask();
onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard));
}
if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
mCard.resetFailedBalanceRequestCounter();
mCard.setIsBalanceEqual(true);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(mCard);
int nodePort = engine.GetNextNodePort(mCard);
UpdateWalletInfoTask connectTaskEx = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.CheckBalance(mCard.getWallet()));
UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort, data);
updateWalletInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.ListUnspent(mCard.getWallet()));
}
RateInfoTask taskRate = new RateInfoTask(LoadedWallet.this);
ExchangeRequest rate = ExchangeRequest.GetRate(mCard.getWallet(), "bitcoin", "bitcoin");
taskRate.execute(rate);
} else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) {
mCard.resetFailedBalanceRequestCounter();
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
mCard.setIsBalanceEqual(true);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(mCard);
int nodePort = engine.GetNextNodePort(mCard);
UpdateWalletInfoTask connectTaskEx = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.CheckBalance(mCard.getWallet()));
}
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort, data);
updateWalletInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.ListUnspent(mCard.getWallet()));
RateInfoTask taskRate = new RateInfoTask(LoadedWallet.this);
ExchangeRequest rate = ExchangeRequest.GetRate(mCard.getWallet(), "bitcoin-cash", "bitcoin-cash");
taskRate.execute(rate);
} else if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet) {
ETHRequestTask updateETH = new ETHRequestTask(LoadedWallet.this, mCard.getBlockchain());
InfuraRequest reqETH = InfuraRequest.GetBalance(mCard.getWallet());
reqETH.setID(67);
reqETH.setBlockchain(mCard.getBlockchain());
InfuraRequest reqNonce = InfuraRequest.GetOutTransactionCount(mCard.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(mCard.getBlockchain());
updateETH.execute(reqETH, reqNonce);
RateInfoTask taskRate = new RateInfoTask(LoadedWallet.this);
ExchangeRequest rate = ExchangeRequest.GetRate(mCard.getWallet(), "ethereum", "ethereum");
taskRate.execute(rate);
} else if (mCard.getBlockchain() == Blockchain.Token) {
ETHRequestTask updateETH = new ETHRequestTask(LoadedWallet.this, mCard.getBlockchain());
InfuraRequest reqETH = InfuraRequest.GetTokenBalance(mCard.getWallet(), engine.GetContractAddress(mCard), engine.GetTokenDecimals(mCard));
reqETH.setID(67);
reqETH.setBlockchain(mCard.getBlockchain());
InfuraRequest reqBalance = InfuraRequest.GetBalance(mCard.getWallet());
reqBalance.setID(67);
reqBalance.setBlockchain(mCard.getBlockchain());
InfuraRequest reqNonce = InfuraRequest.GetOutTransactionCount(mCard.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(mCard.getBlockchain());
updateETH.execute(reqETH, reqNonce, reqBalance);
RateInfoTask taskRate = new RateInfoTask(LoadedWallet.this);
ExchangeRequest rate = ExchangeRequest.GetRate(mCard.getWallet(), "ethereum", "ethereum");
taskRate.execute(rate);
}
if (needResendTX)
sendTransaction(LastSignStorage.getTxForSend(mCard.getWallet()));
}
@Override
public void onTagDiscovered(Tag tag) {
startVerify(tag);
}
public Intent prepareResultIntent() {
Intent data = new Intent();
data.putExtra("UID", mCard.getUID());
data.putExtra("Card", mCard.getAsBundle());
return data;
}
@Override
public void OnReadStart(CardProtocol cardProtocol) {
rlProgressBar.post(() -> rlProgressBar.setVisibility(View.VISIBLE));
}
@Override
public void OnReadFinish(final CardProtocol cardProtocol) {
verifyCardTask = null;
if (cardProtocol != null) {
if (cardProtocol.getError() == null) {
rlProgressBar.post(() -> {
rlProgressBar.setVisibility(View.GONE);
mCardProtocol = cardProtocol;
refresh();
});
} else {
// remove last UIDs because of error and no card read
rlProgressBar.post(() -> {
lastReadSuccess = false;
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported)
if (!NoExtendedLengthSupportDialog.allreadyShowed)
new NoExtendedLengthSupportDialog().show(getActivity().getFragmentManager(), NoExtendedLengthSupportDialog.TAG);
else
Toast.makeText(getContext(), R.string.try_to_scan_again, Toast.LENGTH_SHORT).show();
});
}
}
rlProgressBar.postDelayed(() -> {
try {
rlProgressBar.setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}, 500);
}
@Override
public void OnReadProgress(CardProtocol protocol, final int progress) {
}
@Override
public void OnReadCancel() {
verifyCardTask = null;
rlProgressBar.postDelayed(() -> {
try {
rlProgressBar.setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}, 500);
}
@Override
public void OnReadWait(int msec) {
WaitSecurityDelayDialog.OnReadWait(getActivity(), msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(getActivity(), timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(getActivity());
}
public void updateViews() {
try {
if (timerHideErrorAndMessage != null) {
timerHideErrorAndMessage.cancel();
timerHideErrorAndMessage = null;
}
tvCardID.setText(mCard.getCIDDescription());
if ((mCard.getError() == null || mCard.getError().isEmpty())) {
tvError.setVisibility(View.GONE);
tvError.setText("");
} else {
tvError.setVisibility(View.VISIBLE);
tvError.setText(mCard.getError());
}
boolean needResendTX = LastSignStorage.getNeedTxSend(mCard.getWallet());
if ((mCard.getMessage() == null || mCard.getMessage().isEmpty()) && !needResendTX) {
tvMessage.setText("");
tvMessage.setVisibility(View.GONE);
} else {
if (needResendTX) {
} else {
tvMessage.setText(mCard.getMessage());
}
tvMessage.setVisibility(View.VISIBLE);
}
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {
BalanceValidator validator = new BalanceValidator();
validator.Check(mCard);
tvBalanceLine1.setText(validator.GetFirstLine());
tvBalanceLine2.setText(validator.GetSecondLine());
tvBalanceLine1.setTextColor(ContextCompat.getColor(getContext(), validator.GetColor()));
}
if (engine.HasBalanceInfo(mCard) || mCard.getOfflineBalance() == null) {
if (mCard.getBlockchain() == Blockchain.Token) {
Spanned html = Html.fromHtml(engine.GetBalanceWithAlter(mCard));
tvBalance.setText(html);
} else {
tvBalance.setText(engine.GetBalanceWithAlter(mCard));
}
tvBalanceEquivalent.setText(engine.GetBalanceEquivalent(mCard));
tvOffline.setVisibility(View.INVISIBLE);
} else {
String offlineAmount = engine.ConvertByteArrayToAmount(mCard, mCard.getOfflineBalance());
if (mCard.getBlockchain() == Blockchain.Token) {
tvBalance.setText(R.string.not_implemented);
} else {
tvBalance.setText(engine.GetAmountDescription(mCard, offlineAmount));
}
tvBalanceEquivalent.setText(engine.GetAmountEqualentDescriptor(mCard, offlineAmount));
tvOffline.setVisibility(View.VISIBLE);
}
if (!mCard.getAmountEquivalentDescriptionAvailable()) {
} else {
tvBalanceEquivalent.setError(null);
}
tvWallet.setText(mCard.getWallet());
tvInputs.setText(mCard.getInputsDescription());
if (mCard.getLastInputDescription().contains("awaiting"))
tvInputs.setTextColor(ContextCompat.getColor(getContext(), R.color.not_confirmed));
else if (mCard.getLastInputDescription().contains("None"))
tvInputs.setTextColor(ContextCompat.getColor(getContext(), R.color.primary_dark));
else
tvInputs.setTextColor(ContextCompat.getColor(getContext(), R.color.confirmed));
tvBlockchain.setText(mCard.getBlockchainName());
if (tvValidationNode != null) {
tvValidationNode.setText(mCard.getValidationNodeDescription());
}
if (mCard.useDefaultPIN1()) {
ivPIN.setImageResource(R.drawable.unlock_pin1);
ivPIN.setOnClickListener(v -> Toast.makeText(getContext(), R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show());
} else {
ivPIN.setImageResource(R.drawable.lock_pin1);
ivPIN.setOnClickListener(v -> Toast.makeText(getContext(), R.string.this_banknote_protected_user_PIN1_code, Toast.LENGTH_LONG).show());
}
if (mCard.getPauseBeforePIN2() > 0 && (mCard.useDefaultPIN2() || !mCard.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer);
ivPIN2orSecurityDelay.setOnClickListener(v -> Toast.makeText(getContext(), String.format("This banknote will enforce %.0f seconds security delay for all operations requiring PIN2 code", mCard.getPauseBeforePIN2() / 1000.0), Toast.LENGTH_LONG).show());
} else if (mCard.useDefaultPIN2()) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(v -> Toast.makeText(getContext(), R.string.this_banknote_protected_default_PIN2_code, Toast.LENGTH_LONG).show());
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(v -> Toast.makeText(getContext(), R.string.this_banknote_protected_user_PIN2_code, Toast.LENGTH_LONG).show());
}
if (mCard.useDevelopersFirmware()) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version);
ivDeveloperVersion.setVisibility(View.VISIBLE);
ivDeveloperVersion.setOnClickListener(v -> Toast.makeText(getContext(), R.string.unlocked_banknote_only_development_use, Toast.LENGTH_LONG).show());
} else {
ivDeveloperVersion.setVisibility(View.INVISIBLE);
}
if (mCard.hasBalanceInfo())
btnExtract.setEnabled(true);
else
btnExtract.setEnabled(false);
tvIssuer.setText(mCard.getIssuerDescription());
timerHideErrorAndMessage = new Timer();
timerHideErrorAndMessage.schedule(new TimerTask() {
@Override
public void run() {
tvError.post(() -> {
tvMessage.setVisibility(View.GONE);
tvError.setVisibility(View.GONE);
mCard.setError(null);
mCard.setMessage(null);
});
}
}, 5000);
} catch (Exception e) {
e.printStackTrace();
}
}
private void openVerifyCard(CardProtocol cardProtocol) {
Intent intent = new Intent(getContext(), VerifyCardActivity.class);
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD);
}
private void startVerify(Tag tag) {
try {
final IsoDep isoDep = IsoDep.get(tag);
if (isoDep == null) {
throw new CardProtocol.TangemException(getString(R.string.wrong_tag_err));
}
byte UID[] = tag.getId();
String sUID = Util.byteArrayToHexString(UID);
if (!mCard.getUID().equals(sUID)) {
Log.d(TAG, "Invalid UID: " + sUID);
mNfcManager.ignoreTag(isoDep.getTag());
return;
} else {
Log.v(TAG, "UID: " + sUID);
}
if (lastReadSuccess) {
isoDep.setTimeout(1000);
} else {
isoDep.setTimeout(65000);
}
verifyCardTask = new VerifyCardTask(getContext(), mCard, mNfcManager, isoDep, this);
verifyCardTask.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private void doShareWallet(boolean useURI) {
if (useURI) {
String txtShare = CoinEngineFactory.Create(mCard.getBlockchain()).getShareWalletURI(mCard).toString();
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "Wallet address");
intent.putExtra(Intent.EXTRA_TEXT, txtShare);
PackageManager packageManager = getActivity().getPackageManager();
List activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
String title = getString(R.string.share_wallet_address_with);
// create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);
// verify the intent will resolve to at least one activity
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(chooser);
}
} else {
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText(txtShare, txtShare));
Toast.makeText(getContext(), R.string.copied_clipboard, Toast.LENGTH_LONG).show();
}
} else {
String txtShare = mCard.getWallet();
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText(txtShare, txtShare));
Toast.makeText(getContext(), R.string.copied_clipboard, Toast.LENGTH_LONG).show();
}
}
private void sendTransaction(String tx) {
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet || mCard.getBlockchain() == Blockchain.Token) {
ETHRequestTask task = new ETHRequestTask(LoadedWallet.this, mCard.getBlockchain());
InfuraRequest req = InfuraRequest.SendTransaction(mCard.getWallet(), tx);
req.setID(67);
req.setBlockchain(mCard.getBlockchain());
task.execute(req);
} else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
UpdateWalletInfoTask connectTask = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort);
connectTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.Broadcast(mCard.getWallet(), tx));
} else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
UpdateWalletInfoTask connectTask = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort);
connectTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.Broadcast(mCard.getWallet(), tx));
}
}
private void startSwapPINActivity() {
Intent intent = new Intent(getContext(), SwapPINActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
intent.putExtra("newPIN", newPIN);
intent.putExtra("newPIN2", newPIN2);
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN);
}
}

View file

@ -0,0 +1,817 @@
package com.tangem.presentation.fragment
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.content.Intent
import android.content.pm.PackageManager
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.AsyncTask
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v4.widget.SwipeRefreshLayout
import android.text.Html
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.google.zxing.WriterException
import com.tangem.data.network.Server
import com.tangem.data.network.VolleyHelper
import com.tangem.data.network.request.ElectrumRequest
import com.tangem.data.network.request.ExchangeRequest
import com.tangem.data.network.request.InfuraRequest
import com.tangem.data.network.request.VerificationServerProtocol
import com.tangem.data.network.task.VerificationServerTask
import com.tangem.data.network.task.loaded_wallet.ETHRequestTask
import com.tangem.data.network.task.loaded_wallet.RateInfoTask
import com.tangem.data.network.task.loaded_wallet.UpdateWalletInfoTask
import com.tangem.data.nfc.VerifyCardTask
import com.tangem.domain.cardReader.CardProtocol
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.*
import com.tangem.presentation.activity.*
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.PINSwapWarningDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.util.Util
import com.tangem.util.UtilHelper
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.fr_loaded_wallet.*
import java.util.*
class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
companion object {
val TAG: String = LoadedWallet::class.java.simpleName
private const val REQUEST_CODE_SEND_PAYMENT = 1
private const val REQUEST_CODE_VERIFY_CARD = 4
private const val REQUEST_CODE_PURGE = 2
private const val REQUEST_CODE_REQUEST_PIN2_FOR_PURGE = 3
private const val REQUEST_CODE_ENTER_NEW_PIN = 5
private const val REQUEST_CODE_ENTER_NEW_PIN2 = 6
private const val REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN = 7
private const val REQUEST_CODE_SWAP_PIN = 8
private const val URL_CARD_VALIDATE = Server.API.Method.CARD_VALIDATE
}
private var mNfcManager: NfcManager? = null
var mCard: TangemCard? = null
private var lastTag: Tag? = null
var srlLoadedWallet: SwipeRefreshLayout? = null
private var lastReadSuccess = true
private var verifyCardTask: VerifyCardTask? = null
private var requestPIN2Count = 0
private var timerHideErrorAndMessage: Timer? = null
private var newPIN = ""
private var newPIN2 = ""
private var mCardProtocol: CardProtocol? = null
private var onlineVerifyTask: OnlineVerifyTask? = null
private inner class OnlineVerifyTask : VerificationServerTask() {
override fun onPostExecute(requests: List<VerificationServerProtocol.Request>) {
super.onPostExecute(requests)
onlineVerifyTask = null
for (request in requests) {
if (request.error == null) {
val answer = request.answer as VerificationServerProtocol.Verify.Answer
if (answer.error == null) {
mCard!!.isOnlineVerified = answer.results[0].passed
} else {
mCard!!.isOnlineVerified = null
}
} else {
mCard!!.isOnlineVerified = null
}
}
srlLoadedWallet!!.isRefreshing = false
}
}
private fun requestCardValidate() {
val params = HashMap<String, String>()
params["CID"] = Util.bytesToHex(mCard!!.cid)
params["publicKey"] = Util.bytesToHex(mCard!!.cardPublicKey)
VolleyHelper().doRequest(context!!, URL_CARD_VALIDATE, params)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mNfcManager = NfcManager(activity, this)
mCard = TangemCard(activity!!.intent.getStringExtra(TangemCard.EXTRA_CARD))
mCard!!.LoadFromBundle(activity!!.intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
lastTag = activity!!.intent.getParcelableExtra(Main.EXTRA_LAST_DISCOVERED_TAG)
// requestCardValidate();
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.fr_loaded_wallet, container, false)
srlLoadedWallet = v.findViewById(R.id.srlLoadedWallet)
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (mCard!!.blockchain == Blockchain.Token)
tvBalance.setSingleLine(false)
ivTangemCard.setImageResource(mCard!!.cardImageResource)
val engine = CoinEngineFactory.Create(mCard!!.blockchain)
val visibleFlag = engine?.InOutPutVisible() ?: true
val visibleIOPuts = if (visibleFlag) View.VISIBLE else View.GONE
tvInputs.visibility = visibleIOPuts
try {
ivQR.setImageBitmap(UtilHelper.generateQrCode(engine!!.getShareWalletURI(mCard).toString()))
} catch (e: WriterException) {
e.printStackTrace()
}
updateViews()
if (!mCard!!.hasBalanceInfo()) {
srlLoadedWallet!!.isRefreshing = true
srlLoadedWallet!!.postDelayed({ this.refresh() }, 1000)
}
if ((mCard!!.isOnlineVerified == null || !mCard!!.isOnlineVerified) && onlineVerifyTask == null) {
onlineVerifyTask = OnlineVerifyTask()
onlineVerifyTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard))
}
startVerify(lastTag)
tvWallet.text = mCard!!.wallet
// set listeners
srlLoadedWallet!!.setOnRefreshListener { this.refresh() }
ivLookup.setOnClickListener {
if (mCard!!.hasBalanceInfo()) {
val engineClick = CoinEngineFactory.Create(mCard!!.blockchain)
val browserIntent = Intent(Intent.ACTION_VIEW, engineClick!!.getShareWalletURIExplorer(mCard))
startActivity(browserIntent)
}
}
ivCopy.setOnClickListener { doShareWallet(false) }
tvWallet.setOnClickListener { doShareWallet(false) }
ivQR.setOnClickListener { doShareWallet(true) }
btnLoad.setOnClickListener {
try {
val intent = Intent(Intent.ACTION_VIEW, CoinEngineFactory.Create(mCard!!.blockchain)!!.getShareWalletURI(mCard))
intent.addCategory(Intent.CATEGORY_DEFAULT)
startActivity(intent)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
}
}
fabInfo.setOnClickListener {
if (mCardProtocol != null)
openVerifyCard(mCardProtocol!!)
else
Toast.makeText(context, R.string.need_attach_card_again, Toast.LENGTH_LONG).show()
}
fabNFC.setOnClickListener {
val intent = Intent(context, MainActivity::class.java)
startActivity(intent)
}
btnExtract.setOnClickListener {
if (!mCard!!.hasBalanceInfo()) {
} else if (!engine!!.IsBalanceNotZero(mCard))
Toast.makeText(context, R.string.wallet_empty, Toast.LENGTH_LONG).show()
else if (!engine.IsBalanceAlterNotZero(mCard))
Toast.makeText(context, R.string.not_enough_funds, Toast.LENGTH_LONG).show()
else if (engine.AwaitingConfirmation(mCard))
Toast.makeText(context, R.string.please_wait_while_previous, Toast.LENGTH_LONG).show()
else if (!engine.CheckUnspentTransaction(mCard))
Toast.makeText(context, R.string.please_wait_for_confirmation, Toast.LENGTH_LONG).show()
else if (mCard!!.remainingSignatures == 0)
Toast.makeText(context, R.string.card_hasn_t_remaining_signature, Toast.LENGTH_LONG).show()
val intent = Intent(context, PreparePaymentActivity::class.java)
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT)
}
}
override fun onResume() {
super.onResume()
mNfcManager!!.onResume()
}
override fun onPause() {
super.onPause()
mNfcManager!!.onPause()
}
override fun onStop() {
super.onStop()
mNfcManager!!.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
var data = data
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_VERIFY_CARD ->
// action when erase wallet
if (resultCode == Activity.RESULT_OK) {
if (activity != null)
activity!!.finish()
}
REQUEST_CODE_ENTER_NEW_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data != null) {
if (data.extras != null && data.extras!!.containsKey("confirmPIN")) {
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString())
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
newPIN = data.getStringExtra("newPIN")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("newPIN", data.getStringExtra("newPIN"))
intent.putExtra("mode", RequestPINActivity.Mode.ConfirmNewPIN.toString())
startActivityForResult(intent, REQUEST_CODE_ENTER_NEW_PIN)
}
}
}
REQUEST_CODE_ENTER_NEW_PIN2 -> if (resultCode == Activity.RESULT_OK) {
if (data != null) {
if (data.extras != null && data.extras!!.containsKey("confirmPIN2")) {
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString())
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
newPIN2 = data.getStringExtra("newPIN2")
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
} else {
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("newPIN2", data.getStringExtra("newPIN2"))
intent.putExtra("mode", RequestPINActivity.Mode.ConfirmNewPIN2.toString())
startActivityForResult(intent, REQUEST_CODE_ENTER_NEW_PIN2)
}
}
}
REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (newPIN == "")
newPIN = mCard!!.pin
if (newPIN2 == "")
newPIN2 = PINStorage.getPIN2()
val pinSwapWarningDialog = PINSwapWarningDialog()
pinSwapWarningDialog.setOnRefreshPage { this.startSwapPINActivity() }
val bundle = Bundle()
if (!PINStorage.isDefaultPIN(newPIN) || !PINStorage.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))
pinSwapWarningDialog.arguments = bundle
pinSwapWarningDialog.show(activity!!.fragmentManager, PINSwapWarningDialog.TAG)
}
REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
data.putExtra("UID", mCard!!.uid)
data.putExtra("Card", mCard!!.asBundle)
data.putExtra("modification", "delete")
} else
data.putExtra("modification", "update")
if (activity != null) {
activity!!.setResult(Activity.RESULT_OK, data)
activity!!.finish()
}
} else {
if (data != null && data.extras != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
val updatedCard = TangemCard(data.getStringExtra("UID"))
updatedCard.LoadFromBundle(data.getBundleExtra("Card"))
mCard = updatedCard
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString())
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
return
} else {
if (data != null && data.extras!!.containsKey("message")) {
mCard!!.error = data.getStringExtra("message")
}
}
}
REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) {
val intent = Intent(context, PurgeActivity::class.java)
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
startActivityForResult(intent, REQUEST_CODE_PURGE)
}
REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
if (data == null) {
data = Intent()
data.putExtra("UID", mCard!!.uid)
data.putExtra("Card", mCard!!.asBundle)
data.putExtra("modification", "delete")
} else {
data.putExtra("modification", "update")
}
if (activity != null) {
activity!!.setResult(Activity.RESULT_OK, data)
activity!!.finish()
}
} else {
if (data != null && data.extras != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
val updatedCard = TangemCard(data.getStringExtra("UID"))
updatedCard.LoadFromBundle(data.getBundleExtra("Card"))
mCard = updatedCard
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++
val intent = Intent(context, RequestPINActivity::class.java)
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString())
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
return
} else {
if (data != null && data.extras!!.containsKey("message")) {
mCard!!.error = data.getStringExtra("message")
}
}
updateViews()
}
REQUEST_CODE_SEND_PAYMENT -> {
if (resultCode == Activity.RESULT_OK) {
srlLoadedWallet!!.postDelayed({ this.refresh() }, 10000)
srlLoadedWallet!!.isRefreshing = true
mCard!!.clearInfo()
updateViews()
}
if (data != null && data.extras != null) {
if (data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
val updatedCard = TangemCard(data.getStringExtra("UID"))
updatedCard.LoadFromBundle(data.getBundleExtra("Card"))
mCard = updatedCard
}
if (data.extras!!.containsKey("message")) {
if (resultCode == Activity.RESULT_OK) {
mCard!!.message = data.getStringExtra("message")
} else {
mCard!!.error = data.getStringExtra("message")
}
}
updateViews()
}
}
}
}
fun refresh() {
srlLoadedWallet!!.isRefreshing = true
mCard!!.clearInfo()
mCard!!.error = null
mCard!!.message = null
val needResendTX = LastSignStorage.getNeedTxSend(mCard!!.wallet)
updateViews()
val engine = CoinEngineFactory.Create(mCard!!.blockchain)
if ((mCard!!.isOnlineVerified == null || !mCard!!.isOnlineVerified) && onlineVerifyTask == null) {
onlineVerifyTask = OnlineVerifyTask()
onlineVerifyTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard))
}
if (mCard!!.blockchain == Blockchain.Bitcoin || mCard!!.blockchain == Blockchain.BitcoinTestNet) {
val data = SharedData(SharedData.COUNT_REQUEST)
mCard!!.resetFailedBalanceRequestCounter()
mCard!!.setIsBalanceEqual(true)
for (i in 0 until data.allRequest) {
val nodeAddress = engine!!.GetNextNode(mCard)
val nodePort = engine.GetNextNodePort(mCard)
val connectTaskEx = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort, data)
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.CheckBalance(mCard!!.wallet))
val updateWalletInfoTask = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort, data)
updateWalletInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.ListUnspent(mCard!!.wallet))
}
val taskRate = RateInfoTask(this@LoadedWallet)
val rate = ExchangeRequest.GetRate(mCard!!.wallet, "bitcoin", "bitcoin")
taskRate.execute(rate)
} else if (mCard!!.blockchain == Blockchain.BitcoinCash || mCard!!.blockchain == Blockchain.BitcoinCashTestNet) {
mCard!!.resetFailedBalanceRequestCounter()
val data = SharedData(SharedData.COUNT_REQUEST)
mCard!!.setIsBalanceEqual(true)
for (i in 0 until data.allRequest) {
val nodeAddress = engine!!.GetNextNode(mCard)
val nodePort = engine.GetNextNodePort(mCard)
val connectTaskEx = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort, data)
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.CheckBalance(mCard!!.wallet))
}
val nodeAddress = engine!!.GetNode(mCard)
val nodePort = engine.GetNodePort(mCard)
val updateWalletInfoTask = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort, data)
updateWalletInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.ListUnspent(mCard!!.wallet))
val taskRate = RateInfoTask(this@LoadedWallet)
val rate = ExchangeRequest.GetRate(mCard!!.wallet, "bitcoin-cash", "bitcoin-cash")
taskRate.execute(rate)
} else if (mCard!!.blockchain == Blockchain.Ethereum || mCard!!.blockchain == Blockchain.EthereumTestNet) {
val updateETH = ETHRequestTask(this@LoadedWallet, mCard!!.blockchain)
val reqETH = InfuraRequest.GetBalance(mCard!!.wallet)
reqETH.id = 67
reqETH.setBlockchain(mCard!!.blockchain)
val reqNonce = InfuraRequest.GetOutTransactionCount(mCard!!.wallet)
reqNonce.id = 67
reqNonce.setBlockchain(mCard!!.blockchain)
updateETH.execute(reqETH, reqNonce)
val taskRate = RateInfoTask(this@LoadedWallet)
val rate = ExchangeRequest.GetRate(mCard!!.wallet, "ethereum", "ethereum")
taskRate.execute(rate)
} else if (mCard!!.blockchain == Blockchain.Token) {
val updateETH = ETHRequestTask(this@LoadedWallet, mCard!!.blockchain)
val reqETH = InfuraRequest.GetTokenBalance(mCard!!.wallet, engine!!.GetContractAddress(mCard), engine.GetTokenDecimals(mCard))
reqETH.id = 67
reqETH.setBlockchain(mCard!!.blockchain)
val reqBalance = InfuraRequest.GetBalance(mCard!!.wallet)
reqBalance.id = 67
reqBalance.setBlockchain(mCard!!.blockchain)
val reqNonce = InfuraRequest.GetOutTransactionCount(mCard!!.wallet)
reqNonce.id = 67
reqNonce.setBlockchain(mCard!!.blockchain)
updateETH.execute(reqETH, reqNonce, reqBalance)
val taskRate = RateInfoTask(this@LoadedWallet)
val rate = ExchangeRequest.GetRate(mCard!!.wallet, "ethereum", "ethereum")
taskRate.execute(rate)
}
if (needResendTX)
sendTransaction(LastSignStorage.getTxForSend(mCard!!.wallet))
}
override fun onTagDiscovered(tag: Tag) {
startVerify(tag)
}
fun prepareResultIntent(): Intent {
val data = Intent()
data.putExtra("UID", mCard!!.uid)
data.putExtra("Card", mCard!!.asBundle)
return data
}
override fun OnReadStart(cardProtocol: CardProtocol) {
rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
}
override fun OnReadFinish(cardProtocol: CardProtocol?) {
verifyCardTask = null
if (cardProtocol != null) {
if (cardProtocol.error == null) {
rlProgressBar.post {
rlProgressBar.visibility = View.GONE
mCardProtocol = cardProtocol
refresh()
}
} else {
// remove last UIDs because of error and no card read
rlProgressBar.post {
lastReadSuccess = false
if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
if (!NoExtendedLengthSupportDialog.allreadyShowed)
NoExtendedLengthSupportDialog().show(activity!!.fragmentManager, NoExtendedLengthSupportDialog.TAG)
else
Toast.makeText(context, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
}
}
}
rlProgressBar.postDelayed({
try {
rlProgressBar.visibility = View.GONE
} catch (e: Exception) {
e.printStackTrace()
}
}, 500)
}
override fun OnReadProgress(protocol: CardProtocol, progress: Int) {
}
override fun OnReadCancel() {
verifyCardTask = null
rlProgressBar.postDelayed({
try {
rlProgressBar.visibility = View.GONE
} catch (e: Exception) {
e.printStackTrace()
}
}, 500)
}
override fun OnReadWait(msec: Int) {
WaitSecurityDelayDialog.OnReadWait(activity!!, msec)
}
override fun OnReadBeforeRequest(timeout: Int) {
WaitSecurityDelayDialog.onReadBeforeRequest(activity!!, timeout)
}
override fun OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(activity!!)
}
fun updateViews() {
try {
if (timerHideErrorAndMessage != null) {
timerHideErrorAndMessage!!.cancel()
timerHideErrorAndMessage = null
}
tvCardID.text = mCard!!.cidDescription
if (mCard!!.error == null || mCard!!.error.isEmpty()) {
tvError.visibility = View.GONE
tvError.text = ""
} else {
tvError.visibility = View.VISIBLE
tvError.text = mCard!!.error
}
val needResendTX = LastSignStorage.getNeedTxSend(mCard!!.wallet)
if ((mCard!!.message == null || mCard!!.message.isEmpty()) && !needResendTX) {
tvMessage!!.text = ""
tvMessage!!.visibility = View.GONE
} else {
if (needResendTX) {
} else {
tvMessage!!.text = mCard!!.message
}
tvMessage!!.visibility = View.VISIBLE
}
val engine = CoinEngineFactory.Create(mCard!!.blockchain)
if (mCard!!.blockchain == Blockchain.Bitcoin || mCard!!.blockchain == Blockchain.BitcoinTestNet) {
val validator = BalanceValidator()
validator.Check(mCard)
tvBalanceLine1.text = validator.GetFirstLine()
tvBalanceLine2.text = validator.GetSecondLine()
tvBalanceLine1.setTextColor(ContextCompat.getColor(context!!, validator.GetColor()))
}
if (engine!!.HasBalanceInfo(mCard) || mCard!!.offlineBalance == null) {
if (mCard!!.blockchain == Blockchain.Token) {
val html = Html.fromHtml(engine.GetBalanceWithAlter(mCard))
tvBalance.text = html
} else {
tvBalance.text = engine.GetBalanceWithAlter(mCard)
}
tvBalanceEquivalent.text = engine.GetBalanceEquivalent(mCard)
tvOffline.visibility = View.INVISIBLE
} else {
val offlineAmount = engine.ConvertByteArrayToAmount(mCard, mCard!!.offlineBalance)
if (mCard!!.blockchain == Blockchain.Token) {
tvBalance.setText(R.string.not_implemented)
} else {
tvBalance.text = engine.GetAmountDescription(mCard, offlineAmount)
}
tvBalanceEquivalent.text = engine.GetAmountEqualentDescriptor(mCard, offlineAmount)
tvOffline.visibility = View.VISIBLE
}
if (!mCard!!.amountEquivalentDescriptionAvailable) {
} else {
tvBalanceEquivalent.error = null
}
tvWallet.text = mCard!!.wallet
tvInputs.text = mCard!!.inputsDescription
when {
mCard!!.lastInputDescription.contains("awaiting") -> tvInputs.setTextColor(ContextCompat.getColor(context!!, R.color.not_confirmed))
mCard!!.lastInputDescription.contains("None") -> tvInputs.setTextColor(ContextCompat.getColor(context!!, R.color.primary_dark))
else -> tvInputs.setTextColor(ContextCompat.getColor(context!!, R.color.confirmed))
}
tvBlockchain.text = mCard!!.blockchainName
tvValidationNode.text = mCard!!.validationNodeDescription
if (mCard!!.useDefaultPIN1()!!) {
ivPIN.setImageResource(R.drawable.unlock_pin1)
ivPIN.setOnClickListener { v -> Toast.makeText(context, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
} else {
ivPIN!!.setImageResource(R.drawable.lock_pin1)
ivPIN!!.setOnClickListener { v -> Toast.makeText(context, R.string.this_banknote_protected_user_PIN1_code, Toast.LENGTH_LONG).show() }
}
if (mCard!!.pauseBeforePIN2 > 0 && (mCard!!.useDefaultPIN2()!! || !mCard!!.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer)
ivPIN2orSecurityDelay.setOnClickListener { v -> Toast.makeText(context, String.format("This banknote will enforce %.0f seconds security delay for all operations requiring PIN2 code", mCard!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
} else if (mCard!!.useDefaultPIN2()!!) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2)
ivPIN2orSecurityDelay.setOnClickListener { v -> Toast.makeText(context, R.string.this_banknote_protected_default_PIN2_code, Toast.LENGTH_LONG).show() }
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2)
ivPIN2orSecurityDelay.setOnClickListener { v -> Toast.makeText(context, R.string.this_banknote_protected_user_PIN2_code, Toast.LENGTH_LONG).show() }
}
if (mCard!!.useDevelopersFirmware()!!) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version)
ivDeveloperVersion.visibility = View.VISIBLE
ivDeveloperVersion.setOnClickListener { v -> Toast.makeText(context, R.string.unlocked_banknote_only_development_use, Toast.LENGTH_LONG).show() }
} else
ivDeveloperVersion.visibility = View.INVISIBLE
btnExtract!!.isEnabled = mCard!!.hasBalanceInfo()
tvIssuer.text = mCard!!.issuerDescription
timerHideErrorAndMessage = Timer()
timerHideErrorAndMessage!!.schedule(object : TimerTask() {
override fun run() {
tvError.post {
tvMessage!!.visibility = View.GONE
tvError.visibility = View.GONE
mCard!!.error = null
mCard!!.message = null
}
}
}, 5000)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun openVerifyCard(cardProtocol: CardProtocol) {
val intent = Intent(context, VerifyCardActivity::class.java)
intent.putExtra("UID", cardProtocol.card.uid)
intent.putExtra("Card", cardProtocol.card.asBundle)
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD)
}
private fun startVerify(tag: Tag?) {
try {
val isoDep = IsoDep.get(tag)
?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
val UID = tag!!.id
val sUID = Util.byteArrayToHexString(UID)
if (mCard!!.uid != sUID) {
Log.d(TAG, "Invalid UID: $sUID")
mNfcManager!!.ignoreTag(isoDep.tag)
return
} else {
Log.v(TAG, "UID: $sUID")
}
if (lastReadSuccess) {
isoDep.timeout = 1000
} else {
isoDep.timeout = 65000
}
verifyCardTask = VerifyCardTask(context, mCard, mNfcManager, isoDep, this)
verifyCardTask!!.start()
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun doShareWallet(useURI: Boolean) {
if (useURI) {
val txtShare = CoinEngineFactory.Create(mCard!!.blockchain)!!.getShareWalletURI(mCard).toString()
val intent = Intent(Intent.ACTION_SEND)
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_SUBJECT, "Wallet address")
intent.putExtra(Intent.EXTRA_TEXT, txtShare)
val packageManager = activity!!.packageManager
val activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
val isIntentSafe = activities.size > 0
if (isIntentSafe) {
val title = getString(R.string.share_wallet_address_with)
// create intent to show chooser
val chooser = Intent.createChooser(intent, title)
// verify the intent will resolve to at least one activity
if (intent.resolveActivity(activity!!.packageManager) != null) {
startActivity(chooser)
}
} else {
val clipboard = activity!!.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboard.primaryClip = ClipData.newPlainText(txtShare, txtShare)
Toast.makeText(context, R.string.copied_clipboard, Toast.LENGTH_LONG).show()
}
} else {
val txtShare = mCard!!.wallet
val clipboard = activity!!.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboard.primaryClip = ClipData.newPlainText(txtShare, txtShare)
Toast.makeText(context, R.string.copied_clipboard, Toast.LENGTH_LONG).show()
}
}
private fun sendTransaction(tx: String) {
val engine = CoinEngineFactory.Create(mCard!!.blockchain)
if (mCard!!.blockchain == Blockchain.Ethereum || mCard!!.blockchain == Blockchain.EthereumTestNet || mCard!!.blockchain == Blockchain.Token) {
val task = ETHRequestTask(this@LoadedWallet, mCard!!.blockchain)
val req = InfuraRequest.SendTransaction(mCard!!.wallet, tx)
req.id = 67
req.setBlockchain(mCard!!.blockchain)
task.execute(req)
} else if (mCard!!.blockchain == Blockchain.Bitcoin || mCard!!.blockchain == Blockchain.BitcoinTestNet) {
val nodeAddress = engine!!.GetNode(mCard)
val nodePort = engine.GetNodePort(mCard)
val connectTask = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort)
connectTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.Broadcast(mCard!!.wallet, tx))
} else if (mCard!!.blockchain == Blockchain.BitcoinCash || mCard!!.blockchain == Blockchain.BitcoinCashTestNet) {
val nodeAddress = engine!!.GetNode(mCard)
val nodePort = engine.GetNodePort(mCard)
val connectTask = UpdateWalletInfoTask(this@LoadedWallet, nodeAddress, nodePort)
connectTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.Broadcast(mCard!!.wallet, tx))
}
}
private fun startSwapPINActivity() {
val intent = Intent(context, SwapPINActivity::class.java)
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
intent.putExtra("newPIN", newPIN)
intent.putExtra("newPIN2", newPIN2)
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN)
}
}

View file

@ -36,6 +36,7 @@
android:gravity="center"
android:orientation="vertical">
<!--not used-->
<TextView
android:id="@+id/tvCaution"
android:layout_width="match_parent"
@ -59,8 +60,7 @@
android:id="@+id/ivTangemCard"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_weight="1"
tools:src="@drawable/card_default" />
tools:src="@drawable/card_default"/>
<RelativeLayout
android:id="@+id/rlProgressBar"
@ -75,7 +75,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.75"
android:background="@color/white" />
android:background="@color/white"/>
<TextView
android:layout_width="wrap_content"
@ -84,7 +84,7 @@
android:alpha="0.8"
android:text="@string/verifying"
android:textColor="@color/colorPrimary"
android:textStyle="bold" />
android:textStyle="bold"/>
<ProgressBar
android:layout_width="@dimen/size_progress_bar_big"
@ -92,7 +92,7 @@
android:layout_centerInParent="true"
android:alpha="0.8"
android:elevation="1dp"
android:progressTint="@color/colorPrimary" />
android:progressTint="@color/colorPrimary"/>
</RelativeLayout>
</RelativeLayout>
@ -120,7 +120,7 @@
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="@dimen/text_size_large"
tools:text="0.05 BTC" />
tools:text="0.05 BTC"/>
<TextView
android:id="@+id/tvBlockchain"
@ -132,7 +132,8 @@
android:paddingRight="10dp"
android:textColor="@color/primary"
android:textStyle="normal|bold"
tools:text="Bitcoin" />
tools:text="Bitcoin"/>
</LinearLayout>
<TextView
@ -143,7 +144,7 @@
android:fontFamily="@font/montserrat_light"
android:textAlignment="center"
android:textColor="@android:color/holo_orange_dark"
android:textSize="18sp" />
android:textSize="18sp"/>
<TextView
android:id="@+id/tvBalanceLine2"
@ -151,10 +152,11 @@
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:fontFamily="@font/montserrat_light"
android:textAlignment="center" />
android:textAlignment="center"/>
</LinearLayout>
<!--not used-->
<TextView
android:id="@+id/tvHeader"
android:layout_width="match_parent"
@ -265,7 +267,7 @@
android:paddingRight="8dp">
<ImageView
android:id="@+id/qrWallet"
android:id="@+id/ivQR"
android:layout_width="@dimen/size_qr_image"
android:layout_height="@dimen/size_qr_image"/>
@ -287,7 +289,7 @@
tools:text="1DoQdnSYshhZ5Tqt5Sk6svZt29jqoYVwQY"/>
<ImageView
android:id="@+id/imgLookup"
android:id="@+id/ivLookup"
android:layout_width="@dimen/size_explore_image"
android:layout_height="@dimen/size_explore_image"
android:layout_marginTop="15dp"
@ -429,7 +431,7 @@
android:textAlignment="center"
android:textColor="@color/black"
android:textStyle="normal|bold"
android:visibility="gone" />
android:visibility="gone"/>
<TextView
android:id="@+id/tvError"
@ -446,7 +448,7 @@
android:textAlignment="center"
android:textColor="@color/white"
android:textStyle="bold"
android:visibility="gone" />
android:visibility="gone"/>
</RelativeLayout>
@ -467,7 +469,7 @@
android:layout_width="wrap_content"
android:layout_margin="10dp"
android:elevation="15dp"
android:text="@string/load" />
android:text="@string/load"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabInfo"
@ -476,17 +478,16 @@
android:layout_margin="10dp"
android:layout_marginEnd="5dp"
app:fabSize="mini"
app:srcCompat="@drawable/ic_information_variant_white_24dp" />
app:srcCompat="@drawable/ic_information_variant_white_24dp"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabNFC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginStart="5dp"
app:fabSize="mini"
app:srcCompat="@drawable/ic_nfc_white_24dp" />
app:srcCompat="@drawable/ic_nfc_white_24dp"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btnExtract"
@ -494,10 +495,11 @@
android:layout_width="wrap_content"
android:layout_margin="10dp"
android:width="100dp"
android:text="@string/extract" />
android:text="@string/extract"/>
</LinearLayout>
<!--not used-->
<RelativeLayout
android:id="@+id/rlCardIdAndIcons"
android:layout_width="match_parent"
@ -506,19 +508,19 @@
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:id="@+id/imgPIN"
android:id="@+id/ivPIN"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="false"
android:layout_marginBottom="8dp"
android:layout_marginStart="4dp"
android:layout_toStartOf="@+id/imgPIN2orSecurityDelay"
android:layout_toStartOf="@+id/ivPIN2orSecurityDelay"
android:elevation="0dp"
android:src="@drawable/unlock_pin1"/>
<ImageView
android:id="@+id/imgPIN2orSecurityDelay"
android:id="@+id/ivPIN2orSecurityDelay"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
@ -530,7 +532,7 @@
android:src="@drawable/unlock_pin2"/>
<ImageView
android:id="@+id/imgDeveloperVersion"
android:id="@+id/ivDeveloperVersion"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
@ -570,8 +572,8 @@
</RelativeLayout>
<!--<include-->
<!--layout="@layout/layout_progress_horizontal"-->
<!--android:visibility="gone"-->
<!--tools:layout_editor_absoluteY="495dp" />-->
<!--layout="@layout/layout_progress_horizontal"-->
<!--android:visibility="gone"-->
<!--tools:layout_editor_absoluteY="495dp" />-->
</android.support.constraint.ConstraintLayout>