Updated on 2026-08-14

This commit is contained in:
Tangem 2018-05-29 16:11:22 +03:00
parent 8c17a8d4f0
commit b19c306250
70 changed files with 6149 additions and 6206 deletions

View file

@ -6,49 +6,18 @@ package com.tangem.wallet;
import android.util.Log;
import com.tangem.cardReader.Util;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1Integer;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERSequenceGenerator;
import org.spongycastle.asn1.sec.SECNamedCurves;
import org.spongycastle.asn1.x9.X9ECParameters;
import org.spongycastle.asn1.x9.X9IntegerConverter;
import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
import org.spongycastle.crypto.params.ECPublicKeyParameters;
import org.spongycastle.crypto.signers.ECDSASigner;
import org.spongycastle.jce.ECNamedCurveTable;
import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
import org.spongycastle.jce.spec.ECPrivateKeySpec;
import org.spongycastle.jce.spec.ECPublicKeySpec;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
import com.tangem.domain.cardReader.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.text.Format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;
import static org.bitcoinj.core.ECKey.CURVE;
import static org.bitcoinj.core.ECKey.HALF_CURVE_ORDER;
@SuppressWarnings({"WeakerAccess", "TryWithIdenticalCatches", "unused"})
public final class BTCUtils {

View file

@ -1,19 +1,6 @@
package com.tangem.wallet;
import android.net.Uri;
import com.google.common.base.Strings;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.Util;
import org.bitcoinj.core.Base58;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by dvol on 06.08.2017.

View file

@ -2,9 +2,9 @@ package com.tangem.wallet;
import android.net.Uri;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.TLV;
import com.tangem.cardReader.Util;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.TLV;
import com.tangem.domain.cardReader.Util;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;

View file

@ -2,9 +2,9 @@ package com.tangem.wallet;
import android.net.Uri;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.TLV;
import com.tangem.cardReader.Util;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.TLV;
import com.tangem.domain.cardReader.Util;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;

View file

@ -1,599 +0,0 @@
package com.tangem.wallet;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.tangem.wallet.Tangem_Card.CountOurTx;
public class CardListAdapter extends RecyclerView.Adapter<CardListAdapter.CardViewHolder> {
public static class CardViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView tvBalance, tvOffline, tvBalanceEquivalent, tvWallet, tvInputs, tvStatusInBlockchain, tvCardID, tvLastInput, lbLastInput, lbLastOutput, tvLastOutput, tvBlockchain;
TextView tvType, tvTypeBg, tvVoid;
ImageView imgBlockchain, imgSecurityNotification;
View llCardLoaded, llCardEmpty, llCardError, llCardPurged;
CardViewHolder(View itemView) {
super(itemView);
cv = itemView.findViewById(R.id.cvCard);
tvBalance = itemView.findViewById(R.id.tvBalance);
tvOffline = itemView.findViewById(R.id.tvOffline);
tvBalanceEquivalent = itemView.findViewById(R.id.tvBalanceEquivalent);
tvWallet = itemView.findViewById(R.id.tvWallet);
tvCardID = itemView.findViewById(R.id.tvCardID);
tvType = itemView.findViewById(R.id.tvType);
tvTypeBg = itemView.findViewById(R.id.tvTypeBg);
tvVoid = itemView.findViewById(R.id.tvVoid);
if (tvCardID != null) {
tvCardID.requestFocus();
}
tvInputs = itemView.findViewById(R.id.tvInputs);
tvLastInput = itemView.findViewById(R.id.tvLastInput);
lbLastInput = itemView.findViewById(R.id.lbLastInput);
lbLastOutput = itemView.findViewById(R.id.lbLastOutput);
tvLastOutput = itemView.findViewById(R.id.tvLastOutput);
tvBlockchain = itemView.findViewById(R.id.tvBlockchain);
imgBlockchain = itemView.findViewById(R.id.imgBlockchain);
llCardLoaded = itemView.findViewById(R.id.cardLoaded);
llCardEmpty = itemView.findViewById(R.id.cardEmpty);
llCardError = itemView.findViewById(R.id.cardError);
llCardPurged = itemView.findViewById(R.id.cardPurged);
imgSecurityNotification = itemView.findViewById(R.id.imgSecurityNotification);
}
}
public interface UiCallbacks {
void onViewCard(Bundle cardInfo);
}
private LayoutInflater mLayoutInflater;
private Context mContext;
private UiCallbacks mUiCallbacks;
private List<Tangem_Card> mCards = new ArrayList<>(100);
public CardListAdapter(LayoutInflater layoutInflater, Bundle instate, UiCallbacks uiCallbacks) {
mLayoutInflater = layoutInflater;
mContext = layoutInflater.getContext();
mUiCallbacks = uiCallbacks;
if (instate != null) {
// restore state
ArrayList<String> UIDs = instate.getStringArrayList("card_UID");
if( UIDs!=null ) {
for (String UID : UIDs) {
Tangem_Card card = new Tangem_Card(UID);
card.LoadFromBundle(instate.getBundle(String.format("card_%s", UID)));
mCards.add(card);
}
}
}
}
public void onSaveInstanceState(Bundle outstate) {
ArrayList<String> UIDs = new ArrayList<String>(mCards.size());
for (Tangem_Card card : mCards) {
Bundle B = new Bundle();
card.SaveToBundle(B);
outstate.putBundle(String.format("card_%s", card.getUID()), B);
UIDs.add(card.getUID());
}
outstate.putStringArrayList("card_UID", UIDs);
}
public void clearCards() {
mCards.clear();
notifyDataSetChanged();
}
public Tangem_Card getCard(int cardIndex) {
return mCards.get(cardIndex);
}
public Tangem_Card getCardByWallet(String walletAddress) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
return c;
}
}
return null;
}
public void addCard(Tangem_Card card) {
mCards.add(0,card);
notifyDataSetChanged();
}
public void removeCard(int cardIndex) {
mCards.remove(cardIndex);
notifyItemRemoved(cardIndex);
}
public void removeCard(Tangem_Card card) {
int i;
for (i = 0; i < mCards.size(); i++) {
if (Arrays.equals(mCards.get(i).getCID(), card.getCID())) {
break;
}
}
if (i == mCards.size()) return;
removeCard(i);
}
public void updateCard(Tangem_Card card) {
int i;
for (i = 0; i < mCards.size(); i++) {
if (Arrays.equals(mCards.get(i).getCID(), card.getCID())) {
break;
}
}
if (i == mCards.size()) {
mCards.add(card);
} else {
mCards.remove(i);
mCards.add(i, card);
}
notifyDataSetChanged();
}
public void UpdateWalletBalance(String walletAddress, Long balanceConfirmed, Long balanceUnconfirmed, String validationNodeDescription) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setBalanceConfirmed(balanceConfirmed);
c.setBalanceUnconfirmed(balanceUnconfirmed);
c.setDecimalBalance(String.valueOf(balanceConfirmed));
c.setValidationNodeDescription(validationNodeDescription);
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletCoutConfirmTx(String walletAddress, BigInteger nonce) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.SetConfirmTXCount(nonce);
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletBlockchain(String walletAddress, Blockchain blockchain) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setBlockchainID(blockchain.getID());
notifyDataSetChanged();
return;
}
}
}
public void AddWalletBlockchainNameToken(String walletAddress) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.addTokenToBlockchainName();
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletBalance(String walletAddress, Long balanceConfirmed, String balanceString, String validationNodeDescription) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setBalanceConfirmed(balanceConfirmed);
c.setBalanceUnconfirmed(0L);
c.setDecimalBalance(String.valueOf(balanceString));
c.setValidationNodeDescription(validationNodeDescription);
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletBalanceOnlyAlter(String walletAddress, String balanceAlter) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setDecimalBalanceAlter(balanceAlter);
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletUnspent(String walletAddress, JSONArray jsUnspentArray) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
try {
c.getUnspentTransactions().clear();
for (int i = 0; i < jsUnspentArray.length(); i++) {
JSONObject jsUnspent = jsUnspentArray.getJSONObject(i);
Tangem_Card.UnspentTransaction trUnspent = new Tangem_Card.UnspentTransaction();
trUnspent.txID = jsUnspent.getString("tx_hash");
trUnspent.Amount = jsUnspent.getInt("value");
trUnspent.Height = jsUnspent.getInt("height");
c.getUnspentTransactions().add(trUnspent);
}
} catch (JSONException e) {
e.printStackTrace();
}
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletHistory(String walletAddress, JSONArray jsHistoryArray) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
try {
c.getHistoryTransactions().clear();
for (int i = 0; i < jsHistoryArray.length(); i++) {
JSONObject jsUnspent = jsHistoryArray.getJSONObject(i);
Tangem_Card.HistoryTransaction trHistory = new Tangem_Card.HistoryTransaction();
trHistory.txID = jsUnspent.getString("tx_hash");
trHistory.Height = jsUnspent.getInt("height");
c.getHistoryTransactions().add(trHistory);
}
} catch (JSONException e) {
e.printStackTrace();
}
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletHeader(String walletAddress, JSONObject jsHeader) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
try {
c.getHaedersInfo();
c.UpdateHeaderInfo(new Tangem_Card.HeaderInfo(
jsHeader.getInt("block_height"),
jsHeader.getInt("timestamp")));
} catch (JSONException e) {
e.printStackTrace();
}
notifyDataSetChanged();
return;
}
}
}
public void UpdateRate(String walletAddress, float rate) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setRate(rate);
notifyDataSetChanged();
break;
}
}
}
public void UpdateRateAlter(String walletAddress, float rate) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setRateAlter(rate);
notifyDataSetChanged();
break;
}
}
}
public void UpdateTransaction(String walletAddress, String txHash, String raw) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
List<Tangem_Card.UnspentTransaction> listTx = c.getUnspentTransactions();
for (Tangem_Card.UnspentTransaction tx : listTx) {
if (tx.txID.equals(txHash)) {
tx.Raw = raw;
}
}
List<Tangem_Card.HistoryTransaction> listHTx = c.getHistoryTransactions();
for (Tangem_Card.HistoryTransaction tx : listHTx) {
if (tx.txID.equals(txHash)) {
tx.Raw = raw;
CountOurTx(listHTx);
}
}
notifyDataSetChanged();
return;
}
}
}
public void UpdateWalletError(String walletAddress, String error) {
for (Tangem_Card c : mCards) {
if (c.getWallet().equals(walletAddress)) {
c.setError(error);
notifyDataSetChanged();
return;
}
}
}
@Override
public int getItemCount() {
return mCards == null ? 0 : mCards.size();
}
@Override
public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_list_item, parent, false);
CardViewHolder cvh = new CardViewHolder(v);
return cvh;
}
@Override
public void onBindViewHolder(CardViewHolder holder, int position) {
try {
Tangem_Card card = mCards.get(position);
CoinEngine engine = CoinEngineFactory.Create(card.getBlockchain());
int color = android.R.color.black;
switch (card.getStatus()) {
case NotPersonalized:
color = R.color.card_state_error;
holder.llCardError.setVisibility(View.VISIBLE);
holder.llCardLoaded.setVisibility(View.GONE);
holder.llCardEmpty.setVisibility(View.GONE);
holder.llCardPurged.setVisibility(View.GONE);
holder.imgBlockchain.setVisibility(View.INVISIBLE);
holder.imgSecurityNotification.setVisibility(View.INVISIBLE);
holder.tvCardID.setVisibility(View.INVISIBLE);
holder.tvCardID.setError(null);
holder.tvType.setVisibility(View.INVISIBLE);
holder.tvTypeBg.setVisibility(View.INVISIBLE);
holder.tvVoid.setVisibility(View.INVISIBLE);
break;
case Empty:
color = R.color.card_state_empty;
holder.llCardEmpty.setVisibility(View.VISIBLE);
holder.llCardLoaded.setVisibility(View.GONE);
holder.llCardError.setVisibility(View.GONE);
holder.llCardPurged.setVisibility(View.GONE);
holder.imgBlockchain.setVisibility(View.VISIBLE);
if (card.getBlockchain() != null) {
holder.imgBlockchain.setImageResource(card.getBlockchain().getImageResource(this.mContext, card.getTokenSymbol()));
holder.imgBlockchain.setVisibility(View.VISIBLE);
} else {
holder.imgBlockchain.setVisibility(View.INVISIBLE);
}
if (card.useDefaultPIN1() || card.useDefaultPIN2() || card.getPauseBeforePIN2() > 0 || card.useDevelopersFirmware()) {
//holder.imgSecurityNotification.setVisibility(View.VISIBLE);
} else {
holder.imgSecurityNotification.setVisibility(View.INVISIBLE);
}
holder.tvCardID.setText(card.getCIDDescription());
holder.tvCardID.setError(null);
holder.tvCardID.setVisibility(View.VISIBLE);
holder.tvType.setVisibility(View.VISIBLE);
holder.tvTypeBg.setVisibility(View.VISIBLE);
if( card.isReusable() ) {
holder.tvType.setText(" REUSABLE REUSABLE ");
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.type_wallet, mContext.getTheme()));
}else{
holder.tvType.setText(" BANKNOTE BANKNOTE");
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.type_banknote, mContext.getTheme()));
}
holder.tvVoid.setVisibility(View.INVISIBLE);
break;
case Purged:
color = R.color.card_state_purged;
holder.llCardEmpty.setVisibility(View.GONE);
holder.llCardLoaded.setVisibility(View.GONE);
holder.llCardError.setVisibility(View.GONE);
holder.llCardPurged.setVisibility(View.VISIBLE);
holder.imgBlockchain.setVisibility(View.VISIBLE);
if (card.getBlockchain() != null) {
holder.imgBlockchain.setImageResource(card.getBlockchain().getImageResource(this.mContext, card.getTokenSymbol()));
holder.imgBlockchain.setVisibility(View.VISIBLE);
} else {
holder.imgBlockchain.setVisibility(View.INVISIBLE);
}
holder.imgSecurityNotification.setVisibility(View.INVISIBLE);
holder.tvCardID.setText(card.getCIDDescription());
holder.tvCardID.setVisibility(View.VISIBLE);
holder.tvCardID.setError(null);
holder.tvType.setVisibility(View.VISIBLE);
holder.tvTypeBg.setVisibility(View.VISIBLE);
holder.tvType.setText(" BANKNOTE BANKNOTE");
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.type_banknote, mContext.getTheme()));
holder.tvVoid.setVisibility(View.INVISIBLE);
break;
case Loaded:
holder.llCardLoaded.setVisibility(View.VISIBLE);
holder.llCardError.setVisibility(View.GONE);
holder.llCardEmpty.setVisibility(View.GONE);
holder.llCardPurged.setVisibility(View.GONE);
holder.tvCardID.setText(card.getCIDDescription());
holder.tvCardID.setVisibility(View.VISIBLE);
holder.tvWallet.setText(card.getShortWalletString());
holder.tvBlockchain.setText(card.getBlockchainName());
if (card.getBlockchain() != null) {
holder.imgBlockchain.setImageResource(card.getBlockchain().getImageResource(this.mContext, card.getTokenSymbol()));
holder.imgBlockchain.setVisibility(View.VISIBLE);
} else {
holder.imgBlockchain.setVisibility(View.INVISIBLE);
}
if (!engine.HasBalanceInfo(card)) {
color = R.color.card_state_loaded;
} else if (engine.IsBalanceNotZero(card)) {
color = R.color.card_state_loaded_with_coins;
} else {
color = R.color.card_state_loaded_with_zero;
}
if (holder.tvStatusInBlockchain != null) {
if (card.hasBalanceInfo() && card.hasUnspentInfo() && card.getUnspentTransactions().size() > 0) {
holder.tvStatusInBlockchain.setText("Ok");
holder.tvStatusInBlockchain.setTextColor(mContext.getResources().getColor(R.color.confirmed, mContext.getTheme()));
} else if (!card.hasBalanceInfo() || !card.hasUnspentInfo()) {
holder.tvStatusInBlockchain.setText("-- -- --");
holder.tvStatusInBlockchain.setTextColor(mContext.getResources().getColor(R.color.primary_dark, mContext.getTheme()));
} else {
holder.tvStatusInBlockchain.setText("Not found");
holder.tvStatusInBlockchain.setTextColor(mContext.getResources().getColor(R.color.not_confirmed, mContext.getTheme()));
}
}
if ( engine.HasBalanceInfo(card) || card.getOfflineBalance() == null) {
String balance = engine.GetBalance(card);
holder.tvBalance.setText(balance);
holder.tvBalanceEquivalent.setText(engine.GetBalanceEquivalent(card));
holder.tvBalance.setTextColor(Color.BLACK);
holder.tvOffline.setVisibility(View.INVISIBLE);
} else {
String offlineAmount = engine.ConvertByteArrayToAmount(card, card.getOfflineBalance());
holder.tvBalance.setText(engine.GetAmountDescription(card, offlineAmount));
holder.tvBalanceEquivalent.setText(engine.GetAmountEqualentDescriptor(card, offlineAmount));
holder.tvOffline.setVisibility(View.VISIBLE);
}
if (!card.getAmountEquivalentDescriptionAvailable()) {
//holder.tvBalanceEquivalent.setError("Service unavailable");
} else {
holder.tvBalanceEquivalent.setError(null);
}
String error = card.getError();
//holder.tvCardID.setError(error);
if (holder.tvInputs != null) {
holder.tvInputs.setText(card.getInputsDescription());
}
boolean visibleFlag = engine != null ? engine.InOutPutVisible() : true;
int visibleIOPuts = visibleFlag ? View.VISIBLE : View.GONE;
if (holder.tvLastInput != null) {
holder.tvLastInput.setText(card.getLastInputDescription());
if (card.getLastInputDescription().contains("awaiting")) {
holder.tvLastInput.setTextColor(mContext.getResources().getColor(R.color.not_confirmed, mContext.getTheme()));
} else if (card.getLastInputDescription().contains("None") || card.getLastInputDescription().contains("--")) {
holder.tvLastInput.setTextColor(mContext.getResources().getColor(R.color.primary_dark, mContext.getTheme()));
} else {
holder.tvLastInput.setTextColor(mContext.getResources().getColor(R.color.confirmed, mContext.getTheme()));
}
holder.tvLastInput.setVisibility(visibleIOPuts);
}
if (holder.lbLastInput != null) {
holder.lbLastInput.setVisibility(visibleIOPuts);
}
if (holder.tvLastOutput != null) {
holder.tvLastOutput.setText(card.getLastOutputDescription());
holder.tvLastOutput.setVisibility(visibleIOPuts);
}
if (holder.lbLastOutput != null) {
holder.lbLastOutput.setVisibility(visibleIOPuts);
}
if (card.useDefaultPIN1() || card.useDefaultPIN2() || card.getPauseBeforePIN2() > 0 || card.useDevelopersFirmware()) {
//holder.imgSecurityNotification.setVisibility(View.VISIBLE);
} else {
holder.imgSecurityNotification.setVisibility(View.INVISIBLE);
}
holder.tvType.setVisibility(View.VISIBLE);
holder.tvTypeBg.setVisibility(View.VISIBLE);
if( card.isReusable() ) {
holder.tvType.setText(" REUSABLE REUSABLE ");
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.type_wallet, mContext.getTheme()));
holder.tvVoid.setVisibility(View.INVISIBLE);
}else{
holder.tvType.setText(" BANKNOTE BANKNOTE");
if( card.getRemainingSignatures()!=card.getMaxSignatures() ) {
holder.tvVoid.setVisibility(View.VISIBLE);
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.msg_err, mContext.getTheme()));
}else{
holder.tvVoid.setVisibility(View.INVISIBLE);
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.type_banknote, mContext.getTheme()));
}
}
break;
}
if(card.useDevelopersFirmware()) {
holder.tvType.setText(" DEVELOPER KIT ");
holder.tvTypeBg.setBackgroundColor(mContext.getResources().getColor(R.color.fab, mContext.getTheme()));
holder.tvVoid.setVisibility(View.INVISIBLE);
}
holder.cv.setOnClickListener(new CardClickListener(position));
holder.cv.setCardBackgroundColor(mContext.getResources().getColor(color));
} catch (Exception e) {
Log.e("onBindViewHolder", e.toString());
}
}
private class CardClickListener implements View.OnClickListener {
Tangem_Card card;
int pos;
CardClickListener(int position) {
card = mCards.get(position);
pos=position;
}
@Override
public void onClick(View v) {
Bundle b = new Bundle();
b.putString("UID", card.getUID());
Bundle bCard = new Bundle();
card.SaveToBundle(bCard);
b.putBundle("Card", bCard);
mUiCallbacks.onViewCard(b);
}
}
}

View file

@ -1,83 +0,0 @@
package com.tangem.wallet;
import android.content.Context;
import android.os.Build;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import static android.text.Html.FROM_HTML_MODE_COMPACT;
/**
* Created by dvol on 17.07.2017.
*/
public class CardUnspentListAdapter extends BaseAdapter {
private LayoutInflater mLayoutInflater;
private Context mContext;
private Tangem_Card mCard;
public CardUnspentListAdapter(LayoutInflater layoutInflater, Tangem_Card card) {
mLayoutInflater = layoutInflater;
mContext = layoutInflater.getContext();
mCard = card;
}
@Override
public int getCount() {
if (mCard != null && mCard.getUnspentTransactions() != null)
return mCard.getUnspentTransactions().size();
return 0;
}
@Override
public Object getItem(int i) {
if (mCard != null && mCard.getUnspentTransactions() != null)
return mCard.getUnspentTransactions().get(i);
return null;
}
@Override
public long getItemId(int i) {
if (mCard != null && mCard.getUnspentTransactions() != null)
return mCard.getUnspentTransactions().get(i).txID.hashCode();
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.card_unspent_list_item, viewGroup,
false);
}
TextView tvItem = (TextView) convertView.findViewById(R.id.tvItem);
Tangem_Card.UnspentTransaction unspentTransaction = (Tangem_Card.UnspentTransaction) getItem(position);
String html=String.format("<b>%d mBTC</b><br>%s", unspentTransaction.Amount, unspentTransaction.txID);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tvItem.setText(Html.fromHtml(html, FROM_HTML_MODE_COMPACT));
} else {
tvItem.setText(Html.fromHtml(html.toString()));
}
return convertView;
}
public void Clear() {
mCard.getUnspentTransactions().clear();
notifyDataSetChanged();
}
public void UpdateUnspent(String tx_hash, int value, int height) {
Tangem_Card.UnspentTransaction newUT=new Tangem_Card.UnspentTransaction();
newUT.txID=tx_hash;
newUT.Amount=value;
newUT.Height=height;
mCard.getUnspentTransactions().add(newUT);
notifyDataSetChanged();
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.wallet;
import android.net.Uri;
import com.tangem.cardReader.CardProtocol;
import com.tangem.domain.cardReader.CardProtocol;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

View file

@ -5,16 +5,14 @@ package com.tangem.wallet;
*/
public class CoinEngineFactory {
public static CoinEngine Create(Blockchain chain)
{
if(Blockchain.BitcoinCash == chain || Blockchain.BitcoinCashTestNet == chain) {
public static CoinEngine Create(Blockchain chain) {
if (Blockchain.BitcoinCash == chain || Blockchain.BitcoinCashTestNet == chain) {
return new BtcCashEngine();
}else if(Blockchain.Bitcoin == chain || Blockchain.BitcoinTestNet == chain) {
} else if (Blockchain.Bitcoin == chain || Blockchain.BitcoinTestNet == chain) {
return new BtcEngine(); //TODO: ВРЕМЕНГГО!!!!
}else if(Blockchain.Ethereum == chain || Blockchain.EthereumTestNet == chain) {
} else if (Blockchain.Ethereum == chain || Blockchain.EthereumTestNet == chain) {
return new EthEngine();
}
else if(Blockchain.Token == chain) {
} else if (Blockchain.Token == chain) {
return new TokenEngine();
} else {
return null;

View file

@ -2,7 +2,7 @@ package com.tangem.wallet;
import android.util.Log;
import com.tangem.cardReader.Util;
import com.tangem.domain.cardReader.Util;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1Integer;

View file

@ -1,184 +0,0 @@
package com.tangem.wallet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by dvol on 16.07.2017.
*/
public class Electrum_Request {
public static final String METHOD_GetBalance = "blockchain.address.get_balance";
public static final String METHOD_ListUnspent = "blockchain.address.listunspent";
public static final String METHOD_GetHistory = "blockchain.address.get_history";
public static final String METHOD_GetTransaction = "blockchain.transaction.get";
public static final String METHOD_GetHeader = "blockchain.block.get_header";
public static final String METHOD_SendTransaction = "blockchain.transaction.broadcast";
public static final String METHOD_GetFee = "blockchain.estimatefee";
public JSONObject jsRequestData;
public String answerData;
public String error;
public String WalletAddress;
public String TxHash;
public String Host;
public int Port;
private Electrum_Request() {
}
public Electrum_Request(JSONObject jsRequest) {
try {
jsRequestData = new JSONObject(jsRequest.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
public JSONObject getAnswer() {
try {
return new JSONObject(answerData);
} catch (Exception e) {
try {
return new JSONObject(String.format("[\"Error\":\"%s\"]", e.getMessage()));
} catch (JSONException e1) {
e1.printStackTrace();
return null;
}
}
}
public String getAsString() {
return jsRequestData.toString();
}
public void setID(int value) {
try {
jsRequestData.put("id", String.format("%d", value));
} catch (JSONException e) {
e.printStackTrace();
}
}
public int getID() {
try {
return jsRequestData.getInt("id");
} catch (JSONException e) {
e.printStackTrace();
return 0;
}
}
public static Electrum_Request CheckBalance(String wallet) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_GetBalance + "\", \"params\":[\"" + wallet + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request GetFee(String wallet) {
Electrum_Request request = new Electrum_Request();
try{
request.WalletAddress = wallet; //METHOD_GetFee
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_GetFee + "\", \"params\":[\"" + 6 + "\"] }");
}
catch(JSONException e)
{
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request GetHeader(String wallet, String height) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_GetHeader + "\", \"params\":[\"" + height + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request ListUnspent(String wallet) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_ListUnspent + "\", \"params\":[\"" + wallet + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request Broadcast(String wallet, String tx) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_SendTransaction + "\", \"params\":[\"" + tx + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request ListHistory(String wallet) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_GetHistory + "\", \"params\":[\"" + wallet + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public static Electrum_Request GetTransaction(String wallet, String tx_hash) {
Electrum_Request request = new Electrum_Request();
try {
request.WalletAddress=wallet;
request.TxHash = tx_hash;
request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_GetTransaction + "\", \"params\":[\"" + tx_hash + "\"] }");
} catch (JSONException e) {
e.printStackTrace();
request.error = e.toString();
}
return request;
}
public boolean isMethod(String methodName) throws JSONException {
return jsRequestData.getString("method").equals(methodName);
}
public JSONArray getParams() throws JSONException {
return jsRequestData.getJSONArray("params");
}
public JSONObject getResult() throws JSONException {
return getAnswer().getJSONObject("result");
}
public String getResultString() throws JSONException {
return getAnswer().getString("result");
}
public JSONArray getResultArray() throws JSONException {
return getAnswer().getJSONArray("result");
}
}

View file

@ -1,116 +0,0 @@
package com.tangem.wallet;
import android.os.AsyncTask;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* Created by dvol on 16.07.2017.
*/
public class Electrum_Task extends AsyncTask<Electrum_Request, Integer, List<Electrum_Request>> {
public static final String logTag = "Electrum";
//public static final String Host = /*"hsmiths.changeip.net";*/ "testnetnode.arihanc.com";
//public static final int Port = /*8080*/51001;
private int reqID = 1;
private String Host = "";
private int Port = 0;
OutputStreamWriter out;
BufferedReader in;
public SharedData sharedCounter = null;
public Electrum_Task(String host, int port) {
super();
Host = host;
Port = port;
}
public Electrum_Task(String host, int port, SharedData sharedCounter) {
super();
Host = host;
Port = port;
this.sharedCounter = sharedCounter;
}
@Override
protected List<Electrum_Request> doInBackground(Electrum_Request... requests) {
List<Electrum_Request> result = new ArrayList<>();
for (int i = 0; i < requests.length; i++) {
result.add(requests[i]);
}
try {
InetAddress serverAddress = InetAddress.getByName(Host);
Log.v(logTag, "Connecting..."+Host);
Socket socket = new Socket(serverAddress, Port);
socket.setSoTimeout(5000);
try {
OutputStream os = socket.getOutputStream();
out = new OutputStreamWriter(os, "UTF-8");
Log.v(logTag, "Connected");
InputStream is = socket.getInputStream();
in = new BufferedReader(new InputStreamReader(is));
publishProgress(5);
for (int i = 0; i < requests.length; i++) {
requests[i].setID(reqID++);
doRequest(requests[i]);
publishProgress(5 + 90 * (i + 1) / requests.length);
}
publishProgress(100);
} catch (Exception e) {
Log.e(logTag, "Error: ", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e(logTag, "Error: ", e);
for (int i = 0; i < requests.length; i++) {
result.get(i).error = e.toString();
}
}
return result;
}
private void doRequest(Electrum_Request request) {
try {
Log.v(logTag, "<< " + request.getAsString());
out.write(request.getAsString() + "\n");
out.flush();
request.answerData = in.readLine();
request.Host=Host;
request.Port=Port;
if (request.answerData != null) {
Log.v(logTag, ">> " + request.answerData);
} else {
request.error = "No answer from server";
Log.v(logTag, ">> <NULL>");
}
} catch (Exception e) {
request.error = e.toString();
}
}
public String getValidationNodeDescription() {
return "Electrum, "+Host+":"+String.valueOf(Port);
}
}

View file

@ -3,8 +3,8 @@ package com.tangem.wallet;
import android.net.Uri;
import android.util.Log;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.TLV;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.TLV;
import org.bitcoinj.core.ECKey;

View file

@ -1,92 +0,0 @@
package com.tangem.wallet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by dvol on 16.07.2017.
*/
public class ExchangeRequest {
public JSONObject jsRequestData;
public String answerData;
public String error;
public String WalletAddress;
public String currency;
public String currencyAlter;
private ExchangeRequest() {
}
public ExchangeRequest(JSONObject jsRequest) {
try {
jsRequestData = new JSONObject(jsRequest.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
public JSONObject getAnswer() {
try {
return new JSONObject(answerData);
} catch (Exception e) {
try {
return new JSONObject(String.format("[\"Error\":\"%s\"]", e.getMessage()));
} catch (JSONException e1) {
e1.printStackTrace();
return null;
}
}
}
public JSONArray getAnswerList() throws JSONException {
return new JSONArray(answerData);
}
public String getAsString() {
return jsRequestData.toString();
}
public void setID(int value) {
try {
jsRequestData.put("id", String.format("%d", value));
} catch (JSONException e) {
e.printStackTrace();
}
}
public int getID() {
try {
return jsRequestData.getInt("id");
} catch (JSONException e) {
e.printStackTrace();
return 0;
}
}
public static ExchangeRequest GetRate(String wallet, String currency, String alterCurrency) {
ExchangeRequest request = new ExchangeRequest();
request.WalletAddress=wallet;
request.currency = currency;
request.currencyAlter = alterCurrency;
return request;
}
public JSONArray getParams() throws JSONException {
return jsRequestData.getJSONArray("params");
}
public JSONObject getResult() throws JSONException {
return getAnswer().getJSONObject("result");
}
public String getResultString() throws JSONException {
return getAnswer().getString("result");
}
public JSONArray getResultArray() throws JSONException {
return getAnswer().getJSONArray("result");
}
}

View file

@ -1,66 +0,0 @@
package com.tangem.wallet;
/**
* Created by Ilia on 16.01.2018.
*/
import android.os.AsyncTask;
import com.tangem.wallet.ExchangeRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Ilia on 04.12.2017.
*/
public class ExchangeTask extends AsyncTask<ExchangeRequest, Void, List<ExchangeRequest>> {
public ExchangeTask()
{
}
protected List<ExchangeRequest> doInBackground(ExchangeRequest... requests) {
List<ExchangeRequest> result = new ArrayList<>();
for (int i = 0; i < requests.length; i++) {
result.add(requests[i]);
}
for (ExchangeRequest request: result)
{
HttpURLConnection httpcon = null;
try {
URL url = new URL("https://api.coinmarketcap.com/v1/ticker/?convert=USD&lmit=10");
httpcon = (HttpURLConnection) url.openConnection();
httpcon.setRequestMethod("GET");
httpcon.connect();
BufferedReader in = new BufferedReader(
new InputStreamReader(httpcon.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
request.answerData = response.toString();
} catch (Exception e) {
request.error = e.getMessage();
} finally {
httpcon.disconnect();
}
}
return result;
}
}

View file

@ -1,63 +0,0 @@
package com.tangem.wallet;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Ilia on 04.12.2017.
*/
public class Fee_Task extends AsyncTask<Fee_Request, Void, List<Fee_Request>> {
public SharedData sharedCounter = null;
public Fee_Task(SharedData sharedData)
{
sharedCounter = sharedData;
}
protected List<Fee_Request> doInBackground(Fee_Request... requests) {
List<Fee_Request> result = new ArrayList<>();
for (int i = 0; i < requests.length; i++) {
result.add(requests[i]);
}
for (Fee_Request request: result)
{
HttpURLConnection httpcon = null;
try {
URL url = new URL("https://estimatefee.com/n/"+String.valueOf(request.getBlockCount()));
httpcon = (HttpURLConnection) url.openConnection();
httpcon.setRequestMethod("GET");
httpcon.connect();
BufferedReader in = new BufferedReader(
new InputStreamReader(httpcon.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
request.answerData = response.toString();
} catch (Exception e) {
request.error = e.getMessage();
} finally {
httpcon.disconnect();
}
}
return result;
}
}

View file

@ -1,134 +0,0 @@
package com.tangem.wallet;
/**
* Created by Ilia on 19.12.2017.
*/
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
/**
* Created by Ilia on 04.12.2017.
*/
public class Infura_Task extends AsyncTask<Infura_Request, Void, List<Infura_Request>> {
private Exception exception;
private Blockchain blockchain;
public Infura_Task(Blockchain blockchainNet)
{
blockchain = blockchainNet;
}
boolean useOurNode = false;
protected List<Infura_Request> doInBackground(Infura_Request... requests) {
List<Infura_Request> result = new ArrayList<>();
for (int i = 0; i < requests.length; i++) {
result.add(requests[i]);
}
for (Infura_Request request: result)
{
HttpURLConnection httpcon = null;
try {
URL url = new URL("https://rinkeby.infura.io/AfWg0tmYEX5Kukn2UkKV");
if(blockchain == Blockchain.Ethereum || blockchain == Blockchain.Token){
if(useOurNode) {
URL tmp = new URL("http://52.230.23.88");
url = new URL(tmp.getProtocol(), tmp.getHost(), 27172, tmp.getFile());
}else
url = new URL("https://mainnet.infura.io/AfWg0tmYEX5Kukn2UkKV");
}
if(useOurNode)
{
httpcon = (HttpURLConnection)url.openConnection();
}
else
{
httpcon = (HttpsURLConnection)url.openConnection();
}
if(httpcon == null)
{
request.error = String.format("Cann't connect to %s", url.getHost());
return result;
}
httpcon.setRequestMethod("POST");
httpcon.setRequestProperty("Content-Type", "application/json");
String params = request.getAsString();
OutputStream os = httpcon.getOutputStream();
if(os == null)
{
request.error = String.format("Cann't recieve data from %s", url.getHost());
return result;
}
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
if(writer == null)
{
request.error = String.format("Cann't send data to %s", url.getHost());
}
writer.write(params);
writer.flush();
writer.close();
os.close();
httpcon.connect();
request.getParams();
System.out.println("code:"+httpcon.getResponseCode());
int code = httpcon.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(httpcon.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
request.answerData = response.toString();
} catch (Exception e) {
this.exception = e;
request.error = e.getMessage();
} finally {
httpcon.disconnect();
}
}
return result;
}
public String getValidationNodeDescription() {
if(blockchain == Blockchain.Ethereum || blockchain == Blockchain.Token)
{
if(useOurNode)
return "52.230.23.88:27172";
else
return "Infura, infura.io";
}
return "Infura, rinkeby.infura.io";
}
}

View file

@ -1,15 +1,9 @@
package com.tangem.wallet;
import com.tangem.cardReader.CardCrypto;
import com.tangem.domain.cardReader.CardCrypto;
import org.spongycastle.jce.ECNamedCurveTable;
import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
import java.math.BigInteger;
import java.util.Arrays;
import static com.tangem.cardReader.CardCrypto.*;
/**
* Created by dvol on 14.11.2017.
*/

View file

@ -3,7 +3,7 @@ package com.tangem.wallet;
import android.content.Context;
import android.util.Log;
import com.tangem.cardReader.Util;
import com.tangem.domain.cardReader.Util;
import java.io.BufferedReader;
import java.io.BufferedWriter;

File diff suppressed because it is too large Load diff

View file

@ -1,34 +0,0 @@
package com.tangem.wallet;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
public class NoExtendedLengthSupportDialog extends DialogFragment {
public static boolean allreadyShowed=false;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle("Warning")
.setMessage("The NFC adapter of the device does not support extended length APDU, it's possible that some functions will not work!")
.setPositiveButton("Got it",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
NoExtendedLengthSupportDialog.allreadyShowed=true;
}
}
)
.create();
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
}
}

View file

@ -5,7 +5,7 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Base64;
import com.tangem.cardReader.CardProtocol;
import com.tangem.domain.cardReader.CardProtocol;
import java.util.ArrayList;
import java.util.List;
@ -31,7 +31,7 @@ public class PINStorage {
}
static List<String> getPINs() {
public static 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 +41,7 @@ public class PINStorage {
return result;
}
static void setLastUsedPIN(String PIN) {
public static void setLastUsedPIN(String PIN) {
mLastUsedPIN = PIN;
}

View file

@ -1,21 +1,16 @@
package com.tangem.wallet;
import android.os.Bundle;
import android.util.Log;
import com.google.common.base.Strings;
import com.tangem.cardReader.SettingsMask;
import com.tangem.cardReader.Util;
import com.tangem.domain.cardReader.SettingsMask;
import com.tangem.domain.cardReader.Util;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;
/**
* Created by dvol on 16.07.2017.

View file

@ -4,8 +4,8 @@ import android.net.Uri;
import android.util.Log;
import com.google.common.base.Strings;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.TLV;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.TLV;
import org.bitcoinj.core.ECKey;
@ -24,51 +24,46 @@ import static com.tangem.wallet.FormatUtil.GetDecimalFormat;
* Created by Ilia on 20.03.2018.
*/
public class TokenEngine extends CoinEngine{
public String GetNextNode(Tangem_Card mCard)
{
public class TokenEngine extends CoinEngine {
public String GetNextNode(Tangem_Card mCard) {
return "abc1.hsmiths.com";
}
public int GetNextNodePort(Tangem_Card mCard)
{
public int GetNextNodePort(Tangem_Card mCard) {
return 60001;
}
public String GetNode(Tangem_Card mCard)
{
public String GetNode(Tangem_Card mCard) {
return "abc1.hsmiths.com";
}
public int GetNodePort(Tangem_Card mCard)
{
public int GetNodePort(Tangem_Card mCard) {
return 60001;
}
public void SwitchNode(Tangem_Card mCard)
{
public void SwitchNode(Tangem_Card mCard) {
}
public boolean AwaitingConfirmation(Tangem_Card card)
{
public boolean AwaitingConfirmation(Tangem_Card card) {
return false;
}
public boolean InOutPutVisible()
{
public boolean InOutPutVisible() {
return false;
}
public String GetBalanceCurrency(Tangem_Card card)
{
public String GetBalanceCurrency(Tangem_Card card) {
String currency = card.getTokenSymbol();
if(Strings.isNullOrEmpty(currency))
if (Strings.isNullOrEmpty(currency))
return "NoN";
return currency;
}
public String GetFeeCurrency()
{
public String GetFeeCurrency() {
return "Gwei";
}
BigDecimal convertToEth(String value)
{
BigDecimal convertToEth(String value) {
BigInteger m = new BigInteger(value, 10);
BigDecimal n = new BigDecimal(m);
BigDecimal d = n.divide(new BigDecimal("1000000000000000000"));
@ -77,17 +72,15 @@ public class TokenEngine extends CoinEngine{
}
public int GetTokenDecimals(Tangem_Card card)
{
public int GetTokenDecimals(Tangem_Card card) {
return card.getTokensDecimal();
}
public String GetContractAddress(Tangem_Card card)
{
public String GetContractAddress(Tangem_Card card) {
return card.getContractAddress();
}
public boolean IsNeedCheckNode()
{
public boolean IsNeedCheckNode() {
return false;
}
@ -96,21 +89,18 @@ public class TokenEngine extends CoinEngine{
return false;
}
if(!address.startsWith("0x")&&!address.startsWith("0X"))
{
if (!address.startsWith("0x") && !address.startsWith("0X")) {
return false;
}
if(address.length()!=42)
{
if (address.length() != 42) {
return false;
}
return true;
}
public String GetBalanceAlterValue(Tangem_Card mCard)
{
public String GetBalanceAlterValue(Tangem_Card mCard) {
String dec = mCard.getDecimalBalanceAlter();
BigDecimal d = convertToEth(dec);
String s = d.toString();
@ -121,9 +111,8 @@ public class TokenEngine extends CoinEngine{
return output;
}
public String GetBalanceValue(Tangem_Card mCard)
{
if(!HasBalanceInfo(mCard))
public String GetBalanceValue(Tangem_Card mCard) {
if (!HasBalanceInfo(mCard))
return "-- -- -- " + GetBalanceCurrency(mCard);
String dec = mCard.getDecimalBalance();
@ -138,28 +127,24 @@ public class TokenEngine extends CoinEngine{
return output;
}
public boolean CheckAmount(Tangem_Card card, String amount) throws Exception
{
public boolean CheckAmount(Tangem_Card card, String amount) throws Exception {
DecimalFormat decimalFormat = GetDecimalFormat();
BigDecimal amountValue = (BigDecimal) decimalFormat.parse(amount); //new BigDecimal(strAmount);
BigDecimal maxValue = new BigDecimal(GetBalanceValue(card));
if(amountValue.compareTo(maxValue) > 0 )
{
if (amountValue.compareTo(maxValue) > 0) {
return false;
}
return true;
}
public Long GetBalanceLong(Tangem_Card mCard)
{
public Long GetBalanceLong(Tangem_Card mCard) {
return mCard.getBalance();
}
public boolean IsBalanceAlterNotZero(Tangem_Card card)
{
public boolean IsBalanceAlterNotZero(Tangem_Card card) {
String balance = card.getDecimalBalanceAlter();
if(balance == null || balance == "")
if (balance == null || balance == "")
return false;
BigDecimal bi = new BigDecimal(balance);
@ -170,10 +155,9 @@ public class TokenEngine extends CoinEngine{
return true;
}
public boolean IsBalanceNotZero(Tangem_Card card)
{
public boolean IsBalanceNotZero(Tangem_Card card) {
String balance = card.getDecimalBalance();
if(balance == null || balance == "")
if (balance == null || balance == "")
return false;
BigDecimal bi = new BigDecimal(balance);
@ -184,21 +168,20 @@ public class TokenEngine extends CoinEngine{
return true;
}
public boolean HasBalanceInfo(Tangem_Card card)
{
public boolean HasBalanceInfo(Tangem_Card card) {
String balance = card.getDecimalBalance();
if(balance == null || balance == "")
if (balance == null || balance == "")
return false;
String balanceEx = card.getDecimalBalanceAlter();
if(balanceEx == null || balanceEx == "")
if (balanceEx == null || balanceEx == "")
return false;
return true;
}
@Override
public String GetBalanceEquivalent(Tangem_Card mCard) {
if(!HasBalanceInfo(mCard)){
if (!HasBalanceInfo(mCard)) {
return "-- -- -- ";
}
String dec = mCard.getDecimalBalance();
@ -208,7 +191,7 @@ public class TokenEngine extends CoinEngine{
@Override
public String GetBalance(Tangem_Card mCard) {
if(!HasBalanceInfo(mCard)){
if (!HasBalanceInfo(mCard)) {
return "-- -- -- " + GetBalanceCurrency(mCard);
}
@ -218,15 +201,12 @@ public class TokenEngine extends CoinEngine{
}
public String GetBalanceWithAlter(Tangem_Card mCard)
{
public String GetBalanceWithAlter(Tangem_Card mCard) {
//return GetBalance(mCard) + "\n(" + GetBalanceAlterValue(mCard) + " ETH)";
return " " + GetBalance(mCard) + " <br><small><small> + " + GetBalanceAlterValue(mCard) + " ETH for gas</small></small>";
}
public String calculateAddress(Tangem_Card mCard, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
public String calculateAddress(Tangem_Card mCard, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
Keccak256 kec = new Keccak256();
int lenPk = pkUncompressed.length;
if (lenPk < 2) {
@ -262,35 +242,29 @@ public class TokenEngine extends CoinEngine{
}
public String GetAmountEqualentDescriptor(Tangem_Card mCard, String value)
{
public String GetAmountEqualentDescriptor(Tangem_Card mCard, String value) {
BigDecimal d = new BigDecimal(value);
return EthEngine.getAmountEquivalentDescriptionETH(d, mCard.getRate());
}
public String GetFeeEqualentDescriptor(Tangem_Card mCard, String value)
{
public String GetFeeEqualentDescriptor(Tangem_Card mCard, String value) {
BigDecimal d = new BigDecimal(value);
return EthEngine.getAmountEquivalentDescriptionETH(d, mCard.getRateAlter());
}
public Uri getShareWalletURIExplorer(Tangem_Card mCard)
{
return Uri.parse("https://etherscan.io/token/"+GetContractAddress(mCard)+"?a=" + mCard.getWallet());
public Uri getShareWalletURIExplorer(Tangem_Card mCard) {
return Uri.parse("https://etherscan.io/token/" + GetContractAddress(mCard) + "?a=" + mCard.getWallet());
}
public Uri getShareWalletURI(Tangem_Card mCard)
{
public Uri getShareWalletURI(Tangem_Card mCard) {
return Uri.parse("" + mCard.getWallet());
}
public boolean CheckUnspentTransaction(Tangem_Card mCard)
{
public boolean CheckUnspentTransaction(Tangem_Card mCard) {
return true;
}
public boolean CheckAmountValie(Tangem_Card mCard, String amountValue, String feeValue, Long minFeeInInternalUnits)
{
public boolean CheckAmountValie(Tangem_Card mCard, String amountValue, String feeValue, Long minFeeInInternalUnits) {
Long fee = null;
BigDecimal amount = null;
try {
@ -301,14 +275,14 @@ public class TokenEngine extends CoinEngine{
return false;
}
if(fee == null || amount == null)
if (fee == null || amount == null)
return false;
if(fee == 0 || amount.compareTo(BigDecimal.ZERO) == 0)
if (fee == 0 || amount.compareTo(BigDecimal.ZERO) == 0)
return false;
if(fee < minFeeInInternalUnits)
if (fee < minFeeInInternalUnits)
return false;
@ -322,8 +296,7 @@ public class TokenEngine extends CoinEngine{
return true;
}
public String EvaluteFeeEquivalent(Tangem_Card mCard, String fee)
{
public String EvaluteFeeEquivalent(Tangem_Card mCard, String fee) {
BigDecimal gweFee = new BigDecimal(fee);
gweFee = gweFee.divide(new BigDecimal("1000000000"));
gweFee = gweFee.setScale(18, RoundingMode.DOWN);
@ -334,7 +307,7 @@ public class TokenEngine extends CoinEngine{
BigInteger nonceValue = mCard.GetConfirmTXCount();
byte[] pbKey = mCard.getWalletPublicKey();
boolean flag = (mCard.getSigningMethod()== Tangem_Card.SigningMethod.Sign_Hash_Validated_By_Issuer);
boolean flag = (mCard.getSigningMethod() == Tangem_Card.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = mCard.getIssuer();
@ -353,8 +326,6 @@ public class TokenEngine extends CoinEngine{
BigInteger amount = amountDec.toBigInteger(); //new BigInteger(amountValue, 10);
//amount = amount.subtract(fee);
BigInteger nonce = nonceValue;
@ -384,12 +355,11 @@ public class TokenEngine extends CoinEngine{
amountLeadZero = amountLeadZero.substring(2);
}
while(amountLeadZero.length() < 64)
{
while (amountLeadZero.length() < 64) {
amountLeadZero = "0" + amountLeadZero;
}
String cmd = "a9059cbb000000000000000000000000"+to+amountLeadZero; //TODO only for BAT
String cmd = "a9059cbb000000000000000000000000" + to + amountLeadZero; //TODO only for BAT
byte[] data = BTCUtils.fromHex(cmd);
@ -416,8 +386,7 @@ public class TokenEngine extends CoinEngine{
boolean f = ECKey.verify(for_hash, new ECKey.ECDSASignature(r, s), pbKey);
if(!f)
{
if (!f) {
Log.e("ETH-CHECK", "Sign Failed.");
}

View file

@ -1,360 +0,0 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.NfcManager;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class VerifyCardActivityFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener, NfcAdapter.ReaderCallback {
Tangem_Card mCard;
TextView tvCardID, tvManufacturer, tvRegistrationDate, tvCardIdentity, tvLastSigned, tvRemainingSignatures, tvReusable, tvOk, tvError, tvMessage,
tvIssuer, tvIssuerData, tvFeatures, tvBlockchain, tvSignedTx, tvSigningMethod, tvFirmware, tvWalletIdentity, tvWallet;
ImageView ivBlockchain, ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion;
SwipeRefreshLayout mSwipeRefreshLayout;
private NfcManager mNfcManager;
public VerifyCardActivityFragment() {
}
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_verify_card, container, false);
mNfcManager = new NfcManager(this.getActivity(), this);
// SwipeRefreshLayout
mSwipeRefreshLayout = v.findViewById(R.id.swipe_container);
mSwipeRefreshLayout.setOnRefreshListener(this);
mCard = new Tangem_Card(getActivity().getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getActivity().getIntent().getExtras().getBundle("Card"));
tvCardID = v.findViewById(R.id.tvCardID);
tvLastSigned = v.findViewById(R.id.tvLastSigned);
tvRemainingSignatures = v.findViewById(R.id.tvRemainingSignatures);
tvReusable = v.findViewById(R.id.tvReusable);
tvManufacturer = v.findViewById(R.id.tvManufacturerInfo);
tvCardIdentity = v.findViewById(R.id.tvCardIdentity);
tvRegistrationDate = v.findViewById(R.id.tvCardRegistredDate);
ivBlockchain = v.findViewById(R.id.imgBlockchain);
ivPIN = v.findViewById(R.id.imgPIN);
ivPIN2orSecurityDelay = v.findViewById(R.id.imgPIN2orSecurityDelay);
ivDeveloperVersion = v.findViewById(R.id.imgDeveloperVersion);
tvError = v.findViewById(R.id.tvError);
tvMessage = v.findViewById(R.id.tvMessage);
tvIssuer = v.findViewById(R.id.tvIssuer);
tvIssuerData = v.findViewById(R.id.tvIssuerData);
tvFirmware = v.findViewById(R.id.tvFirmware);
tvFeatures = v.findViewById(R.id.tvFeatures);
tvBlockchain = v.findViewById(R.id.tvBlockchain);
tvSignedTx = v.findViewById(R.id.tvSignedTx);
tvSigningMethod = v.findViewById(R.id.tvSigningMethod);
tvOk = v.findViewById(R.id.tvOk);
if (tvOk != null) {
tvOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent data = prepareResultIntent();
data.putExtra("modification", "update");
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
});
}
tvWallet = v.findViewById(R.id.tvWallet);
tvWalletIdentity = v.findViewById(R.id.tvWalletIdentity);
UpdateViews();
// if (NeedUpdate) {
// mSwipeRefreshLayout.setRefreshing(true);
// mSwipeRefreshLayout.postDelayed(new Runnable() {
// @Override
// public void run() {
// onRefresh();
// }
// }, 1000);
// }
return v;
}
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());
}
if (mCard.getMessage() == null || mCard.getMessage().isEmpty()) {
tvMessage.setVisibility(View.GONE);
tvMessage.setText("");
} else {
tvMessage.setVisibility(View.VISIBLE);
tvMessage.setText(mCard.getMessage());
}
tvManufacturer.setText(mCard.getManufacturer().getOfficialName());
if (mCard.isManufacturerConfirmed() && mCard.isCardPublicKeyValid()) {
tvCardIdentity.setText("Attested");
tvCardIdentity.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
} else {
tvCardIdentity.setText("Not confirmed");
tvCardIdentity.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
}
tvIssuer.setText(mCard.getIssuerDescription());
tvIssuerData.setText(mCard.getIssuerDataDescription());
tvRegistrationDate.setText(mCard.getPersonalizationDateTimeDescription());
//tvBlockchain.setText(mCard.getBlockchain().getOfficialName());
tvBlockchain.setText(mCard.getBlockchainName());
ivBlockchain.setImageResource(mCard.getBlockchain().getImageResource(this.getContext(), mCard.getTokenSymbol()));
if (mCard.isReusable()) {
tvReusable.setText("Reusable");
} else {
tvReusable.setText("One-off banknote");
}
tvSigningMethod.setText(mCard.getSigningMethod().getDescription());
if (mCard.getStatus() == Tangem_Card.Status.Loaded || mCard.getStatus() == Tangem_Card.Status.Purged) {
tvLastSigned.setText(mCard.getLastSignedDescription());
if (mCard.getRemainingSignatures() == 0) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("None");
} else if (mCard.getRemainingSignatures() == 1) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("Last one!");
} else if (mCard.getRemainingSignatures() > 1000) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("Unlimited");
} else {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText(String.valueOf(mCard.getRemainingSignatures()));
}
tvSignedTx.setText(String.valueOf(mCard.getMaxSignatures() - mCard.getRemainingSignatures()));
} else {
tvLastSigned.setText("");
tvRemainingSignatures.setText("");
tvSignedTx.setText("");
}
tvFirmware.setText(mCard.getFirmwareVersion());
String features = "";
if (mCard.allowSwapPIN() && mCard.allowSwapPIN2()) {
features += "Allows change PIN1 and PIN2\n";
} else if (mCard.allowSwapPIN()) {
features += "Allows change PIN1\n";
} else if (mCard.allowSwapPIN2()) {
features += "Allows change PIN2\n";
} else {
features += "Fixed PIN1 and PIN2\n";
}
if (mCard.needCVC()) {
features += "Requires CVC\n";
}
if (mCard.supportDynamicNDEF()) {
features += "Dynamic NDEF for iOS\n";
} else if (mCard.supportNDEF()) {
features += "NDEF\n";
}
if (mCard.supportBlock()) {
features += "Blockable\n";
}
if (mCard.supportOnlyOneCommandAtTime()) {
features += "Atomic command mode";
}
if (features.endsWith("\n")) {
features = features.substring(0, features.length() - 1);
}
tvFeatures.setText(features);
if (mCard.useDefaultPIN1()) {
ivPIN.setImageResource(R.drawable.unlock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by default PIN1 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN.setImageResource(R.drawable.lock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by user's PIN1 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.getPauseBeforePIN2() > 0 && (mCard.useDefaultPIN2() || !mCard.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View 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(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by default PIN2 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by user's PIN2 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.useDevelopersFirmware()) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version);
ivDeveloperVersion.setVisibility(View.VISIBLE);
ivDeveloperVersion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "Unlocked banknote, only for development use", Toast.LENGTH_LONG).show();
}
});
} else {
ivDeveloperVersion.setVisibility(View.INVISIBLE);
}
if (mCard.getStatus() == Tangem_Card.Status.Loaded) {
tvWallet.setText(mCard.getShortWalletString());
if (mCard.isWalletPublicKeyValid()) {
tvWalletIdentity.setText("Possession proved");
tvWalletIdentity.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
} else {
tvWalletIdentity.setText("Possession NOT proved");
tvWalletIdentity.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
}
} else {
tvWallet.setText("not available");
tvWalletIdentity.setText("-- -- --");
}
timerHideErrorAndMessage = new Timer();
timerHideErrorAndMessage.schedule(new TimerTask() {
@Override
public void run() {
tvError.post(new Runnable() {
@Override
public void run() {
tvMessage.setVisibility(View.GONE);
tvError.setVisibility(View.GONE);
mCard.setError(null);
mCard.setMessage(null);
}
});
}
}, 5000);
} catch (Exception e) {
e.printStackTrace();
}
}
Timer timerHideErrorAndMessage = null;
public Intent prepareResultIntent() {
Intent data = new Intent();
data.putExtra("UID", mCard.getUID());
data.putExtra("Card", mCard.getAsBundle());
return data;
}
@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 onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(), "Ignore discovered tag!");
mNfcManager.IgnoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -4,8 +4,8 @@ import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
/**
* Created by dvol on 04.02.2018.

View file

@ -1,70 +0,0 @@
package com.tangem.wallet;
import android.content.Context;
import android.graphics.Canvas;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.TextView;
public class VerticalTextView extends TextView
{
final boolean topDown;
public VerticalTextView( Context context,
AttributeSet attrs )
{
super( context, attrs );
final int gravity = getGravity();
if ( Gravity.isVertical( gravity )
&& ( gravity & Gravity.VERTICAL_GRAVITY_MASK )
== Gravity.BOTTOM )
{
setGravity(
( gravity & Gravity.HORIZONTAL_GRAVITY_MASK )
| Gravity.TOP );
topDown = false;
}
else
{
topDown = true;
}
}
@Override
protected void onMeasure( int widthMeasureSpec,
int heightMeasureSpec )
{
super.onMeasure( heightMeasureSpec,
widthMeasureSpec );
setMeasuredDimension( getMeasuredHeight(),
getMeasuredWidth() );
}
@Override
protected void onDraw( Canvas canvas )
{
TextPaint textPaint = getPaint();
textPaint.setColor( getCurrentTextColor() );
textPaint.drawableState = getDrawableState();
canvas.save();
if ( topDown )
{
canvas.translate( getWidth(), 0 );
canvas.rotate( 90 );
}
else
{
canvas.translate( 0, getHeight() );
canvas.rotate( -90 );
}
canvas.translate( getCompoundPaddingLeft(),
getExtendedPaddingTop() );
getLayout().draw( canvas );
canvas.restore();
}
}

View file

@ -1,166 +0,0 @@
package com.tangem.wallet;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by dvol on 06.03.2018.
*/
public class WaitSecurityDelayDialog extends DialogFragment {
ProgressBar progressBar;
int msTimeout = 60000, msProgress = 0;
Timer timer;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View v = inflater.inflate(R.layout.dialog_wait_pin2, null);
progressBar = v.findViewById(R.id.progressBar);
progressBar.setMax(msTimeout);
progressBar.setProgress(msProgress);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
progressBar.post(new Runnable() {
@Override
public void run() {
int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
if (progress < WaitSecurityDelayDialog.this.progressBar.getMax()) {
WaitSecurityDelayDialog.this.progressBar.setProgress(progress + 1000);
}
}
});
}
}, 1000, 1000);
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle("Security delay")
.setView(v)
.setCancelable(false)
.create();
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
}
public void setup(int msTimeout, int msProgress) {
this.msTimeout = msTimeout;
this.msProgress = msProgress;
}
public void setRemainingTimeout(final int msec) {
progressBar.post(new Runnable() {
@Override
public void run() {
int progress = WaitSecurityDelayDialog.this.progressBar.getProgress();
if (timer != null) {
// we get delay latency from card for first time - don't change progress by timer, only by card answer
progressBar.setMax(progress + msec);
timer.cancel();
timer = null;
} else {
int newProgress = progressBar.getMax() - msec;
if (newProgress > progress) {
progressBar.setProgress(newProgress);
} else {
progressBar.setMax(progress + msec);
}
}
}
});
}
static Timer timerToShowDelayDialog = null;
static WaitSecurityDelayDialog instance = null;
public static WaitSecurityDelayDialog getInstance() {
if (instance == null) {
instance = new WaitSecurityDelayDialog();
}
return instance;
}
private final static int MinRemainingDelayToShowDialog=1000;
private final static int DelayBeforeShowDialog=5000;
public static void onReadBeforeRequest(final Activity activity, final int timeout) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (timerToShowDelayDialog != null || timeout < DelayBeforeShowDialog+MinRemainingDelayToShowDialog) return;
timerToShowDelayDialog = new Timer();
timerToShowDelayDialog.schedule(new TimerTask() {
@Override
public void run() {
if (WaitSecurityDelayDialog.instance != null) return;
instance = new WaitSecurityDelayDialog();
instance.setup(timeout, DelayBeforeShowDialog);
instance.setCancelable(false);
instance.show(activity.getFragmentManager(), "WaitSecurityDelayDialog");
}
}, DelayBeforeShowDialog);
}
});
}
public static void onReadAfterRequest(final Activity activity) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (timerToShowDelayDialog == null) return;
timerToShowDelayDialog.cancel();
timerToShowDelayDialog = null;
}
});
}
public static void OnReadWait(final Activity activity, final int msec) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (timerToShowDelayDialog != null) {
timerToShowDelayDialog.cancel();
timerToShowDelayDialog = null;
}
if (msec == 0) {
if (instance != null) {
instance.dismiss();
instance = null;
}
return;
}
if (instance == null) {
if( msec>MinRemainingDelayToShowDialog ) {
instance = new WaitSecurityDelayDialog();
// 1000ms - card delay notification interval
instance.setup(msec + 1000, 1000);
instance.setCancelable(false);
instance.show(activity.getFragmentManager(), "WaitSecurityDelayDialog");
}
} else {
instance.setRemainingTimeout(msec);
}
}
});
}
}

View file

@ -1,150 +0,0 @@
package com.tangem.wallet;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.Hashtable;
import static android.content.Context.CLIPBOARD_SERVICE;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link WalletInfoFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class WalletInfoFragment extends Fragment {
// TODO: Rename and change types of parameters
private Tangem_Card mCard;
private OnFragmentInteractionListener mListener;
public WalletInfoFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment WalletInfoFragment.
*/
// TODO: Rename and change types and number of parameters
public static WalletInfoFragment newInstance(Tangem_Card card) {
WalletInfoFragment fragment = new WalletInfoFragment();
Bundle args = new Bundle();
args.putString("UID",card.getUID());
card.SaveToBundle(args);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mCard = new Tangem_Card(getArguments().getString("UID"));
mCard.LoadFromBundle(getArguments());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View result=inflater.inflate(R.layout.fragment_wallet_info, container, false);
ImageView mImage= (ImageView)result.findViewById(R.id.qrWallet);
try {
mImage.setImageBitmap(generateQrCode(mCard.getWallet()));
} catch (WriterException e) {
e.printStackTrace();
}
TextView mText=(TextView)result.findViewById(R.id.strWallet);
mText.setText(mCard.getWallet());
mText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TextView mText = (TextView) view;
ClipboardManager clipboard = (ClipboardManager)getActivity().getSystemService(CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText(mText.getText(), mText.getText()));
Toast.makeText(getContext(),"Copied to clipboard",Toast.LENGTH_LONG).show();
}
});
return result;
}
public static Bitmap generateQrCode(String myCodeText) throws WriterException {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // H = 30% damage
QRCodeWriter qrCodeWriter = new QRCodeWriter();
int size = 256;
BitMatrix bitMatrix = qrCodeWriter.encode(myCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
int width = bitMatrix.getWidth();
Bitmap bmp = Bitmap.createBitmap(width, width, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
bmp.setPixel(y, x, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
return bmp;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
// void onFragmentInteraction(Uri uri);
}
}