Updated on 2026-08-14
This commit is contained in:
parent
61ef397705
commit
bae8bd0e6c
30 changed files with 1686 additions and 1276 deletions
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.wallet.Blockchain;
|
|||
import com.tangem.domain.wallet.CoinEngine;
|
||||
import com.tangem.domain.wallet.CoinEngineFactory;
|
||||
import com.tangem.domain.wallet.TangemCard;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
import com.tangem.presentation.activity.SendTransactionActivity;
|
||||
import com.tangem.presentation.activity.SignPaymentActivity;
|
||||
import com.tangem.util.BTCUtils;
|
||||
|
|
@ -32,14 +33,14 @@ public class SignPaymentTask extends Thread {
|
|||
|
||||
private String txOutAddress;
|
||||
private Activity mContext;
|
||||
private TangemCard mCard;
|
||||
private TangemContext mCtx;
|
||||
private NfcManager mNfcManager;
|
||||
private IsoDep mIsoDep;
|
||||
private CardProtocol.Notifications mNotifications;
|
||||
private boolean isCancelled = false;
|
||||
|
||||
public SignPaymentTask(Activity context, TangemCard card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, String amount, String fee, Boolean IncFee, String outAddress) {
|
||||
mCard = card;
|
||||
public SignPaymentTask(Activity context, TangemContext ctx, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, String amount, String fee, Boolean IncFee, String outAddress) {
|
||||
mCtx=ctx;
|
||||
mContext = context;
|
||||
mNfcManager = nfcManager;
|
||||
mIsoDep = isoDep;
|
||||
|
|
@ -53,7 +54,7 @@ public class SignPaymentTask extends Thread {
|
|||
if (mIsoDep == null) {
|
||||
return;
|
||||
}
|
||||
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCard, mNotifications);
|
||||
CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mCtx.getCard(), mNotifications);
|
||||
|
||||
mNotifications.onReadStart(protocol);
|
||||
try {
|
||||
|
|
@ -86,15 +87,15 @@ public class SignPaymentTask extends Thread {
|
|||
// SignBTC_TX(protocol);
|
||||
// }
|
||||
|
||||
CoinEngine engine = CoinEngineFactory.create(mCard.getBlockchain());
|
||||
CoinEngine engine = CoinEngineFactory.create(mCtx.getCard().getBlockchain());
|
||||
if (engine != null) {
|
||||
if (mCard.getPauseBeforePIN2() > 0) {
|
||||
mNotifications.onReadWait(mCard.getPauseBeforePIN2());
|
||||
if (mCtx.getCard().getPauseBeforePIN2() > 0) {
|
||||
mNotifications.onReadWait(mCtx.getCard().getPauseBeforePIN2());
|
||||
}
|
||||
|
||||
byte[] tx = null;
|
||||
try {
|
||||
tx = engine.sign(txFee, txAmount, txIncFee, txOutAddress, mCard, protocol);
|
||||
tx = engine.sign(txFee, txAmount, txIncFee, txOutAddress, protocol);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
@ -104,14 +105,14 @@ public class SignPaymentTask extends Thread {
|
|||
}
|
||||
|
||||
if (tx != null) {
|
||||
// TODO - move to engine!!!
|
||||
String txStr = BTCUtils.toHex(tx);
|
||||
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet || mCard.getBlockchain() == Blockchain.Token) {
|
||||
if (mCtx.getBlockchain() == Blockchain.Ethereum || mCtx.getBlockchain() == Blockchain.EthereumTestNet || mCtx.getBlockchain() == Blockchain.Token) {
|
||||
txStr = String.format("0x%s", txStr);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(mContext, SendTransactionActivity.class);
|
||||
intent.putExtra(TangemCard.EXTRA_UID, mCard.getUID());
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, mCard.getAsBundle());
|
||||
mCtx.saveToBundle(intent.getExtras());
|
||||
intent.putExtra(SendTransactionActivity.EXTRA_TX, txStr);
|
||||
mContext.startActivityForResult(intent, SignPaymentActivity.REQUEST_CODE_SEND_PAYMENT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.domain.wallet.Issuer;
|
|||
import com.tangem.domain.wallet.LocalStorage;
|
||||
import com.tangem.domain.wallet.TangemCard;
|
||||
import com.tangem.domain.wallet.Manufacturer;
|
||||
import com.tangem.domain.wallet.TangemContext;
|
||||
import com.tangem.util.Util;
|
||||
|
||||
import org.spongycastle.jce.ECNamedCurveTable;
|
||||
|
|
@ -584,8 +585,9 @@ public class CardProtocol {
|
|||
mCard.setWalletPublicKey(pkUncompressed);
|
||||
mCard.setWalletPublicKeyRar(pkCompresses);
|
||||
|
||||
CoinEngine engineCoin = CoinEngineFactory.create(mCard.getBlockchain());
|
||||
String wallet = engineCoin.calculateAddress(mCard, pkUncompressed);
|
||||
TangemContext ctx=new TangemContext(mCard);
|
||||
CoinEngine engineCoin = CoinEngineFactory.create(ctx);
|
||||
String wallet = engineCoin.calculateAddress(pkUncompressed);
|
||||
mCard.setWallet(wallet);
|
||||
//mCard.setWallet(Blockchain.calculateWalletAddress(mCard, pkUncompressed));
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ public class BalanceValidator {
|
|||
return firstLine;
|
||||
}
|
||||
|
||||
public void setFirstLine(String value) {
|
||||
firstLine=value;
|
||||
}
|
||||
|
||||
public String getSecondLine(Boolean recommend) {
|
||||
if (!recommend) return secondLine;
|
||||
if (score > 89) {
|
||||
|
|
@ -26,6 +30,14 @@ public class BalanceValidator {
|
|||
}
|
||||
}
|
||||
|
||||
public void setSecondLine(String value) {
|
||||
secondLine=value;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
if (score > 89) {
|
||||
return R.color.confirmed;
|
||||
|
|
@ -38,73 +50,14 @@ public class BalanceValidator {
|
|||
}
|
||||
}
|
||||
|
||||
public void Check(TangemCard card, Boolean attest) {
|
||||
public void Check(TangemContext ctx, Boolean attest) {
|
||||
firstLine = "Verification failed";
|
||||
secondLine = "";
|
||||
TangemCard card=ctx.getCard();
|
||||
CoinEngine engine=CoinEngineFactory.create(ctx);
|
||||
|
||||
if (card.getBlockchain() == Blockchain.Bitcoin || card.getBlockchain() == Blockchain.BitcoinTestNet) {
|
||||
|
||||
if (((card.getOfflineBalance() == null) && !card.isBalanceReceived()) || (!card.isBalanceReceived() && (card.getRemainingSignatures() != card.getMaxSignatures()))) {
|
||||
score = 0;
|
||||
firstLine = "Unknown balance";
|
||||
secondLine = "Balance cannot be verified. Swipe down to refresh.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround before new back-end
|
||||
// if (card.getRemainingSignatures() == card.getMaxSignatures()) {
|
||||
// firstLine = "Verified balance";
|
||||
// secondLine = "Balance confirmed in blockchain. ";
|
||||
// secondLine += "Verified note identity. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (card.getBalanceUnconfirmed() != 0) {
|
||||
score = 0;
|
||||
firstLine = "Transaction in progress";
|
||||
secondLine = "Wait for confirmation in blockchain";
|
||||
return;
|
||||
}
|
||||
|
||||
if (card.isBalanceReceived() && card.isBalanceEqual()) {
|
||||
score = 100;
|
||||
firstLine = "Verified balance";
|
||||
secondLine = "Balance confirmed in blockchain";
|
||||
if (card.getBalance() == 0) {
|
||||
firstLine = "Empty wallet";
|
||||
secondLine = "";
|
||||
}
|
||||
}
|
||||
|
||||
// rule 4 TODO: need to check SignedHashed against number of outputs in blockchain
|
||||
// if((card.getRemainingSignatures() != card.getMaxSignatures()) && card.getBalance() != 0)
|
||||
// {
|
||||
// score = 80;
|
||||
// firstLine = "Unguaranteed balance";
|
||||
// secondLine = "Potential unsent transaction. Redeem immediately if accept. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if ((card.getOfflineBalance() != null) && !card.isBalanceReceived() && (card.getRemainingSignatures() == card.getMaxSignatures()) && card.getBalance() != 0) {
|
||||
score = 80;
|
||||
firstLine = "Verified offline balance";
|
||||
secondLine = "Can't obtain balance from blockchain. Restore internet connection to be more confident. ";
|
||||
}
|
||||
|
||||
// if(card.getFailedBalanceRequestCounter()!=0) {
|
||||
// score -= 5 * card.getFailedBalanceRequestCounter();
|
||||
// secondLine += "Not all nodes have returned balance. Swipe down or tap again. ";
|
||||
// if(score <= 0)
|
||||
// return;
|
||||
// }
|
||||
|
||||
//
|
||||
// if(card.isBalanceReceived() && !card.isBalanceEqual()) {
|
||||
// score = 0;
|
||||
// firstLine = "Disputed balance";
|
||||
// secondLine += " Cannot obtain trusted balance at the moment. Try to tap and check this banknote later.";
|
||||
// return;
|
||||
// }
|
||||
if (ctx.getBlockchain() == Blockchain.Bitcoin || ctx.getBlockchain() == Blockchain.BitcoinTestNet) {
|
||||
if( !engine.validateBalance(this) ) return;
|
||||
} else if ((card.getBlockchain() == Blockchain.Ethereum) || (card.getBlockchain() == Blockchain.Token)) {
|
||||
|
||||
if (card.getBalance() == null) {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public enum Blockchain {
|
|||
return resourceId;
|
||||
}
|
||||
|
||||
public int getLogoImageResource(String blockchainID, String symbolName) {
|
||||
public static int getLogoImageResource(String blockchainID, String symbolName) {
|
||||
switch (blockchainID) {
|
||||
case "BTC":
|
||||
return R.drawable.ic_logo_bitcoin;
|
||||
|
|
|
|||
|
|
@ -1,105 +1,116 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.domain.cardReader.CardProtocol;
|
||||
import com.tangem.domain.cardReader.TLV;
|
||||
import com.tangem.util.BTCUtils;
|
||||
import com.tangem.util.CryptoUtil;
|
||||
import com.tangem.util.DecimalDigitsInputFilter;
|
||||
import com.tangem.util.DerEncodingUtil;
|
||||
import com.tangem.util.FormatUtil;
|
||||
import com.tangem.util.Util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.tangem.util.FormatUtil.GetDecimalFormat;
|
||||
|
||||
/**
|
||||
* Created by Ilia on 15.02.2018.
|
||||
*/
|
||||
|
||||
public class BtcCashEngine extends CoinEngine {
|
||||
|
||||
public String getNode(TangemCard mCard) {
|
||||
return "35.157.238.5";
|
||||
public BtcData btcData = null;
|
||||
|
||||
public BtcCashEngine(TangemContext context) throws Exception {
|
||||
super(context);
|
||||
if (context.getCoinData() == null) {
|
||||
btcData = new BtcData();
|
||||
context.setCoinData(btcData);
|
||||
} else if (context.getCoinData() instanceof BtcData) {
|
||||
btcData = (BtcData) context.getCoinData();
|
||||
} else {
|
||||
throw new Exception("Invalid type of Blockchain data for BtcEngine");
|
||||
}
|
||||
}
|
||||
|
||||
public int getNodePort(TangemCard mCard) {
|
||||
return 51001;
|
||||
public BtcCashEngine() {
|
||||
|
||||
}
|
||||
|
||||
public void switchNode(TangemCard mCard) {
|
||||
private void checkBlockchainDataExists() throws Exception {
|
||||
if (btcData == null) throw new Exception("No blockchain data");
|
||||
}
|
||||
|
||||
public boolean inOutPutVisible() {
|
||||
@Override
|
||||
public boolean awaitingConfirmation(){
|
||||
if( btcData==null ) return false;
|
||||
return btcData.getBalanceUnconfirmed() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceHTML() {
|
||||
if (hasBalanceInfo()) {
|
||||
Amount balance = convertToAmount(btcData.getBalanceInInternalUnits());
|
||||
return balance.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceCurrencyHTML() {
|
||||
return "mBCH";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBalanceAlterNotZero() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean awaitingConfirmation(TangemCard card) {
|
||||
return card.getBalanceUnconfirmed() != 0;
|
||||
|
||||
@Override
|
||||
public boolean isBalanceNotZero() {
|
||||
if( btcData==null ) return false;
|
||||
if (btcData.getBalanceInInternalUnits() == null) return false;
|
||||
return btcData.getBalanceInInternalUnits().notZero();
|
||||
}
|
||||
|
||||
public String getBalanceWithAlter(TangemCard mCard) {
|
||||
return getBalance(mCard);
|
||||
}
|
||||
|
||||
public boolean isBalanceAlterNotZero(TangemCard card) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Long getBalanceLong(TangemCard mCard) {
|
||||
return mCard.getBalance();
|
||||
}
|
||||
|
||||
public boolean isBalanceNotZero(TangemCard card) {
|
||||
return card.getBalance() > 0;
|
||||
}
|
||||
|
||||
public boolean checkAmount(TangemCard card, String amount) throws Exception {
|
||||
DecimalFormat decimalFormat = GetDecimalFormat();
|
||||
BigDecimal amountValue = (BigDecimal) decimalFormat.parse(amount);
|
||||
|
||||
// Convert Balance to BigDecimal
|
||||
BigDecimal maxValue = new BigDecimal(getBalanceValue(card));
|
||||
maxValue = maxValue.divide(new BigDecimal(1000));
|
||||
|
||||
//if (use_mCurrency) {
|
||||
amountValue = amountValue.divide(new BigDecimal(1000));
|
||||
//}
|
||||
|
||||
if (amountValue.compareTo(maxValue) > 0) {
|
||||
@Override
|
||||
public boolean checkAmount(Amount amount) throws Exception {
|
||||
checkBlockchainDataExists();
|
||||
if (amount.compareTo(convertToAmount(btcData.getBalanceInInternalUnits())) > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasBalanceInfo(TangemCard card) {
|
||||
return card.hasBalanceInfo();
|
||||
@Override
|
||||
public boolean hasBalanceInfo(){
|
||||
if( btcData==null ) return false;
|
||||
return btcData.hasBalanceInfo();
|
||||
}
|
||||
|
||||
public String getBalanceCurrency(TangemCard card) {
|
||||
@Override
|
||||
public boolean checkUnspentTransaction() throws Exception {
|
||||
checkBlockchainDataExists();
|
||||
return btcData.getUnspentTransactions().size() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeeCurrencyHTML() {
|
||||
return "mBCH";
|
||||
}
|
||||
|
||||
public boolean checkUnspentTransaction(TangemCard mCard) {
|
||||
return mCard.getUnspentTransactions().size() != 0;
|
||||
}
|
||||
|
||||
public String getFeeCurrency() {
|
||||
return "mBCH";
|
||||
}
|
||||
|
||||
public boolean validateAddress(String address, TangemCard card) {
|
||||
@Override
|
||||
public boolean validateAddress(String address) {
|
||||
if (address == null || address.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -134,44 +145,46 @@ public class BtcCashEngine extends CoinEngine {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (card.getBlockchain() != Blockchain.BitcoinCashTestNet && card.getBlockchain() != Blockchain.BitcoinCash) {
|
||||
if (ctx.getBlockchain() != Blockchain.BitcoinCashTestNet && ctx.getBlockchain() != Blockchain.BitcoinCash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (card.getBlockchain() == Blockchain.BitcoinCashTestNet && (address.startsWith("1") || address.startsWith("3"))) {
|
||||
if (ctx.getBlockchain() == Blockchain.BitcoinCashTestNet && (address.startsWith("1") || address.startsWith("3"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public int getTokenDecimals(TangemCard card) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getContractAddress(TangemCard card) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNeedCheckNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Uri getShareWalletUriExplorer(TangemCard mCard) {
|
||||
return Uri.parse((mCard.getBlockchain() == Blockchain.BitcoinCash ? "https://bitcoincash.blockexplorer.com/address/" : "https://testnet.blockexplorer.com/address/") + mCard.getWallet());
|
||||
@Override
|
||||
public Uri getShareWalletUriExplorer() {
|
||||
return Uri.parse((ctx.getBlockchain() == Blockchain.BitcoinCash ? "https://bitcoincash.blockexplorer.com/address/" : "https://testnet.blockexplorer.com/address/") + ctx.getCard().getWallet());
|
||||
}
|
||||
|
||||
public Uri getShareWalletUri(TangemCard mCard) {
|
||||
return Uri.parse("bitcoincash:" + mCard.getWallet());
|
||||
@Override
|
||||
public Uri getShareWalletUri() {
|
||||
return Uri.parse("bitcoincash:" + ctx.getCard().getWallet());
|
||||
}
|
||||
|
||||
public boolean checkAmountValue(TangemCard card, String amountValue, String feeValue, Long minFeeInInternalUnits, Boolean incfee) {
|
||||
Long fee;
|
||||
Long amount;
|
||||
@Override
|
||||
public InputFilter[] getAmountInputFilters() {
|
||||
return new InputFilter[] { new DecimalDigitsInputFilter(8) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkAmountValue(String amountValue, String feeValue, InternalAmount minFeeInInternalUnits, Boolean isIncludeFee) {
|
||||
InternalAmount fee;
|
||||
InternalAmount amount;
|
||||
|
||||
try {
|
||||
amount = card.internalUnitsFromString(amountValue);
|
||||
fee = card.internalUnitsFromString(feeValue);
|
||||
checkBlockchainDataExists();
|
||||
amount = convertToInternalAmount(new Amount(amountValue, ctx.getBlockchain()));
|
||||
fee = convertToInternalAmount(new Amount(feeValue, ctx.getBlockchain()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
|
|
@ -180,64 +193,106 @@ public class BtcCashEngine extends CoinEngine {
|
|||
if (fee == null || amount == null)
|
||||
return false;
|
||||
|
||||
if (fee == 0 || amount == 0)
|
||||
if (fee.isZero() || amount.isZero())
|
||||
return false;
|
||||
|
||||
if (incfee && amount > card.getBalance())
|
||||
if (isIncludeFee && amount.compareTo(btcData.getBalanceInInternalUnits())>0)
|
||||
return false;
|
||||
|
||||
if (!incfee && amount + fee > card.getBalance())
|
||||
if (!isIncludeFee && amount.add(fee).compareTo(btcData.getBalanceInInternalUnits())>0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String evaluateFeeEquivalent(TangemCard mCard, String fee) {
|
||||
return getAmountEquivalentDescriptor(mCard, fee);
|
||||
@Override
|
||||
public boolean validateBalance(BalanceValidator balanceValidator) {
|
||||
if (((ctx.getCard().getOfflineBalance() == null) && !ctx.getCoinData().isBalanceReceived()) || (!ctx.getCoinData().isBalanceReceived() && (ctx.getCard().getRemainingSignatures() != ctx.getCard().getMaxSignatures()))) {
|
||||
balanceValidator.setScore(0);
|
||||
balanceValidator.setFirstLine("Unknown balance");
|
||||
balanceValidator.setSecondLine("Balance cannot be verified. Swipe down to refresh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Workaround before new back-end
|
||||
// if (card.getRemainingSignatures() == card.getMaxSignatures()) {
|
||||
// firstLine = "Verified balance";
|
||||
// secondLine = "Balance confirmed in blockchain. ";
|
||||
// secondLine += "Verified note identity. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (btcData.getBalanceUnconfirmed() != 0) {
|
||||
balanceValidator.setScore(0);
|
||||
balanceValidator.setFirstLine("Transaction in progress");
|
||||
balanceValidator.setSecondLine("Wait for confirmation in blockchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (btcData.isBalanceReceived() && btcData.isBalanceEqual()) {
|
||||
balanceValidator.setScore(100);
|
||||
balanceValidator.setFirstLine("Verified balance");
|
||||
balanceValidator.setSecondLine("Balance confirmed in blockchain");
|
||||
if (btcData.getBalanceInInternalUnits().isZero()) {
|
||||
balanceValidator.setFirstLine("Empty wallet");
|
||||
balanceValidator.setSecondLine("");
|
||||
}
|
||||
}
|
||||
|
||||
// rule 4 TODO: need to check SignedHashed against number of outputs in blockchain
|
||||
// if((card.getRemainingSignatures() != card.getMaxSignatures()) && card.getBalance() != 0)
|
||||
// {
|
||||
// score = 80;
|
||||
// firstLine = "Unguaranteed balance";
|
||||
// secondLine = "Potential unsent transaction. Redeem immediately if accept. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if ((ctx.getCard().getOfflineBalance() != null) && !btcData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && btcData.getBalanceInInternalUnits().notZero() ) {
|
||||
balanceValidator.setScore(80);
|
||||
balanceValidator.setFirstLine("Verified offline balance");
|
||||
balanceValidator.setSecondLine("Can't obtain balance from blockchain. Restore internet connection to be more confident. ");
|
||||
}
|
||||
|
||||
// if(card.getFailedBalanceRequestCounter()!=0) {
|
||||
// score -= 5 * card.getFailedBalanceRequestCounter();
|
||||
// secondLine += "Not all nodes have returned balance. Swipe down or tap again. ";
|
||||
// if(score <= 0)
|
||||
// return;
|
||||
// }
|
||||
|
||||
//
|
||||
// if(card.isBalanceReceived() && !card.isBalanceEqual()) {
|
||||
// score = 0;
|
||||
// firstLine = "Disputed balance";
|
||||
// secondLine += " Cannot obtain trusted balance at the moment. Try to tap and check this banknote later.";
|
||||
// return;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceEquivalent(TangemCard mCard) {
|
||||
Double balance = Double.NaN;
|
||||
try {
|
||||
Long val = mCard.getBalance();
|
||||
balance = mCard.amountFromInternalUnits(val);
|
||||
} catch (Exception ex) {
|
||||
mCard.setRate(0);
|
||||
}
|
||||
|
||||
return mCard.getAmountEquivalentDescription(balance);
|
||||
public Amount getBalance() {
|
||||
return convertToAmount(btcData.getBalanceInInternalUnits());
|
||||
}
|
||||
|
||||
public String getBalance(TangemCard mCard) {
|
||||
if (mCard.hasBalanceInfo()) {
|
||||
Double balance = mCard.amountFromInternalUnits(mCard.getBalance());
|
||||
return mCard.getAmountDescription(balance);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public String evaluateFeeEquivalent(String fee) {
|
||||
return getAmountEquivalentDescriptor(ctx.getCard(), fee);
|
||||
}
|
||||
|
||||
public String getBalanceValue(TangemCard mCard) {
|
||||
if (mCard.hasBalanceInfo()) {
|
||||
Double balance = mCard.getBalance() / (mCard.getBlockchain().getMultiplier());
|
||||
|
||||
String output = FormatUtil.DoubleToString(balance);
|
||||
//String pattern = "#0.000"; // If you like 4 zeros
|
||||
//DecimalFormat myFormatter = new DecimalFormat(pattern);
|
||||
//String output = myFormatter.format(balance);
|
||||
return output;
|
||||
|
||||
//return Double.toString(balance);
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
@Override
|
||||
public String getBalanceEquivalent() {
|
||||
if( btcData==null ) return "";
|
||||
return btcData.getAmountEquivalentDescription(getBalance());
|
||||
}
|
||||
|
||||
public String calculateAddress(TangemCard mCard, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
@Override
|
||||
public String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
|
||||
byte netSelectionByte;
|
||||
switch (mCard.getBlockchain()) {
|
||||
switch (ctx.getBlockchain()) {
|
||||
case BitcoinCash:
|
||||
netSelectionByte = (byte) 0x00; //0 - MainNet 0x6f - TestNet
|
||||
break;
|
||||
|
|
@ -266,29 +321,49 @@ public class BtcCashEngine extends CoinEngine {
|
|||
BB.put(hash4[3]);
|
||||
|
||||
return org.bitcoinj.core.Base58.encode(BB.array());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertByteArrayToAmount(TangemCard mCard, byte[] bytes) throws Exception {
|
||||
public Amount convertToAmount(InternalAmount internalAmount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalAmount convertToInternalAmount(byte[] bytes) {
|
||||
if (bytes == null) return null;
|
||||
byte[] reversed = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
|
||||
return FormatUtil.DoubleToString(mCard.amountFromInternalUnits(Util.byteArrayToLong(reversed)));
|
||||
return new InternalAmount(Util.byteArrayToLong(reversed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] convertAmountToByteArray(TangemCard card, String amount) throws Exception {
|
||||
byte[] bytes = Util.longToByteArray(card.internalUnitsFromString(amount));
|
||||
public byte[] convertToByteArray(InternalAmount internalAmount) throws Exception {
|
||||
byte[] bytes = Util.longToByteArray(internalAmount.longValueExact());
|
||||
byte[] reversed = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
|
||||
return reversed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAmountDescription(TangemCard mCard, String amount) throws Exception {
|
||||
return mCard.getAmountDescription(Double.parseDouble(amount));
|
||||
public CoinData createCoinData() {
|
||||
return new BtcData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnspentInputsDescription() {
|
||||
return btcData.getUnspentInputsDescription();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getAmountDescription(TangemCard mCard, String amount) throws Exception {
|
||||
// return mCard.getAmountDescription(Double.parseDouble(amount));
|
||||
// }
|
||||
|
||||
public static String getAmountEquivalentDescriptionBTC(Double amount, float rate) {
|
||||
if ((rate > 0) && (amount > 0)) {
|
||||
return String.format("≈ USD %.2f", amount * rate);
|
||||
|
|
@ -298,18 +373,21 @@ public class BtcCashEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
public String getAmountEquivalentDescriptor(TangemCard mCard, String value) {
|
||||
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), mCard.getRate());
|
||||
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), btcData.getRate());
|
||||
}
|
||||
|
||||
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, TangemCard mCard, CardProtocol protocol) throws Exception {
|
||||
@Override
|
||||
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
|
||||
|
||||
String myAddress = mCard.getWallet();
|
||||
byte[] pbKey = mCard.getWalletPublicKeyRar(); //ALWAYS USING COMPRESS KEY
|
||||
checkBlockchainDataExists();
|
||||
|
||||
String myAddress = ctx.getCard().getWallet();
|
||||
byte[] pbKey = ctx.getCard().getWalletPublicKeyRar(); //ALWAYS USING COMPRESS KEY
|
||||
String outputAddress = toValue;
|
||||
String changeAddress = myAddress;
|
||||
|
||||
// Build script for our address
|
||||
List<TangemCard.UnspentTransaction> rawTxList = mCard.getUnspentTransactions();
|
||||
List<BtcData.UnspentTransaction> rawTxList = btcData.getUnspentTransactions();
|
||||
byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
|
||||
|
||||
// Collect unspent
|
||||
|
|
@ -345,7 +423,7 @@ public class BtcCashEngine extends CoinEngine {
|
|||
unspentOutputs.get(i).bodyDoubleHash = doubleHashData;
|
||||
unspentOutputs.get(i).bodyHash = hashData;
|
||||
|
||||
if (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
if (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
dataForSign[i] = newTX;
|
||||
} else {
|
||||
dataForSign[i] = doubleHashData;
|
||||
|
|
@ -353,8 +431,8 @@ public class BtcCashEngine extends CoinEngine {
|
|||
|
||||
}
|
||||
|
||||
byte[] signFromCard = null;
|
||||
if (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
byte[] signFromCard;
|
||||
if (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
if (dataForSign.length > 10) throw new Exception("To much hashes in one transaction!");
|
||||
for (int i = 0; i < dataForSign.length; i++) {
|
||||
|
|
@ -364,20 +442,18 @@ public class BtcCashEngine extends CoinEngine {
|
|||
}
|
||||
signFromCard = protocol.run_SignRaw(PINStorage.getPIN2(), bs.toByteArray()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
} else {
|
||||
signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), dataForSign, mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer, null, mCard.getIssuer()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), dataForSign, ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer, null, ctx.getCard().getIssuer()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
// TODO slice signFromCard to hashes.length parts
|
||||
}
|
||||
|
||||
for (int i = 0; i < unspentOutputs.size(); ++i) {
|
||||
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0 + i * 64, 32 + i * 64));
|
||||
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, i * 64, 32 + i * 64));
|
||||
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64));
|
||||
s = CryptoUtil.toCanonicalised(s);
|
||||
byte[] encodingSign = DerEncodingUtil.packSignDerBitcoinCash(r, s, pbKey);
|
||||
|
||||
unspentOutputs.get(i).scriptForBuild = encodingSign;
|
||||
unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDerBitcoinCash(r, s, pbKey);
|
||||
}
|
||||
|
||||
byte[] realTX = BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
|
||||
return realTX;
|
||||
return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
123
app/src/main/java/com/tangem/domain/wallet/BtcData.java
Normal file
123
app/src/main/java/com/tangem/domain/wallet/BtcData.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BtcData extends CoinData {
|
||||
public BtcData() {
|
||||
super();
|
||||
}
|
||||
|
||||
private Long balanceConfirmed, balanceUnconfirmed;
|
||||
|
||||
public String getUnspentInputsDescription() {
|
||||
int gatheredUnspents = 0;
|
||||
for (int i=0; i<unspentTransactions.size(); i++) {
|
||||
if (unspentTransactions.get(i).Raw.length() > 1) gatheredUnspents++;
|
||||
}
|
||||
return String.valueOf(unspentTransactions.size()) + " unspents (" + String.valueOf(gatheredUnspents) + " received)";
|
||||
}
|
||||
|
||||
public static class UnspentTransaction {
|
||||
public String txID;
|
||||
public Integer Amount;
|
||||
public Integer Height;
|
||||
public String Raw = "";
|
||||
|
||||
public Bundle getAsBundle() {
|
||||
Bundle B = new Bundle();
|
||||
B.putString("txID", txID);
|
||||
B.putInt("Amount", Amount);
|
||||
B.putInt("Height", Height);
|
||||
B.putString("Raw", Raw);
|
||||
return B;
|
||||
}
|
||||
|
||||
public void loadFromBundle(Bundle B) {
|
||||
txID = B.getString("txID");
|
||||
Amount = B.getInt("Amount");
|
||||
Height = B.getInt("Height");
|
||||
Raw = B.getString("Raw");
|
||||
}
|
||||
}
|
||||
|
||||
private List<UnspentTransaction> unspentTransactions = null;
|
||||
|
||||
public List<UnspentTransaction> getUnspentTransactions() {
|
||||
if (unspentTransactions == null) unspentTransactions = new ArrayList<>();
|
||||
return unspentTransactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromBundle(Bundle B) {
|
||||
super.loadFromBundle(B);
|
||||
|
||||
if (B.containsKey("BalanceConfirmed")) balanceConfirmed = B.getLong("BalanceConfirmed");
|
||||
else balanceConfirmed = null;
|
||||
if (B.containsKey("BalanceUnconfirmed"))
|
||||
balanceUnconfirmed = B.getLong("BalanceUnconfirmed");
|
||||
else balanceUnconfirmed = null;
|
||||
if (B.containsKey("UnspentTransactions")) {
|
||||
unspentTransactions = new ArrayList<>();
|
||||
Bundle BB = B.getBundle("UnspentTransactions");
|
||||
Integer i = 0;
|
||||
while (BB.containsKey(i.toString())) {
|
||||
UnspentTransaction t = new UnspentTransaction();
|
||||
t.loadFromBundle(BB.getBundle(i.toString()));
|
||||
unspentTransactions.add(t);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToBundle(Bundle B) {
|
||||
super.saveToBundle(B);
|
||||
try {
|
||||
if (unspentTransactions != null) {
|
||||
Bundle BB = new Bundle();
|
||||
for (Integer i = 0; i < unspentTransactions.size(); i++) {
|
||||
BB.putBundle(i.toString(), unspentTransactions.get(i).getAsBundle());
|
||||
}
|
||||
B.putBundle("UnspentTransactions", BB);
|
||||
}
|
||||
if (balanceConfirmed != null) B.putLong("BalanceConfirmed", balanceConfirmed);
|
||||
if (balanceUnconfirmed != null) B.putLong("BalanceUnconfirmed", balanceUnconfirmed);
|
||||
} catch (Exception e) {
|
||||
Log.e("Can't save to bundle ", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearInfo() {
|
||||
super.clearInfo();
|
||||
balanceConfirmed = null;
|
||||
balanceUnconfirmed = null;
|
||||
unspentTransactions = null;
|
||||
}
|
||||
|
||||
public CoinEngine.InternalAmount getBalanceInInternalUnits() {
|
||||
return new CoinEngine.InternalAmount(BigDecimal.valueOf(balanceConfirmed).add(BigDecimal.valueOf(balanceUnconfirmed)));
|
||||
}
|
||||
|
||||
public Long getBalanceUnconfirmed() {
|
||||
return balanceUnconfirmed;
|
||||
}
|
||||
|
||||
public void setBalanceConfirmed(Long balance) {
|
||||
this.balanceConfirmed = balance;
|
||||
}
|
||||
|
||||
public void setBalanceUnconfirmed(Long balance) {
|
||||
this.balanceUnconfirmed = balance;
|
||||
}
|
||||
|
||||
public boolean hasBalanceInfo() {
|
||||
return balanceConfirmed != null || balanceUnconfirmed != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.domain.BitcoinNode;
|
||||
import com.tangem.domain.BitcoinNodeTestNet;
|
||||
|
|
@ -8,12 +9,12 @@ import com.tangem.domain.cardReader.CardProtocol;
|
|||
import com.tangem.domain.cardReader.TLV;
|
||||
import com.tangem.util.BTCUtils;
|
||||
import com.tangem.util.CryptoUtil;
|
||||
import com.tangem.util.DecimalDigitsInputFilter;
|
||||
import com.tangem.util.DerEncodingUtil;
|
||||
import com.tangem.util.FormatUtil;
|
||||
import com.tangem.util.Util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
|
@ -21,12 +22,27 @@ import java.security.NoSuchProviderException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.tangem.util.FormatUtil.stringToBigDecimal;
|
||||
|
||||
public class BtcEngine extends CoinEngine {
|
||||
|
||||
public BtcData btcData = null;
|
||||
|
||||
public BtcEngine(TangemContext context) throws Exception {
|
||||
super(context);
|
||||
if (context.getCoinData() == null) {
|
||||
btcData = new BtcData();
|
||||
context.setCoinData(btcData);
|
||||
} else if (context.getCoinData() instanceof BtcData) {
|
||||
btcData = (BtcData) context.getCoinData();
|
||||
} else {
|
||||
throw new Exception("Invalid type of Blockchain data for BtcEngine");
|
||||
}
|
||||
}
|
||||
|
||||
public BtcEngine() {
|
||||
super();
|
||||
}
|
||||
|
||||
private static String[] getBitcoinServiceHosts() {
|
||||
return new String[]{
|
||||
BitcoinNode.n1.getHost(),
|
||||
|
|
@ -79,80 +95,70 @@ public class BtcEngine extends CoinEngine {
|
|||
|
||||
static int serviceIndex = 0;
|
||||
|
||||
public String getNode(TangemCard card) {
|
||||
switch (card.getBlockchain()) {
|
||||
case Bitcoin:
|
||||
return getBitcoinServiceHosts()[serviceIndex]; //
|
||||
private void checkBlockchainDataExists() throws Exception {
|
||||
if (btcData == null) throw new Exception("No blockchain data");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean awaitingConfirmation(){
|
||||
if( btcData==null ) return false;
|
||||
return btcData.getBalanceUnconfirmed() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceHTML() {
|
||||
if (hasBalanceInfo()) {
|
||||
Amount balance = convertToAmount(btcData.getBalanceInInternalUnits());
|
||||
return balance.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getNodePort(TangemCard card) {
|
||||
switch (card.getBlockchain()) {
|
||||
case Bitcoin:
|
||||
return getBitcoinServicePorts()[serviceIndex];//8080;
|
||||
}
|
||||
return 8080;
|
||||
}
|
||||
|
||||
public void switchNode(TangemCard card) {
|
||||
serviceIndex++;
|
||||
if (serviceIndex > getBitcoinServiceHosts().length - 1) serviceIndex = 0;
|
||||
}
|
||||
|
||||
public boolean inOutPutVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean awaitingConfirmation(TangemCard card) {
|
||||
return card.getBalanceUnconfirmed() != 0;
|
||||
}
|
||||
|
||||
public String getBalanceWithAlter(TangemCard card) {
|
||||
return getBalance(card);
|
||||
}
|
||||
|
||||
public boolean isBalanceAlterNotZero(TangemCard card) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Long getBalanceLong(TangemCard card) {
|
||||
return card.getBalance();
|
||||
}
|
||||
|
||||
public boolean isBalanceNotZero(TangemCard card) {
|
||||
if (card.getBalance() == null) return false;
|
||||
return card.getBalance() > 0;
|
||||
}
|
||||
|
||||
public boolean checkAmount(TangemCard card, String amount) throws Exception {
|
||||
// DecimalFormat decimalFormat = GetDecimalFormat();
|
||||
// BigDecimal amountValue = (BigDecimal) decimalFormat.parse(amount);
|
||||
BigDecimal amountValue = stringToBigDecimal(amount, Locale.US);
|
||||
BigDecimal maxValue = stringToBigDecimal(getBalanceValue(card), Locale.US);
|
||||
if (amountValue.compareTo(maxValue) > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasBalanceInfo(TangemCard card) {
|
||||
return card.hasBalanceInfo();
|
||||
}
|
||||
|
||||
public String getBalanceCurrency(TangemCard card) {
|
||||
@Override
|
||||
public String getBalanceCurrencyHTML() {
|
||||
return "BTC";
|
||||
}
|
||||
|
||||
public boolean checkUnspentTransaction(TangemCard card) {
|
||||
return card.getUnspentTransactions().size() != 0;
|
||||
@Override
|
||||
public String getOfflineBalanceHTML() {
|
||||
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
|
||||
Amount offlineAmount = convertToAmount(offlineInternalAmount);
|
||||
return offlineAmount.toString();
|
||||
}
|
||||
|
||||
public String getFeeCurrency() {
|
||||
@Override
|
||||
public boolean isBalanceAlterNotZero() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBalanceNotZero() {
|
||||
if( btcData==null ) return false;
|
||||
if (btcData.getBalanceInInternalUnits() == null) return false;
|
||||
return btcData.getBalanceInInternalUnits().notZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBalanceInfo(){
|
||||
if( btcData==null ) return false;
|
||||
return btcData.hasBalanceInfo();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkUnspentTransaction() throws Exception {
|
||||
checkBlockchainDataExists();
|
||||
return btcData.getUnspentTransactions().size() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeeCurrencyHTML() {
|
||||
return "BTC";
|
||||
}
|
||||
|
||||
public boolean validateAddress(String address, TangemCard card) {
|
||||
@Override
|
||||
public boolean validateAddress(String address) {
|
||||
if (address == null || address.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -187,11 +193,11 @@ public class BtcEngine extends CoinEngine {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (card.getBlockchain() != Blockchain.BitcoinTestNet && card.getBlockchain() != Blockchain.Bitcoin) {
|
||||
if (ctx.getBlockchain() != Blockchain.BitcoinTestNet && ctx.getBlockchain() != Blockchain.Bitcoin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (card.getBlockchain() == Blockchain.BitcoinTestNet && (address.startsWith("1") || address.startsWith("3"))) {
|
||||
if (ctx.getBlockchain() == Blockchain.BitcoinTestNet && (address.startsWith("1") || address.startsWith("3"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -199,37 +205,48 @@ public class BtcEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
|
||||
public int getTokenDecimals(TangemCard card) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getContractAddress(TangemCard card) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNeedCheckNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Uri getShareWalletUriExplorer(TangemCard card) {
|
||||
return Uri.parse((card.getBlockchain() == Blockchain.Bitcoin ? "https://blockchain.info/address/" : "https://testnet.blockchain.info/address/") + card.getWallet());
|
||||
@Override
|
||||
public Uri getShareWalletUriExplorer() {
|
||||
return Uri.parse((ctx.getBlockchain() == Blockchain.Bitcoin ? "https://blockchain.info/address/" : "https://testnet.blockchain.info/address/") + ctx.getCard().getWallet());
|
||||
}
|
||||
|
||||
public Uri getShareWalletUri(TangemCard card) {
|
||||
if (card.getDenomination() != null) {
|
||||
return Uri.parse("bitcoin:" + card.getWallet() + "?amount=" + BTCUtils.satoshiToBtc(card.getDenomination()));
|
||||
@Override
|
||||
public Uri getShareWalletUri() {
|
||||
if (ctx.getCard().getDenomination() != null) {
|
||||
return Uri.parse("bitcoin:" + ctx.getCard().getWallet() + "?amount=" + BTCUtils.satoshiToBtc(ctx.getCard().getDenomination()));
|
||||
} else {
|
||||
return Uri.parse("bitcoin:" + card.getWallet());
|
||||
return Uri.parse("bitcoin:" + ctx.getCard().getWallet());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputFilter[] getAmountInputFilters() {
|
||||
return new InputFilter[] { new DecimalDigitsInputFilter(8) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkNewTransactionAmount(Amount amount){
|
||||
if( btcData==null ) return false;
|
||||
if (amount.compareTo(convertToAmount(btcData.getBalanceInInternalUnits())) > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkNewTransactionAmountAndFee(Amount amountValue, Amount feeValue, Boolean isIncludeFee, InternalAmount minFeeInInternalUnits) {
|
||||
InternalAmount fee;
|
||||
InternalAmount amount;
|
||||
|
||||
public boolean checkAmountValue(TangemCard card, String amountValue, String feeValue, Long minFeeInInternalUnits, Boolean isIncludeFee) {
|
||||
Long fee;
|
||||
Long amount;
|
||||
try {
|
||||
amount = card.internalUnitsFromString(amountValue);
|
||||
fee = card.internalUnitsFromString(feeValue);
|
||||
checkBlockchainDataExists();
|
||||
amount = convertToInternalAmount(amountValue);
|
||||
fee = convertToInternalAmount(feeValue);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
|
|
@ -238,63 +255,105 @@ public class BtcEngine extends CoinEngine {
|
|||
if (fee == null || amount == null)
|
||||
return false;
|
||||
|
||||
if (fee == 0 || amount == 0)
|
||||
if (fee.isZero() || amount.isZero())
|
||||
return false;
|
||||
|
||||
if (isIncludeFee && amount > card.getBalance())
|
||||
if (isIncludeFee && amount.compareTo(btcData.getBalanceInInternalUnits())>0)
|
||||
return false;
|
||||
|
||||
if (!isIncludeFee && amount + fee > card.getBalance())
|
||||
if (!isIncludeFee && amount.add(fee).compareTo(btcData.getBalanceInInternalUnits())>0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String evaluateFeeEquivalent(TangemCard card, String fee) {
|
||||
return getAmountEquivalentDescriptor(card, fee);
|
||||
@Override
|
||||
public boolean validateBalance(BalanceValidator balanceValidator) {
|
||||
if (((ctx.getCard().getOfflineBalance() == null) && !ctx.getCoinData().isBalanceReceived()) || (!ctx.getCoinData().isBalanceReceived() && (ctx.getCard().getRemainingSignatures() != ctx.getCard().getMaxSignatures()))) {
|
||||
balanceValidator.setScore(0);
|
||||
balanceValidator.setFirstLine("Unknown balance");
|
||||
balanceValidator.setSecondLine("Balance cannot be verified. Swipe down to refresh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Workaround before new back-end
|
||||
// if (card.getRemainingSignatures() == card.getMaxSignatures()) {
|
||||
// firstLine = "Verified balance";
|
||||
// secondLine = "Balance confirmed in blockchain. ";
|
||||
// secondLine += "Verified note identity. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (btcData.getBalanceUnconfirmed() != 0) {
|
||||
balanceValidator.setScore(0);
|
||||
balanceValidator.setFirstLine("Transaction in progress");
|
||||
balanceValidator.setSecondLine("Wait for confirmation in blockchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (btcData.isBalanceReceived() && btcData.isBalanceEqual()) {
|
||||
balanceValidator.setScore(100);
|
||||
balanceValidator.setFirstLine("Verified balance");
|
||||
balanceValidator.setSecondLine("Balance confirmed in blockchain");
|
||||
if (btcData.getBalanceInInternalUnits().isZero()) {
|
||||
balanceValidator.setFirstLine("Empty wallet");
|
||||
balanceValidator.setSecondLine("");
|
||||
}
|
||||
}
|
||||
|
||||
// rule 4 TODO: need to check SignedHashed against number of outputs in blockchain
|
||||
// if((card.getRemainingSignatures() != card.getMaxSignatures()) && card.getBalance() != 0)
|
||||
// {
|
||||
// score = 80;
|
||||
// firstLine = "Unguaranteed balance";
|
||||
// secondLine = "Potential unsent transaction. Redeem immediately if accept. ";
|
||||
// return;
|
||||
// }
|
||||
|
||||
if ((ctx.getCard().getOfflineBalance() != null) && !btcData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && btcData.getBalanceInInternalUnits().notZero() ) {
|
||||
balanceValidator.setScore(80);
|
||||
balanceValidator.setFirstLine("Verified offline balance");
|
||||
balanceValidator.setSecondLine("Can't obtain balance from blockchain. Restore internet connection to be more confident. ");
|
||||
}
|
||||
|
||||
// if(card.getFailedBalanceRequestCounter()!=0) {
|
||||
// score -= 5 * card.getFailedBalanceRequestCounter();
|
||||
// secondLine += "Not all nodes have returned balance. Swipe down or tap again. ";
|
||||
// if(score <= 0)
|
||||
// return;
|
||||
// }
|
||||
|
||||
//
|
||||
// if(card.isBalanceReceived() && !card.isBalanceEqual()) {
|
||||
// score = 0;
|
||||
// firstLine = "Disputed balance";
|
||||
// secondLine += " Cannot obtain trusted balance at the moment. Try to tap and check this banknote later.";
|
||||
// return;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceEquivalent(TangemCard card) {
|
||||
Double balance = Double.NaN;
|
||||
try {
|
||||
Long val = card.getBalance();
|
||||
balance = card.amountFromInternalUnits(val);
|
||||
} catch (Exception ex) {
|
||||
card.setRate(0);
|
||||
}
|
||||
|
||||
return card.getAmountEquivalentDescription(balance);
|
||||
public Amount getBalance() {
|
||||
return convertToAmount(btcData.getBalanceInInternalUnits());
|
||||
}
|
||||
|
||||
public String getBalance(TangemCard card) {
|
||||
if (card.hasBalanceInfo()) {
|
||||
Double balance = card.amountFromInternalUnits(card.getBalance());
|
||||
return card.getAmountDescription(balance);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public String evaluateFeeEquivalent(String fee) {
|
||||
return getAmountEquivalentDescriptor(ctx.getCard(), fee);
|
||||
}
|
||||
|
||||
public String getBalanceValue(TangemCard card) {
|
||||
if (card.hasBalanceInfo()) {
|
||||
Double balance = card.getBalance() / (card.getBlockchain().getMultiplier());
|
||||
|
||||
String output = FormatUtil.DoubleToString(balance);
|
||||
//String pattern = "#0.000"; // If you like 4 zeros
|
||||
//DecimalFormat myFormatter = new DecimalFormat(pattern);
|
||||
//String output = myFormatter.format(balance);
|
||||
return output;
|
||||
|
||||
//return Double.toString(balance);
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
@Override
|
||||
public String getBalanceEquivalent() {
|
||||
if( btcData==null ) return "";
|
||||
return btcData.getAmountEquivalentDescription(getBalance());
|
||||
}
|
||||
|
||||
public String calculateAddress(TangemCard card, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
@Override
|
||||
public String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
byte netSelectionByte;
|
||||
switch (card.getBlockchain()) {
|
||||
switch (ctx.getBlockchain()) {
|
||||
case Bitcoin:
|
||||
netSelectionByte = (byte) 0x00; //0 - MainNet 0x6f - TestNet
|
||||
break;
|
||||
|
|
@ -326,26 +385,54 @@ public class BtcEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String convertByteArrayToAmount(TangemCard card, byte[] bytes) throws Exception {
|
||||
if (bytes == null) return "";
|
||||
byte[] reversed = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
|
||||
return FormatUtil.DoubleToString(card.amountFromInternalUnits(Util.byteArrayToLong(reversed)));
|
||||
public Amount convertToAmount(InternalAmount internalAmount) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] convertAmountToByteArray(TangemCard card, String amount) throws Exception {
|
||||
byte[] bytes = Util.longToByteArray(card.internalUnitsFromString(amount));
|
||||
public Amount convertToAmount(String strAmount) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalAmount convertToInternalAmount(byte[] bytes) {
|
||||
if (bytes == null) return null;
|
||||
byte[] reversed = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
|
||||
return new InternalAmount(Util.byteArrayToLong(reversed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] convertToByteArray(InternalAmount internalAmount) throws Exception {
|
||||
byte[] bytes = Util.longToByteArray(internalAmount.longValueExact());
|
||||
byte[] reversed = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) reversed[i] = bytes[bytes.length - i - 1];
|
||||
return reversed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAmountDescription(TangemCard card, String amount) throws Exception {
|
||||
return card.getAmountDescription(Double.parseDouble(amount));
|
||||
public CoinData createCoinData() {
|
||||
return new BtcData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnspentInputsDescription() {
|
||||
return btcData.getUnspentInputsDescription();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getAmountDescription(TangemCard card, String amount) throws Exception {
|
||||
// return card.getAmountDescription(Double.parseDouble(amount));
|
||||
// }
|
||||
|
||||
public static String getAmountEquivalentDescriptionBTC(Double amount, float rate) {
|
||||
if ((rate > 0) && (amount > 0)) {
|
||||
return String.format("≈ USD %.2f", amount * rate);
|
||||
|
|
@ -355,18 +442,22 @@ public class BtcEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
public String getAmountEquivalentDescriptor(TangemCard card, String value) {
|
||||
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), card.getRate());
|
||||
|
||||
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), btcData.getRate());
|
||||
}
|
||||
|
||||
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, TangemCard card, CardProtocol protocol) throws Exception {
|
||||
@Override
|
||||
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
|
||||
|
||||
String myAddress = card.getWallet();
|
||||
byte[] pbKey = card.getWalletPublicKey();
|
||||
checkBlockchainDataExists();
|
||||
|
||||
String myAddress = ctx.getCard().getWallet();
|
||||
byte[] pbKey = ctx.getCard().getWalletPublicKey();
|
||||
String outputAddress = toValue;
|
||||
String changeAddress = myAddress;
|
||||
|
||||
// Build script for our address
|
||||
List<TangemCard.UnspentTransaction> rawTxList = card.getUnspentTransactions();
|
||||
List<BtcData.UnspentTransaction> rawTxList = btcData.getUnspentTransactions();
|
||||
byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
|
||||
|
||||
// Collect unspent
|
||||
|
|
@ -402,7 +493,7 @@ public class BtcEngine extends CoinEngine {
|
|||
unspentOutputs.get(i).bodyDoubleHash = doubleHashData;
|
||||
unspentOutputs.get(i).bodyHash = hashData;
|
||||
|
||||
if (card.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || card.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
if (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
dataForSign[i] = newTX;
|
||||
} else {
|
||||
dataForSign[i] = doubleHashData;
|
||||
|
|
@ -410,7 +501,7 @@ public class BtcEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
byte[] signFromCard;
|
||||
if (card.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || card.getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
if (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw || ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Raw_Validated_By_Issuer) {
|
||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||
if (dataForSign.length > 10) throw new Exception("To much hashes in one transaction!");
|
||||
for (int i = 0; i < dataForSign.length; i++) {
|
||||
|
|
@ -420,21 +511,19 @@ public class BtcEngine extends CoinEngine {
|
|||
}
|
||||
signFromCard = protocol.run_SignRaw(PINStorage.getPIN2(), bs.toByteArray()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
} else {
|
||||
signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), dataForSign, card.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer, null, card.getIssuer()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), dataForSign, ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer, null, ctx.getCard().getIssuer()).getTLV(TLV.Tag.TAG_Signature).Value;
|
||||
// TODO slice signFromCard to hashes.length parts
|
||||
}
|
||||
|
||||
for (int i = 0; i < unspentOutputs.size(); ++i) {
|
||||
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0 + i * 64, 32 + i * 64));
|
||||
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, i * 64, 32 + i * 64));
|
||||
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64));
|
||||
s = CryptoUtil.toCanonicalised(s);
|
||||
byte[] encodingSign = DerEncodingUtil.packSignDer(r, s, pbKey);
|
||||
|
||||
unspentOutputs.get(i).scriptForBuild = encodingSign;
|
||||
unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDer(r, s, pbKey);
|
||||
}
|
||||
|
||||
byte[] realTX = BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
|
||||
return realTX;
|
||||
return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change);
|
||||
}
|
||||
|
||||
}
|
||||
175
app/src/main/java/com/tangem/domain/wallet/CoinData.java
Normal file
175
app/src/main/java/com/tangem/domain/wallet/CoinData.java
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class CoinData {
|
||||
|
||||
public CoinData() {
|
||||
}
|
||||
|
||||
public boolean isBalanceReceived() {
|
||||
return balanceReceived;
|
||||
}
|
||||
|
||||
private boolean balanceReceived = false;
|
||||
|
||||
public void setBalanceReceived(boolean value) {
|
||||
balanceReceived = value;
|
||||
}
|
||||
|
||||
public void loadFromBundle(Bundle B) {
|
||||
if (B.containsKey("balanceReceived")) setBalanceReceived(B.getBoolean("balanceReceived"));
|
||||
|
||||
validationNodeDescription = B.getString("validationNodeDescription");
|
||||
|
||||
if (B.containsKey("FailedBalance"))
|
||||
failedBalanceRequestCounter = new AtomicInteger(B.getInt("FailedBalance"));
|
||||
|
||||
if (B.containsKey("isBalanceEqual")) setIsBalanceEqual(B.getBoolean("isBalanceEqual"));
|
||||
|
||||
if (B.containsKey("rate"))
|
||||
rate = B.getFloat("rate");
|
||||
if (B.containsKey("rateAlter"))
|
||||
rateAlter = B.getFloat("rateAlter");
|
||||
}
|
||||
|
||||
public void saveToBundle(Bundle B) {
|
||||
try {
|
||||
if (balanceEqual != null) B.putBoolean("isBalanceEqual", balanceEqual);
|
||||
|
||||
if (failedBalanceRequestCounter != null)
|
||||
B.putInt("FailedBalance", failedBalanceRequestCounter.get());
|
||||
|
||||
B.putFloat("rate", rate);
|
||||
B.putFloat("rateAlter", rateAlter);
|
||||
|
||||
B.putBoolean("balanceReceived", balanceReceived);
|
||||
B.putString("validationNodeDescription", validationNodeDescription);
|
||||
} catch (Exception e) {
|
||||
Log.e("Can't save to bundle ", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Bundle asBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
saveToBundle(bundle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static CoinData fromBundle(Blockchain blockchain, Bundle bundle) {
|
||||
CoinEngine engine=CoinEngineFactory.create(blockchain);
|
||||
if( engine==null ) return null;
|
||||
CoinData result = engine.createCoinData();
|
||||
result.loadFromBundle(bundle);
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO - move all to special engines
|
||||
private float rate = 0;
|
||||
private float rateAlter = 0;
|
||||
|
||||
public float getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public float getRateAlter() {
|
||||
return rateAlter;
|
||||
}
|
||||
|
||||
public void setRate(float rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public void setRateAlter(float rate) {
|
||||
this.rateAlter = rate;
|
||||
}
|
||||
|
||||
// public Double amountFromInternalUnits(Long internalAmount) {
|
||||
// // TODO java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
|
||||
// return ((double) internalAmount) /
|
||||
// getBlockchain().getMultiplier();
|
||||
// }
|
||||
//
|
||||
// public Double amountFromInternalUnits(Integer internalAmount) {
|
||||
// return ((double) internalAmount) / getBlockchain().getMultiplier();
|
||||
// }
|
||||
//
|
||||
// // TODO разобраться с балансами, привести к единому интерфейсу
|
||||
// public Long internalUnitsFromString(String caption) {
|
||||
// try {
|
||||
// return FormatUtil.ConvertStringToLong(caption);
|
||||
// } catch (Exception e) {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public String getAmountDescription(Double amount) {
|
||||
// String output = FormatUtil.DoubleToString(amount);
|
||||
// return output + " " + getBlockchain().getCurrency();
|
||||
// }
|
||||
|
||||
public String getAmountEquivalentDescription(CoinEngine.Amount amount) {
|
||||
if (getBlockchain() == Blockchain.Ethereum || getBlockchain() == Blockchain.EthereumTestNet || getBlockchain() == Blockchain.Token) {
|
||||
return EthEngine.getAmountEquivalentDescriptionETH(amount, rate);
|
||||
}
|
||||
|
||||
return BtcEngine.getAmountEquivalentDescriptionBTC(amount.doubleValue(), rate);
|
||||
}
|
||||
|
||||
public boolean getAmountEquivalentDescriptionAvailable() {
|
||||
return rate > 0;
|
||||
}
|
||||
|
||||
|
||||
public void clearInfo() {
|
||||
setIsBalanceEqual(false);
|
||||
}
|
||||
|
||||
private AtomicInteger failedBalanceRequestCounter;
|
||||
|
||||
public int incFailedBalanceRequestCounter() {
|
||||
if (failedBalanceRequestCounter == null)
|
||||
failedBalanceRequestCounter = new AtomicInteger(0);
|
||||
return failedBalanceRequestCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
public void resetFailedBalanceRequestCounter() {
|
||||
failedBalanceRequestCounter = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public int getFailedBalanceRequestCounter() {
|
||||
if (failedBalanceRequestCounter == null)
|
||||
return 0;
|
||||
return failedBalanceRequestCounter.get();
|
||||
}
|
||||
|
||||
private Boolean balanceEqual;
|
||||
|
||||
public Boolean isBalanceEqual() {
|
||||
return balanceEqual;
|
||||
}
|
||||
|
||||
public void setIsBalanceEqual(boolean isEqual) {
|
||||
balanceEqual = isEqual;
|
||||
}
|
||||
|
||||
private String validationNodeDescription = "";
|
||||
|
||||
public String getValidationNodeDescription() {
|
||||
return validationNodeDescription;
|
||||
}
|
||||
|
||||
public void setValidationNodeDescription(String validationNodeDescription) {
|
||||
this.validationNodeDescription = validationNodeDescription;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
|
||||
import com.tangem.domain.cardReader.CardProtocol;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
|
||||
|
|
@ -13,66 +17,150 @@ import java.security.NoSuchProviderException;
|
|||
|
||||
public abstract class CoinEngine {
|
||||
|
||||
public abstract String getNode(TangemCard card);
|
||||
@Nullable
|
||||
public static final String EXTRA_ENGINE = "CoinEngine";
|
||||
|
||||
public abstract int getNodePort(TangemCard card);
|
||||
public static class InternalAmount extends BigDecimal {
|
||||
public InternalAmount() {
|
||||
super(0);
|
||||
}
|
||||
|
||||
public abstract void switchNode(TangemCard card);
|
||||
public InternalAmount(String amountString) {
|
||||
super(amountString);
|
||||
}
|
||||
|
||||
public abstract boolean awaitingConfirmation(TangemCard card);
|
||||
public InternalAmount(long amount) {
|
||||
super(amount);
|
||||
}
|
||||
|
||||
public abstract boolean hasBalanceInfo(TangemCard card);
|
||||
public InternalAmount(BigDecimal amount) {
|
||||
super(amount.unscaledValue(), amount.scale());
|
||||
}
|
||||
|
||||
public abstract boolean isBalanceNotZero(TangemCard card);
|
||||
public boolean notZero()
|
||||
{
|
||||
return compareTo(BigDecimal.ZERO)>0;
|
||||
}
|
||||
|
||||
public abstract boolean isBalanceAlterNotZero(TangemCard card);
|
||||
public boolean isZero() {
|
||||
return compareTo(BigDecimal.ZERO)==0;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean checkAmount(TangemCard card, String amount) throws Exception;
|
||||
public static class Amount extends BigDecimal {
|
||||
private Blockchain blockchain;
|
||||
|
||||
public abstract int getTokenDecimals(TangemCard card);
|
||||
public Amount() {
|
||||
super(0);
|
||||
blockchain = Blockchain.Unknown;
|
||||
}
|
||||
|
||||
public abstract String getContractAddress(TangemCard card);
|
||||
public Amount(String amountString, Blockchain blockchain) {
|
||||
super(amountString);
|
||||
this.blockchain = blockchain;
|
||||
}
|
||||
|
||||
public abstract byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, TangemCard mCard, CardProtocol protocol) throws Exception;
|
||||
public Amount(Long amount, Blockchain blockchain) {
|
||||
super(amount);
|
||||
this.blockchain=blockchain;
|
||||
}
|
||||
|
||||
public abstract boolean checkUnspentTransaction(TangemCard card);
|
||||
public String getCurrency() {
|
||||
return blockchain.getCurrency();
|
||||
}
|
||||
|
||||
public abstract Uri getShareWalletUriExplorer(TangemCard card);
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " " + blockchain.getCurrency();
|
||||
}
|
||||
|
||||
public abstract Long getBalanceLong(TangemCard card);
|
||||
public boolean notZero()
|
||||
{
|
||||
return compareTo(BigDecimal.ZERO)>0;
|
||||
}
|
||||
|
||||
public abstract Uri getShareWalletUri(TangemCard card);
|
||||
public String getStringToEdit() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
public abstract String evaluateFeeEquivalent(TangemCard card, String fee);
|
||||
}
|
||||
|
||||
public abstract boolean checkAmountValue(TangemCard card, String amount, String fee, Long minFeeInInternalUnits, Boolean incfee);
|
||||
protected TangemContext ctx;
|
||||
|
||||
public abstract boolean inOutPutVisible();
|
||||
public CoinEngine() {
|
||||
|
||||
public abstract String getBalance(TangemCard card);
|
||||
}
|
||||
|
||||
public abstract String getBalanceWithAlter(TangemCard card);
|
||||
public CoinEngine(TangemContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public abstract String getBalanceCurrency(TangemCard card);
|
||||
public abstract boolean awaitingConfirmation();
|
||||
|
||||
public abstract String getFeeCurrency();
|
||||
public abstract boolean hasBalanceInfo();
|
||||
|
||||
public abstract boolean isBalanceNotZero();
|
||||
|
||||
public abstract boolean isBalanceAlterNotZero();
|
||||
|
||||
public abstract byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception;
|
||||
|
||||
public abstract boolean checkUnspentTransaction() throws Exception;
|
||||
|
||||
public abstract Uri getShareWalletUriExplorer();
|
||||
|
||||
public abstract Uri getShareWalletUri();
|
||||
|
||||
// public abstract Long getBalanceLong(TangemCard card);
|
||||
|
||||
public abstract boolean checkNewTransactionAmount(Amount amount);
|
||||
|
||||
// TODO - move minFeeInInternalUnits to CoinData
|
||||
public abstract boolean checkNewTransactionAmountAndFee(Amount amount, Amount fee, Boolean isFeeIncluded, InternalAmount minFeeInInternalUnits);
|
||||
|
||||
public abstract boolean validateBalance(BalanceValidator balanceValidator);
|
||||
|
||||
public abstract Amount getBalance();
|
||||
|
||||
public abstract String getBalanceHTML();
|
||||
|
||||
public abstract String getBalanceCurrencyHTML();
|
||||
|
||||
public abstract InputFilter[] getAmountInputFilters();
|
||||
|
||||
public abstract String getOfflineBalanceHTML();
|
||||
|
||||
public abstract String evaluateFeeEquivalent(String fee);
|
||||
|
||||
public abstract String getFeeCurrencyHTML();
|
||||
|
||||
public abstract boolean isNeedCheckNode();
|
||||
|
||||
public abstract String getBalanceEquivalent(TangemCard card);
|
||||
public abstract String getBalanceEquivalent();
|
||||
|
||||
public abstract String getBalanceValue(TangemCard card);
|
||||
// public abstract String getBalanceValue(TangemCard card);
|
||||
|
||||
public abstract String getAmountDescription(TangemCard card, String amount) throws Exception;
|
||||
// public abstract String getAmountDescription(TangemCard card, String amount) throws Exception;
|
||||
|
||||
public abstract String getAmountEquivalentDescriptor(TangemCard card, String value);
|
||||
// public abstract String getAmountEquivalentDescriptor(TangemCard card, String value);
|
||||
|
||||
public abstract boolean validateAddress(String address, TangemCard card);
|
||||
public abstract boolean validateAddress(String address);
|
||||
|
||||
public abstract String calculateAddress(TangemCard card, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException;
|
||||
public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException;
|
||||
|
||||
public abstract String convertByteArrayToAmount(TangemCard card, byte[] bytes) throws Exception;
|
||||
public abstract Amount convertToAmount(InternalAmount internalAmount);
|
||||
public abstract Amount convertToAmount(String strAmount);
|
||||
|
||||
public abstract byte[] convertAmountToByteArray(TangemCard card, String amount) throws Exception;
|
||||
public abstract InternalAmount convertToInternalAmount(Amount amount) throws Exception;
|
||||
public abstract InternalAmount convertToInternalAmount(byte[] bytes) throws Exception;
|
||||
|
||||
public abstract byte[] convertToByteArray(InternalAmount internalAmount) throws Exception;
|
||||
|
||||
|
||||
// public abstract CoinEngine swithToBaseEngine();
|
||||
|
||||
public abstract CoinData createCoinData();
|
||||
|
||||
public abstract String getUnspentInputsDescription();
|
||||
|
||||
}
|
||||
|
|
@ -5,17 +5,37 @@ package com.tangem.domain.wallet;
|
|||
*/
|
||||
|
||||
public class CoinEngineFactory {
|
||||
public static CoinEngine create(Blockchain chain) {
|
||||
if (Blockchain.BitcoinCash == chain || Blockchain.BitcoinCashTestNet == chain) {
|
||||
return new BtcCashEngine();
|
||||
} else if (Blockchain.Bitcoin == chain || Blockchain.BitcoinTestNet == chain) {
|
||||
return new BtcEngine(); //TODO: ВРЕМЕНГГО!!!!
|
||||
} else if (Blockchain.Ethereum == chain || Blockchain.EthereumTestNet == chain) {
|
||||
return new EthEngine();
|
||||
} else if (Blockchain.Token == chain) {
|
||||
return new TokenEngine();
|
||||
public static CoinEngine create(Blockchain blockchain) {
|
||||
switch (blockchain) {
|
||||
case Bitcoin:
|
||||
case BitcoinTestNet:
|
||||
return new BtcEngine();
|
||||
case BitcoinCash:
|
||||
case BitcoinCashTestNet:
|
||||
return new BtcCashEngine();
|
||||
case Ethereum:
|
||||
case EthereumTestNet:
|
||||
return new EthEngine();
|
||||
case Token:
|
||||
return new TokenEngine();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CoinEngine create(TangemContext context) {
|
||||
CoinEngine result;
|
||||
if (Blockchain.BitcoinCash == context.getBlockchain() || Blockchain.BitcoinCashTestNet == context.getBlockchain()) {
|
||||
result = new BtcCashEngine(context);
|
||||
} else if (Blockchain.Bitcoin == context.getBlockchain() || Blockchain.BitcoinTestNet == context.getBlockchain()) {
|
||||
result = new BtcEngine(context);
|
||||
} else if (Blockchain.Ethereum == context.getBlockchain() || Blockchain.EthereumTestNet == context.getBlockchain()) {
|
||||
result = new EthEngine(context);
|
||||
} else if (Blockchain.Token == context.getBlockchain()) {
|
||||
result = new TokenEngine(context);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
114
app/src/main/java/com/tangem/domain/wallet/EthData.java
Normal file
114
app/src/main/java/com/tangem/domain/wallet/EthData.java
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class EthData extends CoinData
|
||||
{
|
||||
private CoinEngine.InternalAmount balance=null;
|
||||
private CoinEngine.InternalAmount balanceAlter=null;
|
||||
|
||||
private BigInteger countConfirmedTX = null;
|
||||
private BigInteger countUnconfirmedTX = BigInteger.valueOf(0);
|
||||
|
||||
public BigInteger getConfirmedTXCount() {
|
||||
if (countConfirmedTX == null) {
|
||||
countConfirmedTX = BigInteger.valueOf(0);
|
||||
}
|
||||
return countConfirmedTX;
|
||||
}
|
||||
|
||||
public void setConfirmedTXCount(BigInteger count) {
|
||||
countConfirmedTX = count;
|
||||
}
|
||||
|
||||
public BigInteger getUnconfirmedTXCount() {
|
||||
if (countUnconfirmedTX == null) {
|
||||
countUnconfirmedTX = BigInteger.valueOf(0);
|
||||
}
|
||||
return countUnconfirmedTX;
|
||||
}
|
||||
|
||||
public void setUnconfirmedTXCount(BigInteger count) {
|
||||
countUnconfirmedTX = count;
|
||||
}
|
||||
|
||||
public String getAmountInGwei(String amount) {
|
||||
BigInteger d = new BigInteger(amount, 10);
|
||||
BigInteger m = d.divide(BigInteger.valueOf(1000000000L));
|
||||
return m.toString(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearInfo() {
|
||||
super.clearInfo();
|
||||
balance = null;
|
||||
balanceAlter = null;
|
||||
}
|
||||
|
||||
public CoinEngine.InternalAmount getBalanceInInternalUnits() {
|
||||
return balance;
|
||||
|
||||
}
|
||||
public CoinEngine.InternalAmount getBalanceAlterInInternalUnits() {
|
||||
return balanceAlter;
|
||||
|
||||
}
|
||||
|
||||
public void setBalanceInInternalUnits(CoinEngine.InternalAmount value) {
|
||||
balance = value;
|
||||
}
|
||||
|
||||
public void setBalanceAlterInInternalUnits(CoinEngine.InternalAmount value) {
|
||||
balanceAlter = value;
|
||||
}
|
||||
|
||||
public Long getBalanceETH() {
|
||||
|
||||
BigDecimal b = null;
|
||||
if (balance != null) {
|
||||
b = balance; // Returns ETH / token balance
|
||||
} else if (balanceAlter != null) {
|
||||
b = balanceAlter; // or ETH balance if there're no tokens on Token card
|
||||
}
|
||||
|
||||
if (b != null) {
|
||||
return b.longValue(); // Will leave only lower 64 bits for ETH and Tokens
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromBundle(Bundle B) {
|
||||
super.loadFromBundle(B);
|
||||
|
||||
balance = new CoinEngine.InternalAmount(B.getString("BalanceDecimal"));
|
||||
balanceAlter =new CoinEngine.InternalAmount(B.getString("BalanceDecimalAlter"));
|
||||
|
||||
if (B.containsKey("confirmTx"))
|
||||
countConfirmedTX = new BigInteger(B.getString("confirmTx"), 16);
|
||||
if (B.containsKey("unconfirmTx"))
|
||||
countUnconfirmedTX = new BigInteger(B.getString("unconfirmTx"), 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToBundle(Bundle B) {
|
||||
try {
|
||||
B.putString("BalanceDecimal", balance.toString());
|
||||
B.putString("BalanceDecimalAlter", balance.toString());
|
||||
|
||||
B.putString("confirmTx", getConfirmedTXCount().toString(16));
|
||||
B.putString("unconfirmTx", getUnconfirmedTXCount().toString(16));
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("Can't save to bundle ", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.InputFilter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tangem.domain.cardReader.CardProtocol;
|
||||
import com.tangem.domain.cardReader.TLV;
|
||||
import com.tangem.util.BTCUtils;
|
||||
import com.tangem.util.CryptoUtil;
|
||||
import com.tangem.util.DecimalDigitsInputFilter;
|
||||
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
|
|
@ -17,7 +19,6 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.NoSuchProviderException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.tangem.util.FormatUtil.GetDecimalFormat;
|
||||
|
||||
|
|
@ -27,30 +28,68 @@ import static com.tangem.util.FormatUtil.GetDecimalFormat;
|
|||
|
||||
public class EthEngine extends CoinEngine {
|
||||
|
||||
public String getNode(TangemCard mCard) {
|
||||
return "abc1.hsmiths.com";
|
||||
public EthData ethData = null;
|
||||
|
||||
public EthEngine(TangemContext ctx) throws Exception {
|
||||
super(ctx);
|
||||
if (ctx.getCoinData() == null) {
|
||||
ethData = new EthData();
|
||||
ctx.setCoinData(ethData);
|
||||
} else if (ctx.getCoinData() instanceof BtcData) {
|
||||
ethData = (EthData) ctx.getCoinData();
|
||||
} else {
|
||||
throw new Exception("Invalid type of Blockchain data for BtcEngine");
|
||||
}
|
||||
}
|
||||
|
||||
public int getNodePort(TangemCard mCard) {
|
||||
return 60001;
|
||||
public EthEngine() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void switchNode(TangemCard mCard) {
|
||||
}
|
||||
|
||||
public boolean inOutPutVisible() {
|
||||
@Override
|
||||
public boolean awaitingConfirmation(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getBalanceCurrency(TangemCard card) {
|
||||
@Override
|
||||
public String getBalanceHTML() {
|
||||
if (hasBalanceInfo()) {
|
||||
Amount balance = convertToAmount(ethData.getBalanceInInternalUnits());
|
||||
return balance.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBalanceCurrencyHTML() {
|
||||
return "ETH";
|
||||
}
|
||||
|
||||
public boolean awaitingConfirmation(TangemCard card) {
|
||||
return false;
|
||||
@Override
|
||||
public String getOfflineBalanceHTML() {
|
||||
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
|
||||
Amount offlineAmount = convertToAmount(offlineInternalAmount);
|
||||
return offlineAmount.toString();
|
||||
}
|
||||
|
||||
public String getFeeCurrency() {
|
||||
|
||||
@Override
|
||||
public boolean isBalanceAlterNotZero() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBalanceNotZero() {
|
||||
if( ethData==null ) return false;
|
||||
if (ethData.getBalanceInInternalUnits() == null) return false;
|
||||
return ethData.getBalanceInInternalUnits().notZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeeCurrencyHTML() {
|
||||
return "Gwei";
|
||||
}
|
||||
|
||||
|
|
@ -66,10 +105,6 @@ public class EthEngine extends CoinEngine {
|
|||
return d;
|
||||
}
|
||||
|
||||
public int getTokenDecimals(TangemCard card) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getContractAddress(TangemCard card) {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -151,7 +186,7 @@ public class EthEngine extends CoinEngine {
|
|||
return mCard.getBalance();
|
||||
}
|
||||
|
||||
public String getBalanceWithAlter(TangemCard mCard) {
|
||||
public String getBalanceHTML(TangemCard mCard) {
|
||||
return getBalance(mCard);
|
||||
}
|
||||
|
||||
|
|
@ -215,8 +250,9 @@ public class EthEngine extends CoinEngine {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean hasBalanceInfo(TangemCard card) {
|
||||
return card.hasBalanceInfo();
|
||||
@Override
|
||||
public boolean hasBalanceInfo() {
|
||||
return ethData.hasBalanceInfo();
|
||||
}
|
||||
|
||||
public Uri getShareWalletUri(TangemCard mCard) {
|
||||
|
|
@ -239,6 +275,12 @@ public class EthEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InputFilter[] getAmountInputFilters() {
|
||||
return new InputFilter[] { new DecimalDigitsInputFilter(18) };
|
||||
}
|
||||
|
||||
|
||||
public boolean checkAmountValue(TangemCard mCard, String amountValue, String feeValue, Long minFeeInInternalUnits, Boolean incfee) {
|
||||
// Long fee = null;
|
||||
// Long amount = null;
|
||||
|
|
@ -263,7 +305,7 @@ public class EthEngine extends CoinEngine {
|
|||
try {
|
||||
BigDecimal tmpFee = new BigDecimal(feeValue);
|
||||
BigDecimal tmpAmount = new BigDecimal(amountValue);
|
||||
BigDecimal cardBalance = new BigDecimal(mCard.getDecimalBalance());
|
||||
BigDecimal cardBalance = new BigDecimal(ethData.getDecimalBalance());
|
||||
tmpAmount = tmpAmount.multiply(new BigDecimal("1000000000"));
|
||||
cardBalance = cardBalance.divide(new BigDecimal("1000000000"));
|
||||
//if (tmpFee.compareTo(tmpAmount) > 0)
|
||||
|
|
@ -311,7 +353,7 @@ public class EthEngine extends CoinEngine {
|
|||
|
||||
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, TangemCard mCard, CardProtocol protocol) throws Exception {
|
||||
|
||||
BigInteger nonceValue = mCard.getConfirmedTXCount();
|
||||
BigInteger nonceValue = ethData.getConfirmedTXCount();
|
||||
byte[] pbKey = mCard.getWalletPublicKey();
|
||||
boolean flag = (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
|
||||
Issuer issuer = mCard.getIssuer();
|
||||
|
|
|
|||
|
|
@ -5,15 +5,9 @@ import android.util.Log;
|
|||
|
||||
import com.google.common.base.Strings;
|
||||
import com.tangem.domain.cardReader.SettingsMask;
|
||||
import com.tangem.util.FormatUtil;
|
||||
import com.tangem.util.Util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by dvol on 16.07.2017.
|
||||
|
|
@ -28,11 +22,6 @@ public class TangemCard {
|
|||
private Status status;
|
||||
private String wallet;
|
||||
private String UID;
|
||||
private String error;
|
||||
private String message;
|
||||
private String balanceDecimal;
|
||||
private String balanceDecimalAlter = "";
|
||||
private Long balanceConfirmed, balanceUnconfirmed;
|
||||
private String blockchainID;
|
||||
private Manufacturer manufacturer = Manufacturer.Unknown;
|
||||
private boolean manufacturerConfirmed = false;
|
||||
|
|
@ -43,49 +32,6 @@ public class TangemCard {
|
|||
private byte[] pbCardKey = null;
|
||||
private byte[] pbWalletKeyRar = null;
|
||||
private Date dtPersonalization = null;
|
||||
private float rate = 0;
|
||||
private float rateAlter = 0;
|
||||
|
||||
private BigInteger countConfirmedTX = null;
|
||||
private BigInteger countUnconfirmedTX = BigInteger.valueOf(0);
|
||||
|
||||
public BigInteger getConfirmedTXCount() {
|
||||
if (countConfirmedTX == null) {
|
||||
countConfirmedTX = BigInteger.valueOf(0);
|
||||
}
|
||||
return countConfirmedTX;
|
||||
}
|
||||
|
||||
public void setConfirmedTXCount(BigInteger count) {
|
||||
countConfirmedTX = count;
|
||||
}
|
||||
|
||||
public BigInteger getUnconfirmedTXCount() {
|
||||
if (countUnconfirmedTX == null) {
|
||||
countUnconfirmedTX = BigInteger.valueOf(0);
|
||||
}
|
||||
return countUnconfirmedTX;
|
||||
}
|
||||
|
||||
public void setUnconfirmedTXCount(BigInteger count) {
|
||||
countUnconfirmedTX = count;
|
||||
}
|
||||
|
||||
public float getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public float getRateAlter() {
|
||||
return rateAlter;
|
||||
}
|
||||
|
||||
public void setRate(float rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public void setRateAlter(float rate) {
|
||||
this.rateAlter = rate;
|
||||
}
|
||||
|
||||
public String getBlockchainID() {
|
||||
return blockchainID;
|
||||
|
|
@ -95,6 +41,10 @@ public class TangemCard {
|
|||
return Blockchain.fromId(blockchainID);
|
||||
}
|
||||
|
||||
public void setBlockchain(Blockchain blockchain) {
|
||||
blockchainID=blockchain.getID();
|
||||
}
|
||||
|
||||
public void setBlockchainID(String blockchainID) {
|
||||
this.blockchainID = blockchainID;
|
||||
}
|
||||
|
|
@ -106,17 +56,12 @@ public class TangemCard {
|
|||
String oldName = getBlockchain().getOfficialName();
|
||||
//String newName = String.format("%s - %s ERC20 token", token, oldName);
|
||||
String newName = token + " <br><small><small> " + oldName + " ERC20 token</small></small>";
|
||||
setBlockchainName(newName);
|
||||
blockchainName=newName;
|
||||
|
||||
}
|
||||
|
||||
private String blockchainName = "";
|
||||
|
||||
public void setBlockchainName(String name) {
|
||||
blockchainName = name;
|
||||
}
|
||||
|
||||
|
||||
public String getBlockchainName() {
|
||||
if (Strings.isNullOrEmpty(blockchainName))
|
||||
return getBlockchain().getOfficialName();
|
||||
|
|
@ -180,47 +125,6 @@ public class TangemCard {
|
|||
return cardPublicKeyValid;
|
||||
}
|
||||
|
||||
public Double amountFromInternalUnits(Long internalAmount) {
|
||||
// TODO java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
|
||||
return ((double) internalAmount) /
|
||||
getBlockchain().getMultiplier();
|
||||
}
|
||||
|
||||
public Double amountFromInternalUnits(Integer internalAmount) {
|
||||
return ((double) internalAmount) / getBlockchain().getMultiplier();
|
||||
}
|
||||
|
||||
// TODO разобраться с балансами, привести к единому интерфейсу
|
||||
public Long internalUnitsFromString(String caption) {
|
||||
try {
|
||||
return FormatUtil.ConvertStringToLong(caption);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getAmountDescription(Double amount) {
|
||||
String output = FormatUtil.DoubleToString(amount);
|
||||
return output + " " + getBlockchain().getCurrency();
|
||||
}
|
||||
|
||||
public String getAmountEquivalentDescription(Double amount) {
|
||||
if (getBlockchain() == Blockchain.Ethereum || getBlockchain() == Blockchain.EthereumTestNet || getBlockchain() == Blockchain.Token) {
|
||||
return EthEngine.getAmountEquivalentDescriptionETH(amount, rate);
|
||||
}
|
||||
|
||||
return BtcEngine.getAmountEquivalentDescriptionBTC(amount, rate);
|
||||
}
|
||||
|
||||
public boolean getAmountEquivalentDescriptionAvailable() {
|
||||
return rate > 0;
|
||||
}
|
||||
|
||||
public String getAmountInGwei(String amount) {
|
||||
BigInteger d = new BigInteger(amount, 10);
|
||||
BigInteger m = d.divide(BigInteger.valueOf(1000000000L));
|
||||
return m.toString(10);
|
||||
}
|
||||
|
||||
public Manufacturer getManufacturer() {
|
||||
return manufacturer;
|
||||
|
|
@ -285,13 +189,7 @@ public class TangemCard {
|
|||
this.PIN = PIN;
|
||||
}
|
||||
|
||||
public void clearInfo() {
|
||||
balanceConfirmed = null;
|
||||
balanceUnconfirmed = null;
|
||||
unspentTransactions = null;
|
||||
balanceDecimal = null;
|
||||
balanceDecimalAlter = null;
|
||||
setIsBalanceEqual(false);
|
||||
public void switchToInitialBlockchain() {
|
||||
if (tokenSymbol.length() > 1)
|
||||
blockchainID = Blockchain.Token.getID(); // Reset blockchain to Token from ETH for token cards with zero token balance on it
|
||||
}
|
||||
|
|
@ -306,7 +204,6 @@ public class TangemCard {
|
|||
|
||||
public String getPersonalizationDateTimeDescription() {
|
||||
return Util.formatDate(dtPersonalization);
|
||||
|
||||
}
|
||||
|
||||
private int health = 0;
|
||||
|
|
@ -418,34 +315,6 @@ public class TangemCard {
|
|||
return pauseBeforePIN2;
|
||||
}
|
||||
|
||||
private AtomicInteger failedBalanceRequestCounter;
|
||||
|
||||
public int incFailedBalanceRequestCounter() {
|
||||
if (failedBalanceRequestCounter == null)
|
||||
failedBalanceRequestCounter = new AtomicInteger(0);
|
||||
return failedBalanceRequestCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
public void resetFailedBalanceRequestCounter() {
|
||||
failedBalanceRequestCounter = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public int getFailedBalanceRequestCounter() {
|
||||
if (failedBalanceRequestCounter == null)
|
||||
return 0;
|
||||
return failedBalanceRequestCounter.get();
|
||||
}
|
||||
|
||||
private Boolean balanceEqual;
|
||||
|
||||
public Boolean isBalanceEqual() {
|
||||
return balanceEqual;
|
||||
}
|
||||
|
||||
public void setIsBalanceEqual(boolean isEqual) {
|
||||
balanceEqual = isEqual;
|
||||
}
|
||||
|
||||
private Integer settingsMask = null;
|
||||
|
||||
public void setSettingsMask(int settingsMask) {
|
||||
|
|
@ -591,16 +460,6 @@ public class TangemCard {
|
|||
return batch;
|
||||
}
|
||||
|
||||
private String validationNodeDescription = "";
|
||||
|
||||
public String getValidationNodeDescription() {
|
||||
return validationNodeDescription;
|
||||
}
|
||||
|
||||
public void setValidationNodeDescription(String validationNodeDescription) {
|
||||
this.validationNodeDescription = validationNodeDescription;
|
||||
}
|
||||
|
||||
public enum SigningMethod {
|
||||
Sign_Hash(0, "sign hash"),
|
||||
Sign_Raw(1, "sign raw tx"),
|
||||
|
|
@ -638,40 +497,32 @@ public class TangemCard {
|
|||
return signingMethod;
|
||||
}
|
||||
|
||||
public static class UnspentTransaction {
|
||||
public String txID;
|
||||
public Integer Amount;
|
||||
public Integer Height;
|
||||
public String Raw = "";
|
||||
|
||||
public Bundle getAsBundle() {
|
||||
Bundle B = new Bundle();
|
||||
B.putString("txID", txID);
|
||||
B.putInt("Amount", Amount);
|
||||
B.putInt("Height", Height);
|
||||
B.putString("Raw", Raw);
|
||||
return B;
|
||||
}
|
||||
|
||||
public void loadFromBundle(Bundle B) {
|
||||
txID = B.getString("txID");
|
||||
Amount = B.getInt("Amount");
|
||||
Height = B.getInt("Height");
|
||||
Raw = B.getString("Raw");
|
||||
}
|
||||
}
|
||||
|
||||
private List<UnspentTransaction> unspentTransactions = null;
|
||||
|
||||
public List<UnspentTransaction> getUnspentTransactions() {
|
||||
if (unspentTransactions == null) unspentTransactions = new ArrayList<>();
|
||||
return unspentTransactions;
|
||||
}
|
||||
|
||||
public TangemCard(String UID) {
|
||||
this.UID = UID;
|
||||
}
|
||||
|
||||
|
||||
public enum Status {
|
||||
NotPersonalized(0), Empty(1), Loaded(2), Purged(3);
|
||||
|
||||
Status(int Code) {
|
||||
mCode = Code;
|
||||
}
|
||||
|
||||
private int mCode;
|
||||
|
||||
public int getCode() {
|
||||
return mCode;
|
||||
}
|
||||
|
||||
public static Status fromCode(int code) {
|
||||
for (Status s : values()) {
|
||||
if (s.getCode() == code) return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
|
@ -721,58 +572,6 @@ public class TangemCard {
|
|||
this.UID = UID;
|
||||
}
|
||||
|
||||
public Long getBalance() {
|
||||
|
||||
BigDecimal balance = null;
|
||||
|
||||
if ((this.getBlockchain() == Blockchain.Bitcoin || this.getBlockchain() == Blockchain.BitcoinCash || this.getBlockchain() == Blockchain.BitcoinTestNet || this.getBlockchain() == Blockchain.BitcoinCashTestNet) && balanceConfirmed != null && balanceUnconfirmed != null) {
|
||||
balance = BigDecimal.valueOf(balanceConfirmed + balanceUnconfirmed);
|
||||
} else if (this.getBlockchain() == Blockchain.Ethereum || this.getBlockchain() == Blockchain.EthereumTestNet || this.getBlockchain() == Blockchain.Token) {
|
||||
if (balanceDecimal != null) {
|
||||
balance = new BigDecimal(balanceDecimal); // Returns ETH / token balance
|
||||
} else if (balanceDecimalAlter != null) {
|
||||
balance = new BigDecimal(balanceDecimalAlter); // or ETH balance if there're no tokens on Token card
|
||||
}
|
||||
}
|
||||
|
||||
if (balance != null) {
|
||||
return balance.longValue(); // Will leave only lower 64 bits for ETH and Tokens
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long getBalanceUnconfirmed() {
|
||||
return balanceUnconfirmed;
|
||||
}
|
||||
|
||||
public void setBalanceConfirmed(Long balance) {
|
||||
this.balanceConfirmed = balance;
|
||||
}
|
||||
|
||||
public void setBalanceUnconfirmed(Long balance) {
|
||||
this.balanceUnconfirmed = balance;
|
||||
}
|
||||
|
||||
public boolean hasBalanceInfo() {
|
||||
return balanceConfirmed != null || balanceUnconfirmed != null || balanceDecimal != "" || balanceDecimalAlter != "";
|
||||
}
|
||||
|
||||
public String getDecimalBalance() {
|
||||
return balanceDecimal;
|
||||
}
|
||||
|
||||
public String getDecimalBalanceAlter() {
|
||||
return balanceDecimalAlter;
|
||||
}
|
||||
|
||||
public void setDecimalBalance(String value) {
|
||||
balanceDecimal = value;
|
||||
}
|
||||
|
||||
public void setDecimalBalanceAlter(String value) {
|
||||
balanceDecimalAlter = value;
|
||||
}
|
||||
|
||||
private byte[] offlineBalance;
|
||||
|
||||
|
|
@ -799,7 +598,10 @@ public class TangemCard {
|
|||
public void setDenomination(byte[] denomination) {
|
||||
this.Denomination = denomination;
|
||||
try {
|
||||
this.DenominationText = CoinEngineFactory.create(getBlockchain()).convertByteArrayToAmount(this, denomination);
|
||||
CoinEngine engine=CoinEngineFactory.create(getBlockchain());
|
||||
CoinEngine.InternalAmount internalAmount=engine.convertToInternalAmount(denomination);
|
||||
CoinEngine.Amount amount=engine.convertToAmount(internalAmount);
|
||||
this.DenominationText = amount.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.DenominationText = "N/A";
|
||||
|
|
@ -834,43 +636,6 @@ public class TangemCard {
|
|||
DenominationText = null;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setMessage(String value) {
|
||||
this.message = value;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public enum Status {
|
||||
NotPersonalized(0), Empty(1), Loaded(2), Purged(3);
|
||||
|
||||
Status(int Code) {
|
||||
mCode = Code;
|
||||
}
|
||||
|
||||
private int mCode;
|
||||
|
||||
public int getCode() {
|
||||
return mCode;
|
||||
}
|
||||
|
||||
public static Status fromCode(int code) {
|
||||
for (Status s : values()) {
|
||||
if (s.getCode() == code) return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Bundle getAsBundle() {
|
||||
Bundle B = new Bundle();
|
||||
saveToBundle(B);
|
||||
|
|
@ -889,7 +654,6 @@ public class TangemCard {
|
|||
B.putInt("TokensDecimal", tokensDecimal);
|
||||
B.putString("TokenSymbol", tokenSymbol);
|
||||
B.putString("ContractAddress", contractAddress);
|
||||
B.putString("validationNodeDescription", validationNodeDescription);
|
||||
if (dtPersonalization != null) B.putLong("dtPersonalization", dtPersonalization.getTime());
|
||||
B.putInt("RemainingSignatures", remainingSignatures);
|
||||
B.putInt("MaxSignatures", maxSignatures);
|
||||
|
|
@ -902,26 +666,18 @@ public class TangemCard {
|
|||
if (issuer != null) B.putString("Issuer", issuer.getID());
|
||||
if (issuerPublicDataKey != null) B.putByteArray("IssuerPublicDataKey", issuerPublicDataKey);
|
||||
if (firmwareVersion != null) B.putString("FirmwareVersion", firmwareVersion);
|
||||
if (balanceEqual != null) B.putBoolean("isBalanceEqual", balanceEqual);
|
||||
if (batch != null) B.putString("Batch", batch);
|
||||
B.putString("BalanceDecimal", balanceDecimal);
|
||||
B.putString("BalanceDecimalAlter", balanceDecimalAlter);
|
||||
B.putBoolean("ManufacturerConfirmed", manufacturerConfirmed);
|
||||
B.putBoolean("CardPublicKeyValid", isCardPublicKeyValid());
|
||||
B.putByteArray("CardPublicKey", getCardPublicKey());
|
||||
|
||||
if (failedBalanceRequestCounter != null)
|
||||
B.putInt("FailedBalance", failedBalanceRequestCounter.get());
|
||||
B.putInt("SignedHashes", getSignedHashes());
|
||||
B.putString("Wallet", wallet);
|
||||
B.putString("Error", error);
|
||||
B.putBoolean("WalletPublicKeyValid", isWalletPublicKeyValid());
|
||||
if (pbWalletKey != null)
|
||||
B.putByteArray("PublicKey", pbWalletKey);
|
||||
if (pbWalletKeyRar != null)
|
||||
B.putByteArray("PublicKeyRar", pbWalletKeyRar);
|
||||
if (balanceConfirmed != null) B.putLong("BalanceConfirmed", balanceConfirmed);
|
||||
if (balanceUnconfirmed != null) B.putLong("BalanceUnconfirmed", balanceUnconfirmed);
|
||||
|
||||
if (getOfflineBalance() != null) B.putByteArray("OfflineBalance", getOfflineBalance());
|
||||
|
||||
|
|
@ -933,18 +689,6 @@ public class TangemCard {
|
|||
B.putBoolean("NeedWriteIssuerData", getNeedWriteIssuerData());
|
||||
}
|
||||
|
||||
if (unspentTransactions != null) {
|
||||
Bundle BB = new Bundle();
|
||||
for (Integer i = 0; i < unspentTransactions.size(); i++) {
|
||||
BB.putBundle(i.toString(), unspentTransactions.get(i).getAsBundle());
|
||||
}
|
||||
B.putBundle("UnspentTransactions", BB);
|
||||
}
|
||||
B.putFloat("rate", rate);
|
||||
B.putFloat("rateAlter", rateAlter);
|
||||
B.putString("confirmTx", getConfirmedTXCount().toString(16));
|
||||
B.putString("unconfirmTx", getUnconfirmedTXCount().toString(16));
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
|
|
@ -954,13 +698,9 @@ public class TangemCard {
|
|||
if (onlineVerified != null)
|
||||
B.putBoolean("onlineVerified", onlineVerified);
|
||||
|
||||
B.putBoolean("balanceReceived", balanceReceived);
|
||||
|
||||
|
||||
if (onlineValidated != null)
|
||||
B.putBoolean("onlineValidated", onlineValidated);
|
||||
|
||||
|
||||
if (codeConfirmed != null)
|
||||
B.putBoolean("codeConfirmed", codeConfirmed);
|
||||
|
||||
|
|
@ -978,16 +718,6 @@ public class TangemCard {
|
|||
|
||||
}
|
||||
|
||||
public boolean isBalanceReceived() {
|
||||
return balanceReceived;
|
||||
}
|
||||
|
||||
private boolean balanceReceived = false;
|
||||
|
||||
public void setBalanceReceived(boolean value) {
|
||||
balanceReceived = value;
|
||||
}
|
||||
|
||||
public void loadFromBundle(Bundle B) {
|
||||
UID = B.getString("UID");
|
||||
CID = B.getByteArray("CID");
|
||||
|
|
@ -995,19 +725,15 @@ public class TangemCard {
|
|||
PIN2 = PIN2_Mode.valueOf(B.getString("PIN2"));
|
||||
status = Status.valueOf(B.getString("Status"));
|
||||
wallet = B.getString("Wallet");
|
||||
error = B.getString("Error");
|
||||
blockchainID = B.getString("Blockchain");
|
||||
tokensDecimal = B.getInt("TokensDecimal", 18);
|
||||
tokenSymbol = B.getString("TokenSymbol", "");
|
||||
contractAddress = B.getString("ContractAddress", "");
|
||||
if (B.containsKey("BlockchainName"))
|
||||
blockchainName = B.getString("BlockchainName", "");
|
||||
validationNodeDescription = B.getString("validationNodeDescription");
|
||||
if (B.containsKey("dtPersonalization")) {
|
||||
dtPersonalization = new Date(B.getLong("dtPersonalization"));
|
||||
}
|
||||
balanceDecimal = B.getString("BalanceDecimal");
|
||||
balanceDecimalAlter = B.getString("BalanceDecimalAlter");
|
||||
remainingSignatures = B.getInt("RemainingSignatures");
|
||||
maxSignatures = B.getInt("MaxSignatures");
|
||||
health = B.getInt("health");
|
||||
|
|
@ -1025,8 +751,6 @@ public class TangemCard {
|
|||
|
||||
if (B.containsKey("SignedHashes")) setSignedHashes(B.getInt("SignedHashes"));
|
||||
|
||||
if (B.containsKey("FailedBalance"))
|
||||
failedBalanceRequestCounter = new AtomicInteger(B.getInt("FailedBalance"));
|
||||
if (B.containsKey("Issuer")) issuer = Issuer.FindIssuer(B.getString("Issuer"));
|
||||
if (B.containsKey("IssuerPublicDataKey"))
|
||||
issuerPublicDataKey = B.getByteArray("IssuerPublicDataKey");
|
||||
|
|
@ -1034,17 +758,9 @@ public class TangemCard {
|
|||
if (B.containsKey("FirmwareVersion")) firmwareVersion = B.getString("FirmwareVersion");
|
||||
if (B.containsKey("Batch")) batch = B.getString("Batch");
|
||||
|
||||
if (B.containsKey("isBalanceEqual")) setIsBalanceEqual(B.getBoolean("isBalanceEqual"));
|
||||
cardPublicKeyValid = B.getBoolean("CardPublicKeyValid");
|
||||
if (B.containsKey("CardPublicKey")) setCardPublicKey(B.getByteArray("CardPublicKey"));
|
||||
|
||||
if (B.containsKey("balanceReceived")) setBalanceReceived(B.getBoolean("balanceReceived"));
|
||||
if (B.containsKey("BalanceConfirmed")) balanceConfirmed = B.getLong("BalanceConfirmed");
|
||||
else balanceConfirmed = null;
|
||||
if (B.containsKey("BalanceUnconfirmed"))
|
||||
balanceUnconfirmed = B.getLong("BalanceUnconfirmed");
|
||||
else balanceUnconfirmed = null;
|
||||
|
||||
if (B.containsKey("OfflineBalance")) setOfflineBalance(B.getByteArray("OfflineBalance"));
|
||||
else clearOfflineBalance();
|
||||
|
||||
|
|
@ -1066,26 +782,6 @@ public class TangemCard {
|
|||
pbWalletKeyRar = B.getByteArray("PublicKeyRar");
|
||||
}
|
||||
|
||||
if (B.containsKey("UnspentTransactions")) {
|
||||
unspentTransactions = new ArrayList<>();
|
||||
Bundle BB = B.getBundle("UnspentTransactions");
|
||||
Integer i = 0;
|
||||
while (BB.containsKey(i.toString())) {
|
||||
UnspentTransaction t = new UnspentTransaction();
|
||||
t.loadFromBundle(BB.getBundle(i.toString()));
|
||||
unspentTransactions.add(t);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (B.containsKey("rate"))
|
||||
rate = B.getFloat("rate");
|
||||
if (B.containsKey("rateAlter"))
|
||||
rateAlter = B.getFloat("rateAlter");
|
||||
if (B.containsKey("confirmTx"))
|
||||
countConfirmedTX = new BigInteger(B.getString("confirmTx"), 16);
|
||||
if (B.containsKey("unconfirmTx"))
|
||||
countUnconfirmedTX = new BigInteger(B.getString("unconfirmTx"), 16);
|
||||
|
||||
if (B.containsKey("codeConfirmed"))
|
||||
codeConfirmed = B.getBoolean("codeConfirmed");
|
||||
|
||||
|
|
@ -1096,19 +792,6 @@ public class TangemCard {
|
|||
onlineValidated = B.getBoolean("onlineValidated");
|
||||
}
|
||||
|
||||
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
if (bytes == null) return "";
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
public enum EncryptionMode {
|
||||
None((byte) 0x0), Fast((byte) 0x1), Strong((byte) 0x2);
|
||||
|
||||
|
|
|
|||
114
app/src/main/java/com/tangem/domain/wallet/TangemContext.java
Normal file
114
app/src/main/java/com/tangem/domain/wallet/TangemContext.java
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
package com.tangem.domain.wallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
public class TangemContext {
|
||||
private static final String EXTRA_BLOCKCHAIN_DATA = "BLOCKCHAIN_DATA";
|
||||
private Context context;
|
||||
private TangemCard card;
|
||||
private CoinData coinData;
|
||||
private String error;
|
||||
private String message;
|
||||
|
||||
|
||||
public TangemContext() {
|
||||
|
||||
}
|
||||
|
||||
public TangemContext(TangemCard card) {
|
||||
this.card = card;
|
||||
}
|
||||
|
||||
public Blockchain getBlockchain() {
|
||||
if (card == null) return Blockchain.Unknown;
|
||||
return card.getBlockchain();
|
||||
}
|
||||
|
||||
public void setBlockchain(Blockchain blockchain) {
|
||||
if (card == null) return;
|
||||
card.setBlockchain(blockchain);
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public TangemCard getCard() {
|
||||
return card;
|
||||
}
|
||||
|
||||
public void setCard(TangemCard card) {
|
||||
this.card = card;
|
||||
}
|
||||
|
||||
public CoinData getCoinData() {
|
||||
return coinData;
|
||||
}
|
||||
|
||||
public void setCoinData(CoinData coinData) {
|
||||
this.coinData = coinData;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setMessage(String value) {
|
||||
this.message = value;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
public static TangemContext loadFromBundle(Context context, Bundle bundle) {
|
||||
TangemContext tangemContext = new TangemContext();
|
||||
tangemContext.setContext(context);
|
||||
|
||||
if (bundle.containsKey(TangemCard.EXTRA_UID)) {
|
||||
tangemContext.card = new TangemCard(bundle.getString(TangemCard.EXTRA_UID));
|
||||
tangemContext.card.loadFromBundle(bundle.getBundle(TangemCard.EXTRA_CARD));
|
||||
}
|
||||
|
||||
if (tangemContext.getBlockchain() != null && bundle.containsKey(EXTRA_BLOCKCHAIN_DATA)) {
|
||||
tangemContext.coinData=CoinData.fromBundle(tangemContext.getBlockchain(), bundle.getBundle(EXTRA_BLOCKCHAIN_DATA));
|
||||
}
|
||||
|
||||
tangemContext.error = bundle.getString("Error");
|
||||
tangemContext.message = bundle.getString("Message");
|
||||
|
||||
return tangemContext;
|
||||
}
|
||||
|
||||
public void saveToBundle(Bundle bundle) {
|
||||
|
||||
if (card != null) {
|
||||
bundle.putString(TangemCard.EXTRA_UID, card.getUID());
|
||||
bundle.putBundle(TangemCard.EXTRA_CARD, card.getAsBundle());
|
||||
}
|
||||
|
||||
if (coinData != null) {
|
||||
bundle.putBundle(EXTRA_BLOCKCHAIN_DATA, coinData.asBundle());
|
||||
}
|
||||
|
||||
bundle.putString("Error", error);
|
||||
bundle.putString("Message", message);
|
||||
|
||||
}
|
||||
|
||||
public String getString(int stringId) {
|
||||
if( context!=null ) return getContext().getResources().getString(stringId);
|
||||
return "context.resources.string["+stringId+"]";
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.cardReader.CardProtocol;
|
|||
import com.tangem.domain.cardReader.TLV;
|
||||
import com.tangem.util.BTCUtils;
|
||||
import com.tangem.util.CryptoUtil;
|
||||
import com.tangem.wallet.R;
|
||||
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
|
|
@ -28,24 +29,23 @@ import static com.tangem.util.FormatUtil.GetDecimalFormat;
|
|||
|
||||
public class TokenEngine extends CoinEngine {
|
||||
|
||||
public String getNode(TangemCard mCard) {
|
||||
return "abc1.hsmiths.com";
|
||||
@Override
|
||||
public String getOfflineBalanceHTML() {
|
||||
return ctx.getString(R.string.not_implemented);
|
||||
}
|
||||
|
||||
public int getNodePort(TangemCard mCard) {
|
||||
return 60001;
|
||||
public TokenEngine(TangemContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void switchNode(TangemCard mCard) {
|
||||
public TokenEngine() {
|
||||
|
||||
}
|
||||
|
||||
public boolean awaitingConfirmation(TangemCard card) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean inOutPutVisible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getBalanceCurrency(TangemCard card) {
|
||||
String currency = card.getTokenSymbol();
|
||||
|
|
@ -219,7 +219,7 @@ public class TokenEngine extends CoinEngine {
|
|||
}
|
||||
|
||||
|
||||
public String getBalanceWithAlter(TangemCard mCard) {
|
||||
public String getBalanceHTML(TangemCard mCard) {
|
||||
//return getBalance(mCard) + "\n(" + GetBalanceAlterValue(mCard) + " ETH)";
|
||||
if (GetBalanceAlterValue(mCard) != "") {
|
||||
return " " + getBalance(mCard) + " <br><small><small> + " + GetBalanceAlterValue(mCard) + " ETH for gas</small></small>";
|
||||
|
|
|
|||
|
|
@ -40,14 +40,16 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
private var serverApiHelper: ServerApiHelper = ServerApiHelper()
|
||||
private var serverApiHelperElectrum: ServerApiHelperElectrum = ServerApiHelperElectrum()
|
||||
|
||||
private var card: TangemCard? = null
|
||||
//private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
|
||||
private var feeRequestSuccess = false
|
||||
private var balanceRequestSuccess = false
|
||||
private var minFee: String? = null
|
||||
private var maxFee: String? = null
|
||||
private var normalFee: String? = null
|
||||
private var isIncludeFee: Boolean = true
|
||||
private var minFeeInInternalUnits: Long? = 0L
|
||||
private var minFeeInInternalUnits: CoinEngine.InternalAmount? = CoinEngine.InternalAmount(0)
|
||||
private var requestPIN2Count = 0
|
||||
private var nodeCheck = false
|
||||
private var dtVerified: Date? = null
|
||||
|
|
@ -61,18 +63,14 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra("UID"))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle("Card"))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
// card = TangemCard(intent.getStringExtra("UID"))
|
||||
// card!!.loadFromBundle(intent.extras!!.getBundle("Card"))
|
||||
//
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
|
||||
val balanceWithAlter = engine!!.getBalanceWithAlter(card).replace(",", ".")
|
||||
|
||||
if (card!!.blockchain == Blockchain.Token) {
|
||||
val html = Html.fromHtml(balanceWithAlter)
|
||||
val html = Html.fromHtml(engine!!.balanceHTML)
|
||||
tvBalance.text = html
|
||||
} else
|
||||
tvBalance.text = balanceWithAlter
|
||||
|
||||
isIncludeFee = intent.getBooleanExtra("IncFee", true)
|
||||
|
||||
|
|
@ -80,14 +78,14 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
tvIncFee.setText(R.string.including_fee)
|
||||
else
|
||||
tvIncFee.setText(R.string.not_including_fee)
|
||||
if (card!!.blockchain == Blockchain.Token)
|
||||
if (ctx.blockchain == Blockchain.Token)
|
||||
tvIncFee.visibility = View.INVISIBLE
|
||||
else
|
||||
tvIncFee.visibility = View.VISIBLE
|
||||
etAmount.setText(intent.getStringExtra(SignPaymentActivity.EXTRA_AMOUNT))
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
tvCurrency2.text = engine.feeCurrency
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
|
||||
tvCurrency2.text = Html.fromHtml(engine.feeCurrencyHTML)
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
etWallet.setText(intent.getStringExtra("Wallet"))
|
||||
etFee.setText("")
|
||||
|
||||
|
|
@ -95,7 +93,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
feeRequestSuccess = false
|
||||
balanceRequestSuccess = false
|
||||
|
||||
if (card!!.blockchain == Blockchain.Ethereum || card!!.blockchain == Blockchain.EthereumTestNet || card!!.blockchain == Blockchain.Token) {
|
||||
if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet || ctx.blockchain == Blockchain.Token) {
|
||||
rgFee.isEnabled = false
|
||||
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_GAS_PRICE)
|
||||
|
|
@ -103,7 +101,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
} else {
|
||||
rgFee.isEnabled = true
|
||||
|
||||
requestElectrum(card!!, ElectrumRequest.checkBalance(card!!.wallet))
|
||||
requestElectrum(ctx.card, ElectrumRequest.checkBalance(ctx.card!!.wallet))
|
||||
|
||||
calcSize = 256
|
||||
try {
|
||||
|
|
@ -112,7 +110,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
Log.e("Build Fee error", ex.message)
|
||||
}
|
||||
|
||||
card!!.resetFailedBalanceRequestCounter()
|
||||
ctx.coinData!!.resetFailedBalanceRequestCounter()
|
||||
|
||||
progressBar.visibility = View.VISIBLE
|
||||
|
||||
|
|
@ -128,11 +126,11 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
try {
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
val eqFee = engine!!.evaluateFeeEquivalent(card, etFee!!.text.toString())
|
||||
val engine = CoinEngineFactory.create(ctx.blockchain)
|
||||
val eqFee = engine!!.evaluateFeeEquivalent(etFee!!.text.toString())
|
||||
tvFeeEquivalent.text = eqFee
|
||||
|
||||
if (!card!!.amountEquivalentDescriptionAvailable) {
|
||||
if (!ctx.coinData!!.amountEquivalentDescriptionAvailable) {
|
||||
tvFeeEquivalent.error = "Service unavailable"
|
||||
tvCurrency2.visibility = View.GONE
|
||||
tvFeeEquivalent.visibility = View.GONE
|
||||
|
|
@ -158,30 +156,30 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
return@setOnClickListener
|
||||
}
|
||||
|
||||
val engineCoin = CoinEngineFactory.create(card!!.blockchain)
|
||||
val engineCoin = CoinEngineFactory.create(ctx)
|
||||
|
||||
if (engineCoin!!.isNeedCheckNode && !nodeCheck) {
|
||||
Toast.makeText(baseContext, getString(R.string.cannot_reach_current_active_blockchain_node_try_again), Toast.LENGTH_LONG).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
val txFee = etFee.text.toString()
|
||||
val txAmount = etAmount.text.toString()
|
||||
val txFee = engineCoin.convertToAmount(etFee.text.toString())
|
||||
val txAmount = engineCoin.convertToAmount(etAmount.text.toString())
|
||||
|
||||
if (!engineCoin.hasBalanceInfo(card)) {
|
||||
if (!engineCoin.hasBalanceInfo()) {
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_check_balance_no_connection_with_blockchain_nodes))
|
||||
return@setOnClickListener
|
||||
|
||||
} else if (!engineCoin.isBalanceNotZero(card)) {
|
||||
} else if (!engineCoin.isBalanceNotZero) {
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.the_wallet_is_empty))
|
||||
return@setOnClickListener
|
||||
|
||||
} else if (!engineCoin.checkUnspentTransaction(card)) {
|
||||
} else if (!engineCoin.checkUnspentTransaction()) {
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.please_wait_for_confirmation_of_incoming_transaction))
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (!engineCoin.checkAmountValue(card, txAmount, txFee, minFeeInInternalUnits, isIncludeFee)) {
|
||||
if (!engineCoin.checkNewTransactionAmountAndFee(txAmount, txFee, isIncludeFee, minFeeInInternalUnits)) {
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.not_enough_funds_on_your_card))
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
|
@ -189,8 +187,9 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
requestPIN2Count = 0
|
||||
val intent = Intent(baseContext, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
intent.putExtra("IncFee", isIncludeFee)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
|
||||
}
|
||||
|
|
@ -201,7 +200,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
if (electrumRequest!!.isMethod(ElectrumRequest.METHOD_GetBalance)) {
|
||||
try {
|
||||
etFee.setText(getString(R.string.empty))
|
||||
if ((electrumRequest.result.getInt("confirmed") + electrumRequest.result.getInt("unconfirmed")) / card!!.blockchain.multiplier * 1000000.0 < java.lang.Float.parseFloat(etAmount.text.toString())) {
|
||||
if ((electrumRequest.result.getInt("confirmed") + electrumRequest.result.getInt("unconfirmed")) / ctx.blockchain.multiplier * 1000000.0 < java.lang.Float.parseFloat(etAmount.text.toString())) {
|
||||
etFee.error = getString(R.string.not_enough_funds)
|
||||
} else {
|
||||
etFee.error = null
|
||||
|
|
@ -214,7 +213,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
requestElectrum(card!!, ElectrumRequest.checkBalance(card!!.wallet))
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.checkBalance(ctx.card!!.wallet))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -236,10 +235,10 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
// rounding gas price to integer gwei
|
||||
val l = BigInteger(gasPrice, 16).divide(BigInteger.valueOf(1000000000L)).multiply(BigInteger.valueOf(1000000000L))
|
||||
|
||||
val m = if (card!!.blockchain == Blockchain.Token) BigInteger.valueOf(60000) else BigInteger.valueOf(21000)
|
||||
val minFeeInGwei = card!!.getAmountInGwei(l.multiply(m).toString())
|
||||
val normalFeeInGwei = card!!.getAmountInGwei(l.multiply(BigInteger.valueOf(12)).divide(BigInteger.valueOf(10)).multiply(m).toString())
|
||||
val maxFeeInGwei = card!!.getAmountInGwei(l.multiply(BigInteger.valueOf(15)).divide(BigInteger.valueOf(10)).multiply(m).toString())
|
||||
val m = if (ctx.blockchain == Blockchain.Token) BigInteger.valueOf(60000) else BigInteger.valueOf(21000)
|
||||
val minFeeInGwei = (ctx.coinData!! as EthData).getAmountInGwei(l.multiply(m).toString())
|
||||
val normalFeeInGwei = (ctx.coinData!! as EthData).getAmountInGwei(l.multiply(BigInteger.valueOf(12)).divide(BigInteger.valueOf(10)).multiply(m).toString())
|
||||
val maxFeeInGwei = (ctx.coinData!! as EthData).getAmountInGwei(l.multiply(BigInteger.valueOf(15)).divide(BigInteger.valueOf(10)).multiply(m).toString())
|
||||
|
||||
minFee = minFeeInGwei
|
||||
normalFee = normalFeeInGwei
|
||||
|
|
@ -250,7 +249,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
feeRequestSuccess = true
|
||||
balanceRequestSuccess = true
|
||||
dtVerified = Date()
|
||||
minFeeInInternalUnits = card!!.internalUnitsFromString(normalFeeInGwei)
|
||||
minFeeInInternalUnits = CoinEngine.InternalAmount(normalFeeInGwei)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +292,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
when (blockCount) {
|
||||
ServerApiHelper.ESTIMATE_FEE_MINIMAL -> {
|
||||
minFee = strFee
|
||||
minFeeInInternalUnits = card!!.internalUnitsFromString(strFee)
|
||||
minFeeInInternalUnits = CoinEngine.InternalAmount(strFee)
|
||||
}
|
||||
|
||||
ServerApiHelper.ESTIMATE_FEE_NORMAL -> {
|
||||
|
|
@ -343,15 +342,16 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
if (data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
|
||||
val updatedCard = TangemCard(data.getStringExtra("UID"))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra("Card"))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
}
|
||||
if (resultCode == SignPaymentActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(baseContext, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
intent.putExtra("IncFee", isIncludeFee)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
|
||||
return
|
||||
|
|
@ -361,8 +361,9 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
} else if (requestCode == REQUEST_CODE_REQUEST_PIN2) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
val intent = Intent(baseContext, SignPaymentActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
intent.putExtra("Wallet", etWallet!!.text.toString())
|
||||
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, etAmount.text.toString())
|
||||
intent.putExtra("Fee", etFee.text.toString())
|
||||
|
|
@ -393,14 +394,15 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO - move to BtcEngine
|
||||
@Throws(Exception::class)
|
||||
internal fun buildSize(outputAddress: String, outFee: String, outAmount: String): Int {
|
||||
val myAddress = card!!.wallet
|
||||
val pbKey = card!!.walletPublicKey
|
||||
val pbComprKey = card!!.walletPublicKeyRar
|
||||
val myAddress = ctx.card!!.wallet
|
||||
val pbKey = ctx.card!!.walletPublicKey
|
||||
val pbComprKey = ctx.card!!.walletPublicKeyRar
|
||||
|
||||
// build script for our address
|
||||
val rawTxList = card!!.unspentTransactions
|
||||
val rawTxList = (ctx.coinData!! as BtcData).unspentTransactions
|
||||
val outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes
|
||||
|
||||
// collect unspent
|
||||
|
|
@ -466,7 +468,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
private fun requestInfura(method: String) {
|
||||
if (UtilHelper.isOnline(this)) {
|
||||
serverApiHelper.infura(method, 67, card!!.wallet, "", "")
|
||||
serverApiHelper.infura(method, 67, ctx.card!!.wallet, "", "")
|
||||
} else
|
||||
finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.data.nfc.CreateNewWalletTask
|
|||
import com.tangem.domain.cardReader.CardProtocol
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.Util
|
||||
|
|
@ -30,7 +31,7 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
|
||||
}
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
|
||||
private var createNewWalletTask: CreateNewWalletTask? = null
|
||||
|
|
@ -46,10 +47,9 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
tvCardId.text = card!!.cidDescription
|
||||
tvCardId.text = ctx.card!!.cidDescription
|
||||
|
||||
progressBar = findViewById(R.id.progressBar)
|
||||
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
|
||||
|
|
@ -65,13 +65,13 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
|
|||
val sUID = Util.byteArrayToHexString(uid)
|
||||
// Log.v(TAG, "UID: " + sUID);
|
||||
|
||||
if (sUID == card!!.uid) {
|
||||
if (sUID == ctx.card!!.uid) {
|
||||
if (lastReadSuccess) {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 5000
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 5000
|
||||
} else {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 65000
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
|
||||
}
|
||||
createNewWalletTask = CreateNewWalletTask(this, card, nfcManager, isoDep, this)
|
||||
createNewWalletTask = CreateNewWalletTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
createNewWalletTask!!.start()
|
||||
} else {
|
||||
// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.data.nfc.VerifyCardTask
|
|||
import com.tangem.domain.cardReader.CardProtocol
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.Util
|
||||
|
|
@ -33,7 +34,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var lastReadSuccess = true
|
||||
private var verifyCardTask: VerifyCardTask? = null
|
||||
private var requestPIN2Count = 0
|
||||
|
|
@ -46,21 +47,20 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
tvIssuer.text = card!!.issuerDescription
|
||||
//tvBlockchain.text = card!!.blockchainName
|
||||
if (card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(card!!.blockchainName)
|
||||
tvIssuer.text = ctx.card!!.issuerDescription
|
||||
//tvBlockchain.text = ctx.card!!.blockchainName
|
||||
if (ctx.card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
} else
|
||||
tvBlockchain.text = card!!.blockchainName
|
||||
tvBlockchain.text = ctx.card!!.blockchainName
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
imgBlockchain.setImageResource(card!!.blockchain.getImageResource(this, card!!.tokenSymbol))
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
imgBlockchain.setImageResource(ctx.card!!.blockchain.getImageResource(this, ctx.card!!.tokenSymbol))
|
||||
|
||||
if (card!!.useDefaultPIN1()!!) {
|
||||
if (ctx.card!!.useDefaultPIN1()!!) {
|
||||
imgPIN.setImageResource(R.drawable.unlock_pin1)
|
||||
imgPIN.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
@ -68,11 +68,11 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
imgPIN.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_user_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
if (card!!.pauseBeforePIN2 > 0 && (card!!.useDefaultPIN2()!! || !card!!.useSmartSecurityDelay())) {
|
||||
if (ctx.card!!.pauseBeforePIN2 > 0 && (ctx.card!!.useDefaultPIN2()!! || !ctx.card!!.useSmartSecurityDelay())) {
|
||||
imgPIN2orSecurityDelay.setImageResource(R.drawable.timer)
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, String.format(getString(R.string.this_banknote_will_enforce), card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, String.format(getString(R.string.this_banknote_will_enforce), ctx.card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
|
||||
|
||||
} else if (card!!.useDefaultPIN2()!!) {
|
||||
} else if (ctx.card!!.useDefaultPIN2()!!) {
|
||||
imgPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2)
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_default_PIN2_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
@ -80,7 +80,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.this_banknote_protected_user_PIN2_code, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
if (card!!.useDevelopersFirmware()!!) {
|
||||
if (ctx.card!!.useDevelopersFirmware()!!) {
|
||||
imgDeveloperVersion.setImageResource(R.drawable.ic_developer_version)
|
||||
imgDeveloperVersion.visibility = View.VISIBLE
|
||||
imgDeveloperVersion.setOnClickListener { Toast.makeText(this@EmptyWalletActivity, R.string.unlocked_banknote_only_development_use, Toast.LENGTH_LONG).show() }
|
||||
|
|
@ -92,8 +92,8 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
requestPIN2Count = 0
|
||||
val intent = Intent(baseContext, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
intent.putExtra("UID", ctx.card!!.uid)
|
||||
intent.putExtra("Card", ctx.card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
|
||||
}
|
||||
}
|
||||
|
|
@ -127,14 +127,14 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
|
||||
val updatedCard = TangemCard(data.getStringExtra("UID"))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra("Card"))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(baseContext, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
intent.putExtra("UID", ctx.card!!.uid)
|
||||
intent.putExtra("Card", ctx.card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2)
|
||||
return
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
|
||||
val uid = tag.id
|
||||
val sUID = Util.byteArrayToHexString(uid)
|
||||
if (card!!.uid != sUID) {
|
||||
if (ctx.card!!.uid != sUID) {
|
||||
// Log.d(TAG, "Invalid UID: " + sUID);
|
||||
nfcManager!!.ignoreTag(isoDep.tag)
|
||||
return
|
||||
|
|
@ -168,7 +168,7 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
isoDep.timeout = 65000
|
||||
}
|
||||
//lastTag = tag;
|
||||
verifyCardTask = VerifyCardTask(this, card, nfcManager, isoDep, this)
|
||||
verifyCardTask = VerifyCardTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
verifyCardTask!!.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
|
@ -254,8 +254,8 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
|
||||
private fun doCreateNewWallet() {
|
||||
val intent = Intent(this, CreateNewWalletActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
intent.putExtra("UID", ctx.card!!.uid)
|
||||
intent.putExtra("Card", ctx.card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
rlProgressBar.post {
|
||||
rlProgressBar.visibility = View.GONE
|
||||
|
||||
// TODO - ??? remove save and load???
|
||||
val cardInfo = Bundle()
|
||||
cardInfo.putString("UID", cardProtocol.card.uid)
|
||||
val bCard = Bundle()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.nfc.NfcAdapter
|
|||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.text.Html
|
||||
import android.text.InputFilter
|
||||
import android.view.View
|
||||
import com.tangem.data.network.Cryptonit_OtherAPI
|
||||
|
|
@ -15,6 +16,7 @@ import com.tangem.domain.cardReader.NfcManager
|
|||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.*
|
||||
|
|
@ -30,7 +32,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
private const val REQUEST_CODE_SCAN_QR_USER_ID = 3
|
||||
}
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var cryptonit: Cryptonit_OtherAPI? = null
|
||||
|
||||
|
|
@ -44,8 +46,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
cryptonit = Cryptonit_OtherAPI(this)
|
||||
|
||||
|
|
@ -53,33 +54,14 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
tvUserID.text = cryptonit!!.userId
|
||||
tvSecret.text = cryptonit!!.secretDescription
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvWallet.text = card!!.wallet
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
tvWallet.text = ctx.card!!.wallet
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
when (card!!.blockchain) {
|
||||
Blockchain.Ethereum, Blockchain.EthereumTestNet -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
}
|
||||
Blockchain.Bitcoin, Blockchain.BitcoinTestNet, Blockchain.BitcoinCash, Blockchain.BitcoinCashTestNet -> {
|
||||
tvCurrency.text = card!!.blockchain.currency
|
||||
}
|
||||
else -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
}
|
||||
}
|
||||
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
|
||||
|
||||
etAmount.setText(engine.convertByteArrayToAmount(card!!, card!!.denomination))
|
||||
when (card!!.blockchain) {
|
||||
Blockchain.Bitcoin ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
|
||||
Blockchain.BitcoinCash ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(8))
|
||||
Blockchain.Ethereum ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(18))
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
|
||||
etAmount.filters=engine.amountInputFilters
|
||||
|
||||
// set listeners
|
||||
btnLoad.setOnClickListener {
|
||||
|
|
@ -93,7 +75,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.cryptonit_request_withdrawal)
|
||||
|
||||
cryptonit!!.requestCryptoWithdrawal(card!!.blockchain.currency, dblAmount.toString(), card!!.wallet)
|
||||
cryptonit!!.requestCryptoWithdrawal(ctx.blockchain.currency, dblAmount.toString(), ctx.card!!.wallet)
|
||||
} catch (e: Exception) {
|
||||
etAmount.error = getString(R.string.unknown_amount_format)
|
||||
}
|
||||
|
|
@ -122,7 +104,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
ivRefreshBalance.setOnClickListener { doRequestBalance() }
|
||||
|
||||
cryptonit!!.setBalanceListener { response ->
|
||||
when (card!!.blockchain) {
|
||||
when (ctx.blockchain) {
|
||||
Blockchain.Ethereum, Blockchain.EthereumTestNet -> {
|
||||
tvBalance.text = response.eth_available
|
||||
}
|
||||
|
|
@ -133,7 +115,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
}
|
||||
}
|
||||
|
||||
tvBalanceCurrency.text = card!!.blockchain.currency
|
||||
tvBalanceCurrency.text = ctx.blockchain.currency
|
||||
tvBalance.setTextColor(Color.BLACK)
|
||||
rlProgressBar.visibility = View.INVISIBLE
|
||||
btnLoad.isActivated = true
|
||||
|
|
@ -161,7 +143,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
|
||||
tvError.visibility = View.INVISIBLE
|
||||
cryptonit!!.requestBalance(card!!.blockchain.currency, "USD")
|
||||
cryptonit!!.requestBalance(ctx.blockchain.currency, "USD")
|
||||
} else {
|
||||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = getString(R.string.cryptonit_not_enough_account_data)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.nfc.NfcAdapter
|
|||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.text.Html
|
||||
import android.text.InputFilter
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
|
|
@ -17,6 +18,7 @@ import com.tangem.domain.cardReader.NfcManager
|
|||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_withdrawal.*
|
||||
|
|
@ -29,7 +31,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
val TAG: String = PrepareCryptonitWithdrawalActivity::class.java.simpleName
|
||||
}
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var cryptonit: Cryptonit? = null
|
||||
|
||||
|
|
@ -43,8 +45,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
cryptonit = Cryptonit(this)
|
||||
|
||||
|
|
@ -52,24 +53,16 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
etPassword.setText(cryptonit!!.password)
|
||||
etFee.setText(cryptonit!!.fee)
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvWallet.text = card!!.wallet
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
tvWallet.text = ctx.card!!.wallet
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
when (card!!.blockchain) {
|
||||
Blockchain.Ethereum -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
}
|
||||
Blockchain.Bitcoin, Blockchain.BitcoinCash -> {
|
||||
tvCurrency.text = card!!.blockchain.currency
|
||||
}
|
||||
else -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
}
|
||||
}
|
||||
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
|
||||
tvFeeCurrency.text = tvCurrency.text
|
||||
|
||||
etAmount.setText(engine.convertByteArrayToAmount(card!!, card!!.denomination))
|
||||
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
|
||||
etAmount.filters=engine.amountInputFilters
|
||||
|
||||
etAmount.setOnEditorActionListener { lv, actionId, event ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
val imm = lv.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
|
@ -79,7 +72,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
false
|
||||
}
|
||||
}
|
||||
when (card!!.blockchain) {
|
||||
when (ctx.blockchain) {
|
||||
Blockchain.Bitcoin -> {
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
|
||||
etFee.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
|
||||
|
|
@ -109,7 +102,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.cryptonit_request_withdrawal)
|
||||
|
||||
cryptonit!!.requestWithdrawCoins(card!!.blockchain.currency, dblAmount, card!!.wallet)
|
||||
cryptonit!!.requestWithdrawCoins(ctx.blockchain.currency, dblAmount, ctx.card!!.wallet)
|
||||
} catch (e: Exception) {
|
||||
etAmount.error = getString(R.string.unknown_amount_format)
|
||||
}
|
||||
|
|
@ -154,7 +147,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
|
||||
tvError.visibility = View.INVISIBLE
|
||||
cryptonit!!.requestBalance(card!!.blockchain.currency)
|
||||
cryptonit!!.requestBalance(ctx.card!!.blockchain.currency)
|
||||
} else {
|
||||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = getString(R.string.cryptonit_not_enough_account_data)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import android.nfc.NfcAdapter
|
|||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.text.Html
|
||||
import android.text.InputFilter
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
|
|
@ -21,6 +22,7 @@ import com.tangem.domain.cardReader.NfcManager
|
|||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_prepare_kraken_withdrawal.*
|
||||
|
|
@ -37,7 +39,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
private const val REQUEST_CODE_SCAN_QR = 1
|
||||
}
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var kraken: Kraken? = null
|
||||
private var fee: BigDecimal? = null
|
||||
|
|
@ -51,42 +53,21 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
kraken = Kraken(this)
|
||||
|
||||
tvKey.text = kraken!!.key
|
||||
tvSecret.text = kraken!!.secretDescription
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvWallet.text = card!!.wallet
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
tvWallet.text = ctx.card!!.wallet
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
when (card!!.blockchain) {
|
||||
Blockchain.Ethereum, Blockchain.EthereumTestNet -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
|
||||
|
||||
}
|
||||
Blockchain.Bitcoin, Blockchain.BitcoinTestNet, Blockchain.BitcoinCash, Blockchain.BitcoinCashTestNet -> {
|
||||
tvCurrency.text = card!!.blockchain.currency
|
||||
}
|
||||
else -> {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
}
|
||||
}
|
||||
|
||||
etAmount.setText(engine.convertByteArrayToAmount(card!!, card!!.denomination))
|
||||
when (card!!.blockchain) {
|
||||
Blockchain.Bitcoin ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
|
||||
Blockchain.BitcoinCash ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(8))
|
||||
Blockchain.Ethereum ->
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(18))
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
|
||||
etAmount.filters=engine.amountInputFilters
|
||||
|
||||
etAmount.setOnEditorActionListener { lv, actionId, event ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
|
|
@ -108,7 +89,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
rlProgressBar.visibility = View.VISIBLE
|
||||
tvProgressDescription.text = getString(R.string.kraken_request_withdrawal)
|
||||
|
||||
kraken!!.requestWithdrawInfo(card!!.blockchain.currency, dblAmount.toString(), card!!.wallet)
|
||||
kraken!!.requestWithdrawInfo(ctx.blockchain.currency, dblAmount.toString(), ctx.card!!.wallet)
|
||||
} catch (e: Exception) {
|
||||
etAmount.error = getString(R.string.unknown_amount_format)
|
||||
}
|
||||
|
|
@ -126,7 +107,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = Arrays.toString(response.error)
|
||||
} else {
|
||||
when (card!!.blockchain) {
|
||||
when (ctx.blockchain) {
|
||||
Blockchain.Ethereum -> {
|
||||
tvBalance.text = response.result.XETH.trimEnd('0')
|
||||
}
|
||||
|
|
@ -140,7 +121,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
tvBalance.text = "???"
|
||||
}
|
||||
}
|
||||
tvBalanceCurrency.text = card!!.blockchain.currency
|
||||
tvBalanceCurrency.text = ctx.blockchain.currency
|
||||
tvBalance.setTextColor(Color.BLACK)
|
||||
btnLoad.visibility = View.VISIBLE
|
||||
}
|
||||
|
|
@ -190,7 +171,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
builder.setTitle("Please confirm withdraw")
|
||||
|
||||
// Set a message for alert dialog
|
||||
builder.setMessage(String.format("Continue with fee %s %s?", fee!!.toString().trimEnd('0'), card!!.blockchain.currency))
|
||||
builder.setMessage(String.format("Continue with fee %s %s?", fee!!.toString().trimEnd('0'), ctx.blockchain.currency))
|
||||
|
||||
// On click listener for dialog buttons
|
||||
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
||||
|
|
@ -207,7 +188,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
|
|||
tvProgressDescription.text = getString(R.string.kraken_request_withdrawal)
|
||||
|
||||
//Toast.makeText(this, String.format("Withdraw %s!",dblAmount.toString()), Toast.LENGTH_LONG).show()
|
||||
kraken!!.requestWithdraw(card!!.blockchain.currency, dblAmount.toString(), card!!.wallet)
|
||||
kraken!!.requestWithdraw(ctx.blockchain.currency, dblAmount.toString(), ctx.card!!.wallet)
|
||||
} catch (e: Exception) {
|
||||
etAmount.error = getString(R.string.unknown_amount_format)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.domain.cardReader.NfcManager
|
|||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
import com.tangem.util.FormatUtil
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -32,8 +33,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
private const val REQUEST_CODE_SEND_PAYMENT = 2
|
||||
}
|
||||
|
||||
private var useCurrency: Boolean = false
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
|
@ -45,59 +45,29 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx= TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
if (card!!.blockchain == Blockchain.Token) {
|
||||
val html = Html.fromHtml(engine!!.getBalanceWithAlter(card))
|
||||
tvBalance.text = html
|
||||
val html = Html.fromHtml(engine!!.balanceHTML)
|
||||
tvBalance.text = html
|
||||
|
||||
//TODO - to engine
|
||||
if (ctx.card!!.blockchain == Blockchain.Token) {
|
||||
rgIncFee!!.visibility = View.INVISIBLE
|
||||
} else {
|
||||
tvBalance.text = engine!!.getBalanceWithAlter(card)
|
||||
rgIncFee!!.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
if (card!!.remainingSignatures < 2)
|
||||
if (ctx.card!!.remainingSignatures < 2)
|
||||
etAmount.isEnabled = false
|
||||
|
||||
// Ethereum EthereumTestNet
|
||||
if (card!!.blockchain == Blockchain.Ethereum || card!!.blockchain == Blockchain.EthereumTestNet) {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
useCurrency = false
|
||||
etAmount.setText(engine.getBalanceValue(card))
|
||||
}
|
||||
|
||||
// Bitcoin BitcoinTestNet
|
||||
else if (card!!.blockchain == Blockchain.Bitcoin || card!!.blockchain == Blockchain.BitcoinTestNet) {
|
||||
val balance = engine.getBalanceLong(card)!! / (card!!.blockchain.multiplier)
|
||||
tvCurrency.text = card!!.blockchain.currency
|
||||
useCurrency = true
|
||||
val output = FormatUtil.DoubleToString(balance)
|
||||
etAmount.setText(output)
|
||||
}
|
||||
|
||||
// BitcoinCash BitcoinCashTestNet
|
||||
else if (card!!.blockchain == Blockchain.BitcoinCash || card!!.blockchain == Blockchain.BitcoinCashTestNet) {
|
||||
val balance = engine.getBalanceLong(card)!! / (card!!.blockchain.multiplier)
|
||||
tvCurrency.text = card!!.blockchain.currency
|
||||
useCurrency = true
|
||||
val output = FormatUtil.DoubleToString(balance)
|
||||
} else {
|
||||
tvCurrency.text = engine.getBalanceCurrency(card)
|
||||
useCurrency = false
|
||||
etAmount.setText(engine.getBalanceValue(card))
|
||||
}
|
||||
tvCurrency.text = engine.balance.currency
|
||||
etAmount.setText(engine.balance.stringToEdit)
|
||||
|
||||
// limit number of symbols after comma
|
||||
if (card!!.blockchain == Blockchain.Bitcoin)
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(8))
|
||||
if (card!!.blockchain == Blockchain.BitcoinCash)
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(8))
|
||||
if (card!!.blockchain == Blockchain.Ethereum)
|
||||
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(18))
|
||||
etAmount.filters = engine.amountInputFilters
|
||||
|
||||
// set listeners
|
||||
etAmount.setOnEditorActionListener { lv, actionId, event ->
|
||||
|
|
@ -111,12 +81,14 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
}
|
||||
btnVerify.setOnClickListener {
|
||||
val strAmount: String = etAmount.text.toString().replace(",", ".")
|
||||
|
||||
val engine1 = CoinEngineFactory.create(card!!.blockchain)
|
||||
val engine1 = CoinEngineFactory.create(ctx.card!!.blockchain)
|
||||
|
||||
val strAmount: String = etAmount.text.toString().replace(",", ".")
|
||||
val amount=engine1.convertToAmount(etAmount.text.toString())
|
||||
|
||||
try {
|
||||
if (!engine.checkAmount(card, etAmount.text.toString()))
|
||||
if (!engine.checkNewTransactionAmount(amount))
|
||||
etAmount.error = getString(R.string.not_enough_funds_on_your_card)
|
||||
} catch (e: Exception) {
|
||||
etAmount.error = getString(R.string.unknown_amount_format)
|
||||
|
|
@ -124,7 +96,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
var checkAddress = false
|
||||
if (engine1 != null)
|
||||
checkAddress = engine1.validateAddress(etWallet.text.toString(), card)
|
||||
checkAddress = engine1.validateAddress(etWallet.text.toString())
|
||||
|
||||
// check wallet address
|
||||
if (!checkAddress) {
|
||||
|
|
@ -132,20 +104,20 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (etWallet.text.toString() == card!!.wallet) {
|
||||
if (etWallet.text.toString() == ctx.card!!.wallet) {
|
||||
etWallet.error = getString(R.string.destination_wallet_address_equal_source_address)
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
// check enough funds
|
||||
if (etAmount.text.toString().replace(",", ".").toDouble() > engine.getBalanceValue(card).replace(",", ".").toDouble()) {
|
||||
etAmount.error = getString(R.string.not_enough_funds_on_your_card)
|
||||
return@setOnClickListener
|
||||
}
|
||||
// TODO - double with engin.checkAmount
|
||||
// if (etAmount.text.toString().replace(",", ".").toDouble() > engine.getBalanceValue(card).replace(",", ".").toDouble()) {
|
||||
// etAmount.error = getString(R.string.not_enough_funds_on_your_card)
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
|
||||
val intent = Intent(baseContext, ConfirmPaymentActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
intent.putExtra("Wallet", etWallet!!.text.toString())
|
||||
intent.putExtra("IncFee", (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn))
|
||||
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, strAmount)
|
||||
|
|
@ -176,7 +148,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
|
||||
var code = data.getStringExtra("QRCode")
|
||||
when (card!!.blockchain) {
|
||||
when (ctx.card!!.blockchain) {
|
||||
Blockchain.Bitcoin -> {
|
||||
if (code.contains("bitcoin:")) {
|
||||
val tmp = code.split("bitcoin:".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.data.nfc.PurgeTask
|
|||
import com.tangem.domain.cardReader.CardProtocol
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.Util
|
||||
|
|
@ -29,7 +30,7 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
|
|||
const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER
|
||||
}
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var purgeTask: PurgeTask? = null
|
||||
|
||||
|
|
@ -43,10 +44,9 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
|
|||
|
||||
MainActivity.commonInit(applicationContext)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
|
||||
progressBar.visibility = View.INVISIBLE
|
||||
}
|
||||
|
|
@ -82,9 +82,9 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
|
|||
val sUID = Util.byteArrayToHexString(uid)
|
||||
// Log.v(TAG, "UID: $sUID")
|
||||
|
||||
if (sUID == card!!.uid) {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 65000
|
||||
purgeTask = PurgeTask(this, card, nfcManager, isoDep, this)
|
||||
if (sUID == ctx.card!!.uid) {
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
|
||||
purgeTask = PurgeTask(this, ctx.card, nfcManager, isoDep, this)
|
||||
purgeTask!!.start()
|
||||
} else {
|
||||
// this Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card.getUID() + ")");
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ import com.tangem.data.network.ServerApiHelper
|
|||
import com.tangem.data.network.ServerApiHelperElectrum
|
||||
import com.tangem.data.network.model.InfuraResponse
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.R
|
||||
import org.json.JSONException
|
||||
|
|
@ -30,7 +28,7 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
private var serverApiHelper: ServerApiHelper = ServerApiHelper()
|
||||
private var serverApiHelperElectrum: ServerApiHelperElectrum = ServerApiHelperElectrum()
|
||||
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
private var tx: String? = null
|
||||
private var nfcManager: NfcManager? = null
|
||||
|
||||
|
|
@ -42,19 +40,18 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
val intent = intent
|
||||
card = TangemCard(getIntent().getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
|
||||
ctx=TangemContext.loadFromBundle(this, intent.extras)
|
||||
tx = intent.getStringExtra(EXTRA_TX)
|
||||
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
if (card!!.blockchain == Blockchain.Ethereum || card!!.blockchain == Blockchain.EthereumTestNet || card!!.blockchain == Blockchain.Token)
|
||||
if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet || ctx.blockchain == Blockchain.Token)
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_SEND_RAW_TRANSACTION, "")
|
||||
else if (card!!.blockchain == Blockchain.Bitcoin || card!!.blockchain == Blockchain.BitcoinTestNet)
|
||||
requestElectrum(card!!, ElectrumRequest.broadcast(card!!.wallet, tx))
|
||||
else if (card!!.blockchain == Blockchain.BitcoinCash || card!!.blockchain == Blockchain.BitcoinCashTestNet)
|
||||
requestElectrum(card!!, ElectrumRequest.broadcast(card!!.wallet, tx))
|
||||
else if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet)
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.card!!.wallet, tx))
|
||||
else if (ctx.blockchain == Blockchain.BitcoinCash || ctx.blockchain == Blockchain.BitcoinCashTestNet)
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.card!!.wallet, tx))
|
||||
|
||||
// request electrum listener
|
||||
val electrumBodyListener: ServerApiHelperElectrum.ElectrumRequestDataListener = object : ServerApiHelperElectrum.ElectrumRequestDataListener {
|
||||
|
|
@ -69,11 +66,11 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
finishWithSuccess()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
requestElectrum(card!!, ElectrumRequest.broadcast(card!!.wallet, tx))
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.card!!.wallet, tx))
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
requestElectrum(card!!, ElectrumRequest.broadcast(card!!.wallet, tx))
|
||||
requestElectrum(ctx.card!!, ElectrumRequest.broadcast(ctx.card!!.wallet, tx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -104,9 +101,9 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
hashTX = hashTX.substring(2)
|
||||
}
|
||||
|
||||
val nonce = card!!.confirmedTXCount
|
||||
val nonce = (ctx.coinData!! as EthData).confirmedTXCount
|
||||
nonce.add(BigInteger.valueOf(1))
|
||||
card!!.confirmedTXCount = nonce
|
||||
(ctx.coinData!! as EthData).confirmedTXCount = nonce
|
||||
|
||||
finishWithSuccess()
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -163,7 +160,7 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
|||
|
||||
private fun requestInfura(method: String, contract: String) {
|
||||
if (UtilHelper.isOnline(this)) {
|
||||
serverApiHelper.infura(method, 67, card!!.wallet, contract, tx)
|
||||
serverApiHelper.infura(method, 67, ctx.card!!.wallet, contract, tx)
|
||||
} else
|
||||
finishWithError(getString(R.string.no_connection))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.data.nfc.SignPaymentTask
|
|||
import com.tangem.domain.cardReader.CardProtocol
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.TangemContext
|
||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.Util
|
||||
|
|
@ -36,7 +37,7 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
|
||||
private var signPaymentTask: SignPaymentTask? = null
|
||||
|
||||
|
|
@ -56,15 +57,14 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
|
||||
nfcManager = NfcManager(this, this)
|
||||
|
||||
card = TangemCard(intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(intent.extras!!.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx=TangemContext.loadFromBundle(this, intent.extras)
|
||||
|
||||
amountStr = intent.getStringExtra(EXTRA_AMOUNT)
|
||||
feeStr = intent.getStringExtra("Fee")
|
||||
isIncludeFee = intent.getBooleanExtra("IncFee", true)
|
||||
outAddressStr = intent.getStringExtra("Wallet")
|
||||
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
|
||||
progressBar = findViewById(R.id.progressBar)
|
||||
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
|
||||
|
|
@ -121,13 +121,13 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
val sUID = Util.byteArrayToHexString(uid)
|
||||
// Log.v(TAG, "UID: $sUID")
|
||||
|
||||
if (sUID == card!!.uid) {
|
||||
if (sUID == ctx.card!!.uid) {
|
||||
if (lastReadSuccess) {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 5000
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 5000
|
||||
} else {
|
||||
isoDep.timeout = card!!.pauseBeforePIN2 + 65000
|
||||
isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000
|
||||
}
|
||||
signPaymentTask = SignPaymentTask(this, card, nfcManager, isoDep, this, amountStr, feeStr, isIncludeFee, outAddressStr)
|
||||
signPaymentTask = SignPaymentTask(this, ctx, nfcManager, isoDep, this, amountStr, feeStr, isIncludeFee, outAddressStr)
|
||||
signPaymentTask!!.start()
|
||||
} else {
|
||||
// Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card!!.uid + ")")
|
||||
|
|
|
|||
|
|
@ -62,7 +62,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
private var serverApiHelperElectrum: ServerApiHelperElectrum = ServerApiHelperElectrum()
|
||||
|
||||
private var singleToast: Toast? = null
|
||||
private var card: TangemCard? = null
|
||||
//private var card: TangemCard? = null
|
||||
//private var engine: CoinEngine? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
|
||||
private var lastTag: Tag? = null
|
||||
private var lastReadSuccess = true
|
||||
private var verifyCardTask: VerifyCardTask? = null
|
||||
|
|
@ -81,8 +84,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
super.onCreate(savedInstanceState)
|
||||
nfcManager = NfcManager(activity, this)
|
||||
|
||||
card = TangemCard(activity.intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
card!!.loadFromBundle(activity.intent.extras.getBundle(TangemCard.EXTRA_CARD))
|
||||
ctx = TangemContext.loadFromBundle(activity, activity.intent.extras)
|
||||
|
||||
// card = TangemCard(activity.intent.getStringExtra(TangemCard.EXTRA_UID))
|
||||
// card!!.loadFromBundle(activity.intent.extras.getBundle(TangemCard.EXTRA_CARD))
|
||||
//
|
||||
// engine = CoinEngineFactory.create(activity, card!!, activity.intent.extras.getBundle(CoinEngine.EXTRA_ENGINE))
|
||||
|
||||
lastTag = activity.intent.getParcelableExtra(MainActivity.EXTRA_LAST_DISCOVERED_TAG)
|
||||
|
||||
|
|
@ -96,13 +103,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
if (card!!.blockchain == Blockchain.Token)
|
||||
if (ctx.blockchain == Blockchain.Token)
|
||||
tvBalance.setSingleLine(false)
|
||||
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!))
|
||||
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
val visibleFlag = engine?.inOutPutVisible() ?: true
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
|
||||
btnExtract.isEnabled = false
|
||||
btnExtract.backgroundTintList = inactiveColor
|
||||
|
|
@ -111,13 +115,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
startVerify(lastTag)
|
||||
|
||||
tvWallet.text = card!!.wallet
|
||||
tvWallet.text = ctx.card!!.wallet
|
||||
|
||||
// set listeners
|
||||
srl!!.setOnRefreshListener { refresh() }
|
||||
btnLookup.setOnClickListener {
|
||||
val engineClick = CoinEngineFactory.create(card!!.blockchain)
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, engineClick.getShareWalletUriExplorer(card))
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, engine!!.shareWalletUriExplorer)
|
||||
startActivity(browserIntent)
|
||||
}
|
||||
btnCopy.setOnClickListener { doShareWallet(false) }
|
||||
|
|
@ -132,7 +136,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
when (items[which]) {
|
||||
getString(R.string.in_app) -> {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_VIEW, CoinEngineFactory.create(card!!.blockchain)!!.getShareWalletUri(card))
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
val intent = Intent(Intent.ACTION_VIEW, engine!!.shareWalletUri)
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
|
|
@ -143,24 +148,27 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
doShareWallet(true)
|
||||
}
|
||||
getString(R.string.load_via_qr) -> {
|
||||
ShowQRCodeDialog.show(activity, engine.getShareWalletUri(card).toString())
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
ShowQRCodeDialog.show(activity, engine!!.shareWalletUri.toString())
|
||||
}
|
||||
// getString(R.string.via_cryptonit2) -> {
|
||||
// val intent = Intent(context, PrepareCryptonitOtherAPIWithdrawalActivity::class.java)
|
||||
// val intent = Intent(ctx, PrepareCryptonitOtherAPIWithdrawalActivity::class.java)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
// startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT)
|
||||
// }
|
||||
getString(R.string.via_cryptonit) -> {
|
||||
val intent = Intent(activity, PrepareCryptonitWithdrawalActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT)
|
||||
}
|
||||
getString(R.string.via_kraken) -> {
|
||||
val intent = Intent(activity, PrepareKrakenWithdrawalActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT)
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -173,7 +181,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
dlg.window.attributes = wlp
|
||||
} else {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_VIEW, CoinEngineFactory.create(card!!.blockchain)!!.getShareWalletUri(card))
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
val intent = Intent(Intent.ACTION_VIEW, engine!!.shareWalletUri)
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
|
|
@ -192,23 +201,25 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
startActivity(intent)
|
||||
}
|
||||
btnExtract.setOnClickListener {
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
if (UtilHelper.isOnline(activity)) {
|
||||
if (!card!!.hasBalanceInfo()) {
|
||||
if (!engine!!.hasBalanceInfo()) {
|
||||
showSingleToast(R.string.cannot_obtain_data_from_blockchain)
|
||||
} else if (!engine.isBalanceNotZero(card))
|
||||
} else if (!engine!!.isBalanceNotZero)
|
||||
showSingleToast(R.string.wallet_empty)
|
||||
else if (!engine.isBalanceAlterNotZero(card))
|
||||
else if (!engine!!.isBalanceAlterNotZero)
|
||||
showSingleToast(R.string.not_enough_eth_for_gas)
|
||||
else if (engine.awaitingConfirmation(card))
|
||||
else if (engine!!.awaitingConfirmation())
|
||||
showSingleToast(R.string.please_wait_while_previous)
|
||||
else if (!engine.checkUnspentTransaction(card))
|
||||
else if (!engine!!.checkUnspentTransaction())
|
||||
showSingleToast(R.string.please_wait_for_confirmation)
|
||||
else if (card!!.remainingSignatures == 0)
|
||||
else if (ctx.card!!.remainingSignatures == 0)
|
||||
showSingleToast(R.string.card_has_no_remaining_signature)
|
||||
else {
|
||||
val intent = Intent(activity, PreparePaymentActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra("Card", card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT)
|
||||
}
|
||||
} else
|
||||
|
|
@ -223,11 +234,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val walletAddress = electrumRequest.params.getString(0)
|
||||
val confBalance = electrumRequest.result.getLong("confirmed")
|
||||
val unconfirmedBalance = electrumRequest.result.getLong("unconfirmed")
|
||||
card!!.isBalanceReceived = true
|
||||
card!!.setBalanceConfirmed(confBalance)
|
||||
card!!.balanceUnconfirmed = unconfirmedBalance
|
||||
card!!.decimalBalance = confBalance.toString()
|
||||
card!!.validationNodeDescription = serverApiHelperElectrum.validationNodeDescription
|
||||
ctx.coinData!!.isBalanceReceived = true
|
||||
(ctx.coinData!! as BtcData).setBalanceConfirmed(confBalance)
|
||||
(ctx.coinData!! as BtcData).balanceUnconfirmed = unconfirmedBalance
|
||||
(ctx.coinData!! as BtcData).decimalBalance = confBalance.toString()
|
||||
(ctx.coinData!! as BtcData).validationNodeDescription = serverApiHelperElectrum.validationNodeDescription
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "FAIL METHOD_GetBalance JSONException")
|
||||
|
|
@ -239,14 +250,14 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val walletAddress = electrumRequest.params.getString(0)
|
||||
val jsUnspentArray = electrumRequest.resultArray
|
||||
try {
|
||||
card!!.unspentTransactions.clear()
|
||||
(ctx.coinData!! as BtcData).unspentTransactions.clear()
|
||||
for (i in 0 until jsUnspentArray.length()) {
|
||||
val jsUnspent = jsUnspentArray.getJSONObject(i)
|
||||
val trUnspent = TangemCard.UnspentTransaction()
|
||||
val trUnspent = BtcData.UnspentTransaction()
|
||||
trUnspent.txID = jsUnspent.getString("tx_hash")
|
||||
trUnspent.Amount = jsUnspent.getInt("value")
|
||||
trUnspent.Height = jsUnspent.getInt("height")
|
||||
card!!.unspentTransactions.add(trUnspent)
|
||||
(ctx.coinData!! as BtcData).unspentTransactions.add(trUnspent)
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
|
|
@ -258,7 +269,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val height = jsUnspent.getInt("height")
|
||||
val hash = jsUnspent.getString("tx_hash")
|
||||
if (height != -1) {
|
||||
requestElectrum(card!!, ElectrumRequest.getTransaction(walletAddress, hash))
|
||||
requestElectrum(ElectrumRequest.getTransaction(walletAddress, hash))
|
||||
}
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
|
|
@ -270,7 +281,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
try {
|
||||
val txHash = electrumRequest.txHash
|
||||
val raw = electrumRequest.resultString
|
||||
val listTx = card!!.unspentTransactions
|
||||
val listTx = (ctx.coinData!! as BtcData).unspentTransactions
|
||||
for (tx in listTx) {
|
||||
if (tx.txID == txHash)
|
||||
tx.Raw = raw
|
||||
|
|
@ -304,12 +315,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val d = l.divide(BigInteger("1000000000000000000", 10))
|
||||
val balance = d.toLong()
|
||||
|
||||
card!!.setBalanceConfirmed(balance)
|
||||
card!!.balanceUnconfirmed = 0L
|
||||
card!!.isBalanceReceived = true
|
||||
if (card!!.blockchain != Blockchain.Token)
|
||||
card!!.decimalBalance = l.toString(10)
|
||||
card!!.decimalBalanceAlter = l.toString(10)
|
||||
ctx.coinData!!.setBalanceConfirmed(balance)
|
||||
ctx.coinData!!.balanceUnconfirmed = 0L
|
||||
ctx.coinData!!.isBalanceReceived = true
|
||||
if (ctx.coinData!!.blockchain != Blockchain.Token)
|
||||
ctx.coinData!!.decimalBalance = l.toString(10)
|
||||
ctx.coinData!!.decimalBalanceAlter = l.toString(10)
|
||||
|
||||
// Log.i("$TAG eth_get_balance", balanceCap)
|
||||
}
|
||||
|
|
@ -318,7 +329,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
var nonce = infuraResponse.result
|
||||
nonce = nonce.substring(2)
|
||||
val count = BigInteger(nonce, 16)
|
||||
card!!.confirmedTXCount = count
|
||||
ctx.coinData!!.confirmedTXCount = count
|
||||
|
||||
// Log.i("$TAG eth_getTransCount", nonce)
|
||||
}
|
||||
|
|
@ -327,7 +338,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
var pending = infuraResponse.result
|
||||
pending = pending.substring(2)
|
||||
val count = BigInteger(pending, 16)
|
||||
card!!.unconfirmedTXCount = count
|
||||
ctx.coinData!!.unconfirmedTXCount = count
|
||||
|
||||
// Log.i("$TAG eth_getPendingTxCount", pending)
|
||||
}
|
||||
|
|
@ -339,8 +350,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val l = BigInteger(balanceCap, 16)
|
||||
val balance = l.toLong()
|
||||
if (l.compareTo(BigInteger.ZERO) == 0) {
|
||||
card!!.blockchainID = Blockchain.Ethereum.id
|
||||
card!!.addTokenToBlockchainName()
|
||||
ctx.card!!.blockchainID = Blockchain.Ethereum.id
|
||||
ctx.card!!.addTokenToBlockchainName()
|
||||
|
||||
ctx.blockchain=Blockchain.Ethereum
|
||||
|
||||
requestCounter--
|
||||
if (requestCounter == 0) srl!!.isRefreshing = false
|
||||
|
|
@ -350,9 +363,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
requestInfura(ServerApiHelper.INFURA_ETH_GET_PENDING_COUNT, "")
|
||||
return
|
||||
}
|
||||
card!!.setBalanceConfirmed(balance)
|
||||
card!!.balanceUnconfirmed = 0L
|
||||
card!!.decimalBalance = l.toString(10)
|
||||
ctx.coinData!!.setBalanceConfirmed(balance)
|
||||
ctx.coinData!!.balanceUnconfirmed = 0L
|
||||
ctx.coinData!!.decimalBalance = l.toString(10)
|
||||
|
||||
// Log.i("$TAG eth_call", balanceCap)
|
||||
|
||||
|
|
@ -384,9 +397,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
Log.e("$TAG TX_RESULT", hashTX)
|
||||
|
||||
val nonce = card!!.confirmedTXCount
|
||||
val nonce = ctx.coinData!!.confirmedTXCount
|
||||
nonce.add(BigInteger.valueOf(1))
|
||||
card!!.confirmedTXCount = nonce
|
||||
ctx.coinData!!.confirmedTXCount = nonce
|
||||
|
||||
Log.e("$TAG TX_RESULT", hashTX)
|
||||
|
||||
|
|
@ -410,27 +423,29 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
override fun onSuccess(cardVerifyAndGetArtworkResponse: CardVerifyAndGetInfo.Response?) {
|
||||
val result = cardVerifyAndGetArtworkResponse?.results!![0]
|
||||
if (result.error != null) {
|
||||
card!!.isOnlineVerified = false
|
||||
ctx.card!!.isOnlineVerified = false
|
||||
return
|
||||
}
|
||||
card!!.isOnlineVerified = result.passed
|
||||
ctx.card!!.isOnlineVerified = result.passed
|
||||
|
||||
if (requestCounter == 0) updateViews()
|
||||
|
||||
if (!result.passed) return
|
||||
|
||||
if (localStorage.checkBatchInfoChanged(card!!, result)) {
|
||||
if (localStorage.checkBatchInfoChanged(ctx.card!!, result)) {
|
||||
Log.w(TAG, "Batch ${result.batch} info changed to '$result'")
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!))
|
||||
localStorage.applySubstitution(card!!)
|
||||
if (card!!.blockchain == Blockchain.Token || card!!.blockchain == Blockchain.Ethereum) {
|
||||
card!!.setBlockchainIDFromCard(Blockchain.Ethereum.id)
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
localStorage.applySubstitution(ctx.card!!)
|
||||
if (ctx.card!!.blockchain == Blockchain.Token || ctx.card!!.blockchain == Blockchain.Ethereum) {
|
||||
ctx.card!!.setBlockchainIDFromCard(Blockchain.Ethereum.id)
|
||||
ctx.blockchain=Blockchain.Ethereum
|
||||
//engine=engine!!.swithToOtherEngine(Blockchain.Ethereum)
|
||||
}
|
||||
refresh()
|
||||
}
|
||||
if (result.artwork != null && localStorage.checkNeedUpdateArtwork(result.artwork)) {
|
||||
Log.w(TAG, "Artwork '${result.artwork!!.id}' updated, need download")
|
||||
serverApiHelper.requestArtwork(result.artwork!!.id, result.artwork!!.getUpdateDate(), card!!)
|
||||
serverApiHelper.requestArtwork(result.artwork!!.id, result.artwork!!.getUpdateDate(), ctx.card!!)
|
||||
updateViews()
|
||||
}
|
||||
// Log.i(TAG, "setCardVerify " + it.results!![0].passed)
|
||||
|
|
@ -446,7 +461,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
val artworkListener: ServerApiHelper.ArtworkListener = object : ServerApiHelper.ArtworkListener {
|
||||
override fun onSuccess(artworkId: String?, inputStream: InputStream?, updateDate: Date?) {
|
||||
localStorage.updateArtwork(artworkId!!, inputStream!!, updateDate!!)
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!))
|
||||
ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(ctx.card!!))
|
||||
}
|
||||
|
||||
override fun onFail(message: String?) {
|
||||
|
|
@ -458,8 +473,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
// request rate info listener
|
||||
serverApiHelper.setRateInfoData {
|
||||
val rate = it.priceUsd.toFloat()
|
||||
card!!.rate = rate
|
||||
card!!.rateAlter = rate
|
||||
ctx.coinData!!.rate = rate
|
||||
ctx.coinData!!.rateAlter = rate
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -504,8 +519,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (data.extras != null && data.extras!!.containsKey("confirmPIN")) {
|
||||
val intent = Intent(activity, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
newPIN = data.getStringExtra("newPIN")
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
} else {
|
||||
|
|
@ -521,8 +537,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (data.extras != null && data.extras!!.containsKey("confirmPIN2")) {
|
||||
val intent = Intent(activity, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
newPIN2 = data.getStringExtra("newPIN2")
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
} else {
|
||||
|
|
@ -535,7 +552,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
}
|
||||
REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (newPIN == "")
|
||||
newPIN = card!!.pin
|
||||
newPIN = ctx.card!!.pin
|
||||
|
||||
if (newPIN2 == "")
|
||||
newPIN2 = PINStorage.getPIN2()
|
||||
|
|
@ -554,8 +571,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
data = Intent()
|
||||
data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(data.extras)
|
||||
// data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
data.putExtra("modification", "delete")
|
||||
} else
|
||||
data.putExtra("modification", "update")
|
||||
|
|
@ -568,33 +586,36 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (data != null && data.extras != null && data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(activity, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra("UID", card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
return
|
||||
} else {
|
||||
if (data != null && data.extras!!.containsKey("message")) {
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.error = data.getStringExtra("message")
|
||||
}
|
||||
}
|
||||
}
|
||||
REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
val intent = Intent(activity, PurgeActivity::class.java)
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_PURGE)
|
||||
}
|
||||
REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
data = Intent()
|
||||
data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(data.extras)
|
||||
// data.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
data.putExtra("modification", "delete")
|
||||
} else {
|
||||
data.putExtra("modification", "update")
|
||||
|
|
@ -607,26 +628,28 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (data != null && data.extras != null && data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(activity, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
|
||||
return
|
||||
} else {
|
||||
if (data != null && data.extras!!.containsKey("message")) {
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.error = data.getStringExtra("message")
|
||||
}
|
||||
}
|
||||
updateViews()
|
||||
}
|
||||
REQUEST_CODE_SEND_PAYMENT, REQUEST_CODE_RECEIVE_PAYMENT -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
card!!.clearInfo()
|
||||
ctx.coinData!!.clearInfo()
|
||||
ctx.card.clearInfo();
|
||||
srl!!.postDelayed({ this.refresh() }, 5000)
|
||||
srl!!.isRefreshing = true
|
||||
updateViews()
|
||||
|
|
@ -636,13 +659,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
if (data.extras!!.containsKey(TangemCard.EXTRA_UID) && data.extras!!.containsKey(TangemCard.EXTRA_CARD)) {
|
||||
val updatedCard = TangemCard(data.getStringExtra(TangemCard.EXTRA_UID))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra(TangemCard.EXTRA_CARD))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (data.extras!!.containsKey("message")) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
card!!.message = data.getStringExtra("message")
|
||||
ctx.message = data.getStringExtra("message")
|
||||
} else {
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.error = data.getStringExtra("message")
|
||||
}
|
||||
}
|
||||
updateViews()
|
||||
|
|
@ -732,24 +755,22 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
timerHideErrorAndMessage = null
|
||||
}
|
||||
|
||||
if (card!!.error == null || card!!.error.isEmpty()) {
|
||||
if (ctx.error == null || ctx.error.isEmpty()) {
|
||||
tvError.visibility = View.GONE
|
||||
tvError.text = ""
|
||||
} else {
|
||||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = card!!.error
|
||||
tvError.text = ctx.error
|
||||
}
|
||||
|
||||
if (card!!.message == null || card!!.message.isEmpty()) {
|
||||
if (ctx.message == null || ctx.message.isEmpty()) {
|
||||
tvMessage!!.text = ""
|
||||
tvMessage!!.visibility = View.GONE
|
||||
} else {
|
||||
tvMessage!!.text = card!!.message
|
||||
tvMessage!!.text = ctx.message
|
||||
tvMessage!!.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
|
||||
if (srl!!.isRefreshing) {
|
||||
tvBalanceLine1.setTextColor(resources.getColor(R.color.primary))
|
||||
tvBalanceLine1.text = getString(R.string.verifying_in_blockchain)
|
||||
|
|
@ -758,39 +779,34 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
tvBalanceEquivalent.text = ""
|
||||
} else {
|
||||
val validator = BalanceValidator()
|
||||
validator.Check(card, false)
|
||||
validator.Check(ctx.card, false)
|
||||
tvBalanceLine1.setTextColor(ContextCompat.getColor(activity, validator.color))
|
||||
tvBalanceLine1.text = validator.firstLine
|
||||
tvBalanceLine2.text = validator.getSecondLine(false)
|
||||
}
|
||||
|
||||
if (engine!!.hasBalanceInfo(card) || card!!.offlineBalance == null) {
|
||||
if ((card!!.blockchain == Blockchain.Token) && (engine.getBalanceWithAlter(card) != null)) {
|
||||
val html = Html.fromHtml(engine.getBalanceWithAlter(card))
|
||||
tvBalance.text = html
|
||||
} else {
|
||||
// tvBalance.text = engine.getBalanceWithAlter(card)
|
||||
tvBalance.text = engine.getBalance(card)
|
||||
tvBalanceEquivalent.text = engine.getBalanceEquivalent(card)
|
||||
}
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
if (engine!!.hasBalanceInfo() || ctx.card!!.offlineBalance == null) {
|
||||
val html = Html.fromHtml(engine!!.balanceHTML)
|
||||
tvBalance.text = html
|
||||
// TODO???
|
||||
tvBalanceEquivalent.text = engine!!.balanceEquivalent
|
||||
} else {
|
||||
val offlineAmount = engine.convertByteArrayToAmount(card, card!!.offlineBalance)
|
||||
if (card!!.blockchain == Blockchain.Token) {
|
||||
tvBalance.setText(R.string.not_implemented)
|
||||
} else
|
||||
tvBalance.text = engine.getAmountDescription(card, offlineAmount)
|
||||
// TODO
|
||||
val html = Html.fromHtml(engine!!.offlineBalanceHTML)
|
||||
tvBalance.text = html
|
||||
}
|
||||
|
||||
tvWallet.text = card!!.wallet
|
||||
tvWallet.text = ctx.card!!.wallet
|
||||
// tvBlockchain.text = card!!.blockchainName
|
||||
|
||||
if (card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(card!!.blockchainName)
|
||||
if (ctx.card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
} else
|
||||
tvBlockchain.text = card!!.blockchainName
|
||||
tvBlockchain.text = ctx.card!!.blockchainName
|
||||
|
||||
if (card!!.hasBalanceInfo()) {
|
||||
if (engine!!.hasBalanceInfo()) {
|
||||
btnExtract.isEnabled = true
|
||||
btnExtract.backgroundTintList = activeColor
|
||||
} else {
|
||||
|
|
@ -798,8 +814,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
btnExtract.backgroundTintList = inactiveColor
|
||||
}
|
||||
|
||||
card!!.error = null
|
||||
card!!.message = null
|
||||
ctx.error = null
|
||||
ctx.message = null
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
|
@ -807,41 +823,41 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
}
|
||||
|
||||
private fun refresh() {
|
||||
if ((srl == null) || (card == null)) return;
|
||||
if ((srl == null) || (ctx.card == null)) return;
|
||||
try {
|
||||
// clear all card data and request again
|
||||
srl!!.isRefreshing = true
|
||||
card!!.clearInfo()
|
||||
card!!.error = null
|
||||
card!!.message = null
|
||||
ctx.coinData.clearInfo();
|
||||
ctx.card!!.clearInfo()
|
||||
//engine=engine!!.swithToBaseEngine()
|
||||
ctx.error = null
|
||||
ctx.message = null
|
||||
requestCounter = 0
|
||||
|
||||
updateViews()
|
||||
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
|
||||
requestVerifyAndGetInfo()
|
||||
|
||||
// Bitcoin
|
||||
if (card!!.blockchain == Blockchain.Bitcoin || card!!.blockchain == Blockchain.BitcoinTestNet) {
|
||||
card!!.setIsBalanceEqual(true)
|
||||
if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet) {
|
||||
ctx.coinData.setIsBalanceEqual(true)
|
||||
|
||||
requestElectrum(card!!, ElectrumRequest.checkBalance(card!!.wallet))
|
||||
requestElectrum(card!!, ElectrumRequest.listUnspent(card!!.wallet))
|
||||
requestElectrum(ElectrumRequest.checkBalance(ctx.card!!.wallet))
|
||||
requestElectrum(ElectrumRequest.listUnspent(ctx.card!!.wallet))
|
||||
requestRateInfo("bitcoin")
|
||||
}
|
||||
|
||||
// BitcoinCash
|
||||
else if (card!!.blockchain == Blockchain.BitcoinCash || card!!.blockchain == Blockchain.BitcoinCashTestNet) {
|
||||
card!!.setIsBalanceEqual(true)
|
||||
else if (ctx.blockchain == Blockchain.BitcoinCash || ctx.blockchain == Blockchain.BitcoinCashTestNet) {
|
||||
ctx.coinData.setIsBalanceEqual(true)
|
||||
|
||||
requestElectrum(card!!, ElectrumRequest.checkBalance(card!!.wallet))
|
||||
requestElectrum(card!!, ElectrumRequest.listUnspent(card!!.wallet))
|
||||
requestElectrum(ElectrumRequest.checkBalance(ctx.card!!.wallet))
|
||||
requestElectrum(ElectrumRequest.listUnspent(ctx.card!!.wallet))
|
||||
requestRateInfo("bitcoin-cash")
|
||||
}
|
||||
|
||||
// Ethereum
|
||||
else if (card!!.blockchain == Blockchain.Ethereum || card!!.blockchain == Blockchain.EthereumTestNet) {
|
||||
else if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet) {
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_GET_BALANCE, "")
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_GET_TRANSACTION_COUNT, "")
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_GET_PENDING_COUNT, "")
|
||||
|
|
@ -849,8 +865,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
}
|
||||
|
||||
// Token
|
||||
else if (card!!.blockchain == Blockchain.Token) {
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_CALL, engine.getContractAddress(card))
|
||||
else if (ctx.blockchain == Blockchain.Token) {
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
requestInfura(ServerApiHelper.INFURA_ETH_CALL, (engine as TokenEngine).getContractAddress(ctx.card))
|
||||
requestRateInfo("ethereum")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -858,10 +875,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestElectrum(card: TangemCard, electrumRequest: ElectrumRequest) {
|
||||
private fun requestElectrum(electrumRequest: ElectrumRequest) {
|
||||
if (UtilHelper.isOnline(activity!!)) {
|
||||
requestCounter++
|
||||
serverApiHelperElectrum.electrumRequestData(card, electrumRequest)
|
||||
serverApiHelperElectrum.electrumRequestData(ctx.card, electrumRequest)
|
||||
} else {
|
||||
Toast.makeText(activity!!, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
|
||||
srl!!.isRefreshing = false
|
||||
|
|
@ -871,7 +888,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
private fun requestInfura(method: String, contract: String) {
|
||||
if (UtilHelper.isOnline(activity)) {
|
||||
requestCounter++
|
||||
serverApiHelper.infura(method, 67, card!!.wallet, contract, "")
|
||||
serverApiHelper.infura(method, 67, ctx.card!!.wallet, contract, "")
|
||||
} else {
|
||||
Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
|
||||
srl!!.isRefreshing = false
|
||||
|
|
@ -880,8 +897,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
private fun requestVerifyAndGetInfo() {
|
||||
if (UtilHelper.isOnline(activity)) {
|
||||
if ((card!!.isOnlineVerified == null || !card!!.isOnlineVerified)) {
|
||||
serverApiHelper.cardVerifyAndGetInfo(card)
|
||||
if ((ctx.card!!.isOnlineVerified == null || !ctx.card!!.isOnlineVerified)) {
|
||||
serverApiHelper.cardVerifyAndGetInfo(ctx.card)
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show()
|
||||
|
|
@ -911,7 +928,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
|
||||
val uid = tag!!.id
|
||||
val sUID = Util.byteArrayToHexString(uid)
|
||||
if (card!!.uid != sUID) {
|
||||
if (ctx.card!!.uid != sUID) {
|
||||
// Log.d(TAG, "Invalid UID: $sUID")
|
||||
nfcManager!!.ignoreTag(isoDep.tag)
|
||||
return
|
||||
|
|
@ -925,7 +942,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
isoDep.timeout = 65000
|
||||
}
|
||||
|
||||
verifyCardTask = VerifyCardTask(activity, card, nfcManager, isoDep, this)
|
||||
verifyCardTask = VerifyCardTask(activity, ctx.card, nfcManager, isoDep, this)
|
||||
verifyCardTask!!.start()
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -935,7 +952,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
private fun doShareWallet(useURI: Boolean) {
|
||||
if (useURI) {
|
||||
val txtShare = CoinEngineFactory.create(card!!.blockchain)!!.getShareWalletUri(card).toString()
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
val txtShare = engine!!.shareWalletUri.toString()
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, "Wallet address")
|
||||
|
|
@ -959,7 +977,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
Toast.makeText(activity, R.string.copied_clipboard, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
val txtShare = card!!.wallet
|
||||
val txtShare = ctx.card!!.wallet
|
||||
val clipboard = activity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.primaryClip = ClipData.newPlainText(txtShare, txtShare)
|
||||
Toast.makeText(activity, R.string.copied_clipboard, Toast.LENGTH_LONG).show()
|
||||
|
|
@ -968,8 +986,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
|||
|
||||
private fun startSwapPINActivity() {
|
||||
val intent = Intent(activity, PinSwapActivity::class.java)
|
||||
intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid)
|
||||
// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle)
|
||||
intent.putExtra("newPIN", newPIN)
|
||||
intent.putExtra("newPIN2", newPIN2)
|
||||
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,7 @@ import android.view.ViewGroup
|
|||
import android.widget.PopupMenu
|
||||
import android.widget.Toast
|
||||
import com.tangem.domain.cardReader.NfcManager
|
||||
import com.tangem.domain.wallet.Blockchain
|
||||
import com.tangem.domain.wallet.CoinEngineFactory
|
||||
import com.tangem.domain.wallet.PINStorage
|
||||
import com.tangem.domain.wallet.TangemCard
|
||||
import com.tangem.domain.wallet.*
|
||||
import com.tangem.presentation.activity.CreateNewWalletActivity
|
||||
import com.tangem.presentation.activity.PurgeActivity
|
||||
import com.tangem.presentation.activity.PinRequestActivity
|
||||
|
|
@ -45,7 +42,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
|
||||
private var nfcManager: NfcManager? = null
|
||||
private var card: TangemCard? = null
|
||||
private lateinit var ctx: TangemContext
|
||||
|
||||
private var requestPIN2Count = 0
|
||||
private var timerHideErrorAndMessage: Timer? = null
|
||||
|
|
@ -56,8 +53,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
super.onCreate(savedInstanceState)
|
||||
nfcManager = NfcManager(activity, this)
|
||||
|
||||
card = TangemCard(activity!!.intent.getStringExtra("UID"))
|
||||
card!!.loadFromBundle(activity!!.intent.extras!!.getBundle("Card"))
|
||||
ctx = TangemContext.loadFromBundle(activity, activity!!.intent.extras)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
|
|
@ -105,8 +101,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (data.extras!!.containsKey("confirmPIN")) {
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
newPIN = data.getStringExtra("newPIN")
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
} else {
|
||||
|
|
@ -122,8 +117,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (data.extras!!.containsKey("confirmPIN2")) {
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
newPIN2 = data.getStringExtra("newPIN2")
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
} else {
|
||||
|
|
@ -135,7 +129,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
}
|
||||
}
|
||||
REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (newPIN == "") newPIN = card!!.pin
|
||||
if (newPIN == "") newPIN = ctx.card!!.pin
|
||||
|
||||
if (newPIN2 == "") newPIN2 = PINStorage.getPIN2()
|
||||
|
||||
|
|
@ -153,8 +147,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
data = Intent()
|
||||
data.putExtra("UID", card!!.uid)
|
||||
data.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(data.extras)
|
||||
data.putExtra("modification", "delete")
|
||||
} else
|
||||
data.putExtra("modification", "update")
|
||||
|
|
@ -164,34 +157,31 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
|
||||
val updatedCard = TangemCard(data.getStringExtra("UID"))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra("Card"))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
return
|
||||
} else {
|
||||
if (data != null && data.extras!!.containsKey("message")) {
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.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", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
startActivityForResult(intent, REQUEST_CODE_PURGE)
|
||||
}
|
||||
REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) {
|
||||
data = Intent()
|
||||
|
||||
data.putExtra("UID", card!!.uid)
|
||||
data.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(data.extras)
|
||||
data.putExtra("modification", "delete")
|
||||
} else {
|
||||
data.putExtra("modification", "update")
|
||||
|
|
@ -202,19 +192,18 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (data != null && data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
|
||||
val updatedCard = TangemCard(data.getStringExtra("UID"))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra("Card"))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
|
||||
requestPIN2Count++
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
|
||||
return
|
||||
} else {
|
||||
if (data != null && data.extras!!.containsKey("message")) {
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.error = data.getStringExtra("message")
|
||||
}
|
||||
}
|
||||
updateViews()
|
||||
|
|
@ -222,7 +211,8 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
REQUEST_CODE_SEND_PAYMENT -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
srlVerifyCard.isRefreshing = true
|
||||
card!!.clearInfo()
|
||||
ctx.coinData!!.clearInfo()
|
||||
ctx.card!!.switchToInitialBlockchain()
|
||||
updateViews()
|
||||
}
|
||||
|
||||
|
|
@ -230,13 +220,13 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
if (data.extras!!.containsKey("UID") && data.extras!!.containsKey("Card")) {
|
||||
val updatedCard = TangemCard(data.getStringExtra("UID"))
|
||||
updatedCard.loadFromBundle(data.getBundleExtra("Card"))
|
||||
card = updatedCard
|
||||
ctx.card = updatedCard
|
||||
}
|
||||
if (data.extras!!.containsKey("message")) {
|
||||
if (resultCode == Activity.RESULT_OK)
|
||||
card!!.message = data.getStringExtra("message")
|
||||
ctx.message = data.getStringExtra("message")
|
||||
else
|
||||
card!!.error = data.getStringExtra("message")
|
||||
ctx.error = data.getStringExtra("message")
|
||||
}
|
||||
updateViews()
|
||||
}
|
||||
|
|
@ -259,26 +249,26 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
timerHideErrorAndMessage!!.cancel()
|
||||
timerHideErrorAndMessage = null
|
||||
}
|
||||
tvCardID.text = card!!.cidDescription
|
||||
tvCardID.text = ctx.card!!.cidDescription
|
||||
|
||||
if (card!!.error == null || card!!.error.isEmpty()) {
|
||||
if (ctx.error == null || ctx.error.isEmpty()) {
|
||||
tvError.visibility = View.GONE
|
||||
tvError.text = ""
|
||||
} else {
|
||||
tvError.visibility = View.VISIBLE
|
||||
tvError.text = card!!.error
|
||||
tvError.text = ctx.error
|
||||
}
|
||||
if (card!!.message == null || card!!.message.isEmpty()) {
|
||||
if (ctx.message == null || ctx.message.isEmpty()) {
|
||||
tvMessage.visibility = View.GONE
|
||||
tvMessage.text = ""
|
||||
} else {
|
||||
tvMessage.visibility = View.VISIBLE
|
||||
tvMessage.text = card!!.message
|
||||
tvMessage.text = ctx.message
|
||||
}
|
||||
|
||||
tvManufacturerInfo.text = card!!.manufacturer.officialName
|
||||
tvManufacturerInfo.text = ctx.card!!.manufacturer.officialName
|
||||
|
||||
if (card!!.isManufacturerConfirmed && card!!.isCardPublicKeyValid) {
|
||||
if (ctx.card!!.isManufacturerConfirmed && ctx.card!!.isCardPublicKeyValid) {
|
||||
tvCardIdentity.setText(R.string.attested)
|
||||
tvCardIdentity.setTextColor(ContextCompat.getColor(context!!, R.color.confirmed))
|
||||
|
||||
|
|
@ -287,18 +277,17 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
tvCardIdentity.setTextColor(ContextCompat.getColor(context!!, R.color.not_confirmed))
|
||||
}
|
||||
|
||||
tvIssuer.text = card!!.issuerDescription
|
||||
tvCardRegistredDate.text = card!!.personalizationDateTimeDescription
|
||||
//tvBlockchain.text = card!!.blockchainName
|
||||
if (card!!.tokenSymbol.length > 1) {
|
||||
val html = Html.fromHtml(card!!.blockchainName)
|
||||
tvIssuer.text = ctx.card!!.issuerDescription
|
||||
tvCardRegistredDate.text = ctx.card!!.personalizationDateTimeDescription
|
||||
val html = Html.fromHtml(ctx.card!!.blockchainName)
|
||||
tvBlockchain.text = html
|
||||
} else
|
||||
tvBlockchain.text = card!!.blockchainName
|
||||
|
||||
tvValidationNode.text = card!!.validationNodeDescription
|
||||
tvValidationNode.text = ctx.coinData!!.validationNodeDescription
|
||||
|
||||
if (card!!.blockchain == Blockchain.Bitcoin || card!!.blockchain == Blockchain.BitcoinTestNet || card!!.blockchain == Blockchain.BitcoinCash || card!!.blockchain == Blockchain.BitcoinCashTestNet) {
|
||||
val engine = CoinEngineFactory.create(ctx)
|
||||
|
||||
tvInputs.text = engine.unspentInputsDescription
|
||||
if (.blockchain == Blockchain.Bitcoin || card!!.blockchain == Blockchain.BitcoinTestNet || card!!.blockchain == Blockchain.BitcoinCash || card!!.blockchain == Blockchain.BitcoinCashTestNet) {
|
||||
var gatheredUnspents = 0
|
||||
for (i in 0 until card!!.unspentTransactions.size) {
|
||||
if (card!!.unspentTransactions[i].Raw.length > 1) gatheredUnspents++
|
||||
|
|
@ -308,70 +297,70 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
else
|
||||
tvInputs.text = ""
|
||||
|
||||
ivBlockchain.setImageResource(card!!.blockchain.getLogoImageResource(card!!.blockchainID, card!!.tokenSymbol))
|
||||
ivBlockchain.setImageResource(Blockchain.getLogoImageResource(ctx.card!!.blockchainID, ctx.card!!.tokenSymbol))
|
||||
|
||||
if (card!!.isReusable!!)
|
||||
if (ctx.card!!.isReusable!!)
|
||||
tvReusable.setText(R.string.reusable)
|
||||
else
|
||||
tvReusable.setText(R.string.one_off_banknote)
|
||||
|
||||
tvSigningMethod.text = card!!.signingMethod.description
|
||||
tvSigningMethod.text = ctx.card!!.signingMethod.description
|
||||
|
||||
if (card!!.status == TangemCard.Status.Loaded || card!!.status == TangemCard.Status.Purged) {
|
||||
if (ctx.card!!.status == TangemCard.Status.Loaded || ctx.card!!.status == TangemCard.Status.Purged) {
|
||||
|
||||
when {
|
||||
card!!.remainingSignatures == 0 -> {
|
||||
ctx.card!!.remainingSignatures == 0 -> {
|
||||
tvRemainingSignatures.setTextColor(ContextCompat.getColor(context!!, R.color.not_confirmed))
|
||||
tvRemainingSignatures.setText(R.string.none)
|
||||
}
|
||||
card!!.remainingSignatures == 1 -> {
|
||||
ctx.card!!.remainingSignatures == 1 -> {
|
||||
tvRemainingSignatures.setTextColor(ContextCompat.getColor(context!!, R.color.not_confirmed))
|
||||
tvRemainingSignatures.setText(R.string.last_one)
|
||||
}
|
||||
card!!.remainingSignatures > 1000 -> {
|
||||
ctx.card!!.remainingSignatures > 1000 -> {
|
||||
tvRemainingSignatures.setTextColor(ContextCompat.getColor(context!!, R.color.confirmed))
|
||||
tvRemainingSignatures.setText(R.string.unlimited)
|
||||
}
|
||||
else -> {
|
||||
tvRemainingSignatures.setTextColor(ContextCompat.getColor(context!!, R.color.confirmed))
|
||||
tvRemainingSignatures.text = card!!.remainingSignatures.toString()
|
||||
tvRemainingSignatures.text = ctx.card!!.remainingSignatures.toString()
|
||||
}
|
||||
}
|
||||
tvSignedTx.text = (card!!.maxSignatures - card!!.remainingSignatures).toString()
|
||||
tvSignedTx.text = (ctx.card!!.maxSignatures - ctx.card!!.remainingSignatures).toString()
|
||||
} else {
|
||||
tvLastSigned.text = ""
|
||||
tvRemainingSignatures.text = ""
|
||||
tvSignedTx.text = ""
|
||||
}
|
||||
|
||||
tvFirmware.text = card!!.firmwareVersion
|
||||
tvFirmware.text = ctx.card!!.firmwareVersion
|
||||
|
||||
var features = ""
|
||||
|
||||
features += if (card!!.allowSwapPIN()!! && card!!.allowSwapPIN2()!!) {
|
||||
features += if (ctx.card!!.allowSwapPIN()!! && ctx.card!!.allowSwapPIN2()!!) {
|
||||
"Allows change PIN1 and PIN2\n"
|
||||
} else if (card!!.allowSwapPIN()!!) {
|
||||
} else if (ctx.card!!.allowSwapPIN()!!) {
|
||||
"Allows change PIN1\n"
|
||||
} else if (card!!.allowSwapPIN2()!!) {
|
||||
} else if (ctx.card!!.allowSwapPIN2()!!) {
|
||||
"Allows change PIN2\n"
|
||||
} else {
|
||||
"Fixed PIN1 and PIN2\n"
|
||||
}
|
||||
|
||||
if (card!!.needCVC()!!)
|
||||
if (ctx.card!!.needCVC()!!)
|
||||
features += "Requires CVC\n"
|
||||
|
||||
|
||||
if (card!!.supportDynamicNDEF()!!) {
|
||||
if (ctx.card!!.supportDynamicNDEF()!!) {
|
||||
features += "Dynamic NDEF for iOS\n"
|
||||
} else if (card!!.supportNDEF()!!)
|
||||
} else if (ctx.card!!.supportNDEF()!!)
|
||||
features += "NDEF\n"
|
||||
|
||||
if (card!!.supportBlock()!!)
|
||||
if (ctx.card!!.supportBlock()!!)
|
||||
features += "Blockable\n"
|
||||
|
||||
|
||||
if (card!!.supportOnlyOneCommandAtTime()!!)
|
||||
if (ctx.card!!.supportOnlyOneCommandAtTime()!!)
|
||||
features += "Atomic command mode"
|
||||
|
||||
if (features.endsWith("\n"))
|
||||
|
|
@ -379,7 +368,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
|
||||
tvFeatures.text = features
|
||||
|
||||
if (card!!.useDefaultPIN1()!!) {
|
||||
if (ctx.card!!.useDefaultPIN1()!!) {
|
||||
imgPIN.setImageResource(R.drawable.unlock_pin1)
|
||||
imgPIN.setOnClickListener { Toast.makeText(context, R.string.this_banknote_protected_default_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
@ -387,10 +376,10 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
imgPIN.setOnClickListener { Toast.makeText(context, R.string.this_banknote_protected_user_PIN1_code, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
if (card!!.pauseBeforePIN2 > 0 && (card!!.useDefaultPIN2()!! || !card!!.useSmartSecurityDelay())) {
|
||||
if (ctx.card!!.pauseBeforePIN2 > 0 && (ctx.card!!.useDefaultPIN2()!! || !ctx.card!!.useSmartSecurityDelay())) {
|
||||
imgPIN2orSecurityDelay.setImageResource(R.drawable.timer)
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, String.format(getString(R.string.this_banknote_will_enforce), card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
|
||||
} else if (card!!.useDefaultPIN2()!!) {
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, String.format(getString(R.string.this_banknote_will_enforce), ctx.card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() }
|
||||
} else if (ctx.card!!.useDefaultPIN2()!!) {
|
||||
imgPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2)
|
||||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.this_banknote_protected_default_PIN2_code, Toast.LENGTH_LONG).show() }
|
||||
} else {
|
||||
|
|
@ -398,16 +387,16 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.this_banknote_protected_user_PIN2_code, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
if (card!!.useDevelopersFirmware()!!) {
|
||||
if (ctx.card!!.useDevelopersFirmware()!!) {
|
||||
imgDeveloperVersion.setImageResource(R.drawable.ic_developer_version)
|
||||
imgDeveloperVersion.visibility = View.VISIBLE
|
||||
imgDeveloperVersion.setOnClickListener { Toast.makeText(context, R.string.unlocked_banknote_only_development_use, Toast.LENGTH_LONG).show() }
|
||||
} else
|
||||
imgDeveloperVersion.visibility = View.INVISIBLE
|
||||
|
||||
if (card!!.status == TangemCard.Status.Loaded) {
|
||||
tvWallet.text = card!!.shortWalletString
|
||||
if (card!!.isWalletPublicKeyValid) {
|
||||
if (ctx.card!!.status == TangemCard.Status.Loaded) {
|
||||
tvWallet.text = ctx.card!!.shortWalletString
|
||||
if (ctx.card!!.isWalletPublicKeyValid) {
|
||||
tvWalletIdentity.setText(R.string.possession_proved)
|
||||
tvWalletIdentity.setTextColor(ContextCompat.getColor(context!!, R.color.confirmed))
|
||||
} else {
|
||||
|
|
@ -450,8 +439,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
requestPIN2Count = 0
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
newPIN = PINStorage.getDefaultPIN()
|
||||
newPIN2 = ""
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
|
|
@ -461,8 +449,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
requestPIN2Count = 0
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
newPIN = ""
|
||||
newPIN2 = PINStorage.getDefaultPIN2()
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
|
|
@ -472,8 +459,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
requestPIN2Count = 0
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
newPIN = PINStorage.getDefaultPIN()
|
||||
newPIN2 = PINStorage.getDefaultPIN2()
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN)
|
||||
|
|
@ -490,25 +476,23 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
|
||||
private fun doPurge() {
|
||||
requestPIN2Count = 0
|
||||
val engine = CoinEngineFactory.create(card!!.blockchain)
|
||||
if (!card!!.hasBalanceInfo()) {
|
||||
val engine=CoinEngineFactory.create(ctx)
|
||||
if (!engine.hasBalanceInfo()) {
|
||||
return
|
||||
} else if (engine != null && engine.isBalanceNotZero(card)) {
|
||||
} else if (engine.isBalanceNotZero) {
|
||||
Toast.makeText(context, R.string.cannot_erase_wallet_with_non_zero_balance, Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
|
||||
val intent = Intent(context, PinRequestActivity::class.java)
|
||||
intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString())
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE)
|
||||
}
|
||||
|
||||
private fun startSwapPINActivity() {
|
||||
val intent = Intent(context, PinSwapActivity::class.java)
|
||||
intent.putExtra("UID", card!!.uid)
|
||||
intent.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(intent.extras)
|
||||
intent.putExtra("newPIN", newPIN)
|
||||
intent.putExtra("newPIN2", newPIN2)
|
||||
startActivityForResult(intent, REQUEST_CODE_SWAP_PIN)
|
||||
|
|
@ -516,8 +500,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
|
||||
fun prepareResultIntent(): Intent {
|
||||
val data = Intent()
|
||||
data.putExtra("UID", card!!.uid)
|
||||
data.putExtra("Card", card!!.asBundle)
|
||||
ctx.saveToBundle(data.extras)
|
||||
return data
|
||||
}
|
||||
|
||||
|
|
@ -526,12 +509,12 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback {
|
|||
val inflater = popup.menuInflater
|
||||
inflater.inflate(R.menu.menu_loaded_wallet, popup.menu)
|
||||
|
||||
popup.menu.findItem(R.id.action_set_PIN1).isVisible = card!!.allowSwapPIN()!!
|
||||
popup.menu.findItem(R.id.action_reset_PIN1).isVisible = card!!.allowSwapPIN()!! && !card!!.useDefaultPIN1()
|
||||
popup.menu.findItem(R.id.action_set_PIN2).isVisible = card!!.allowSwapPIN2()!!
|
||||
popup.menu.findItem(R.id.action_reset_PIN2).isVisible = card!!.allowSwapPIN2()!! && !card!!.useDefaultPIN2()
|
||||
popup.menu.findItem(R.id.action_reset_PINs).isVisible = card!!.allowSwapPIN()!! && card!!.allowSwapPIN2()!! && !card!!.useDefaultPIN1() && !card!!.useDefaultPIN2()
|
||||
if (!card!!.isReusable || card!!.status != TangemCard.Status.Loaded)
|
||||
popup.menu.findItem(R.id.action_set_PIN1).isVisible = ctx.card!!.allowSwapPIN()!!
|
||||
popup.menu.findItem(R.id.action_reset_PIN1).isVisible = ctx.card!!.allowSwapPIN()!! && !ctx.card!!.useDefaultPIN1()
|
||||
popup.menu.findItem(R.id.action_set_PIN2).isVisible = ctx.card!!.allowSwapPIN2()!!
|
||||
popup.menu.findItem(R.id.action_reset_PIN2).isVisible = ctx.card!!.allowSwapPIN2()!! && !ctx.card!!.useDefaultPIN2()
|
||||
popup.menu.findItem(R.id.action_reset_PINs).isVisible = ctx.card!!.allowSwapPIN()!! && ctx.card!!.allowSwapPIN2()!! && !ctx.card!!.useDefaultPIN1() && !ctx.card!!.useDefaultPIN2()
|
||||
if (!ctx.card!!.isReusable || ctx.card!!.status != TangemCard.Status.Loaded)
|
||||
popup.menu.findItem(R.id.action_purge).isVisible = false
|
||||
|
||||
popup.setOnMenuItemClickListener { item ->
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import android.util.Log;
|
|||
import com.tangem.domain.wallet.Base58;
|
||||
import com.tangem.domain.wallet.BitcoinException;
|
||||
import com.tangem.domain.wallet.BitcoinOutputStream;
|
||||
import com.tangem.domain.wallet.TangemCard;
|
||||
import com.tangem.domain.wallet.BtcData;
|
||||
import com.tangem.domain.wallet.Transaction;
|
||||
import com.tangem.domain.wallet.UnspentOutputInfo;
|
||||
|
||||
|
|
@ -325,10 +325,10 @@ public final class BTCUtils {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
public static ArrayList<UnspentOutputInfo> getOutputs(List<TangemCard.UnspentTransaction> rawTxList, byte[] outputScriptWeAreAbleToSpend) throws BitcoinException {
|
||||
public static ArrayList<UnspentOutputInfo> getOutputs(List<BtcData.UnspentTransaction> rawTxList, byte[] outputScriptWeAreAbleToSpend) throws BitcoinException {
|
||||
ArrayList<UnspentOutputInfo> unspentOutputs = new ArrayList<>();
|
||||
|
||||
for(TangemCard.UnspentTransaction current: rawTxList)
|
||||
for(BtcData.UnspentTransaction current: rawTxList)
|
||||
{
|
||||
byte[] rawTxByte = BTCUtils.fromHex(current.Raw);
|
||||
if (rawTxByte == null || current.Raw.isEmpty())
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ public class Util {
|
|||
(byte) value};
|
||||
}
|
||||
|
||||
public static int byteArrayToInt(byte[] byteArray) {
|
||||
public static int byteArrayToInt(byte[] byteArray) throws IllegalArgumentException {
|
||||
if( byteArray.length==1 ) return byteArray[0]&0xFF;
|
||||
java.nio.ByteBuffer BB=java.nio.ByteBuffer.wrap(byteArray);
|
||||
switch (byteArray.length)
|
||||
|
|
@ -417,7 +417,7 @@ public class Util {
|
|||
}
|
||||
}
|
||||
|
||||
public static long byteArrayToLong(byte[] byteArray) {
|
||||
public static long byteArrayToLong(byte[] byteArray) throws IllegalArgumentException {
|
||||
if( byteArray.length==1 ) return byteArray[0]&0xFF;
|
||||
java.nio.ByteBuffer BB=java.nio.ByteBuffer.wrap(byteArray);
|
||||
switch (byteArray.length)
|
||||
|
|
@ -442,7 +442,7 @@ public class Util {
|
|||
(byte) value};
|
||||
}
|
||||
|
||||
public static int byteArrayToInt(byte[] byteArray, int startPos, int length) {
|
||||
public static int byteArrayToInt(byte[] byteArray, int startPos, int length) throws IllegalArgumentException {
|
||||
if (byteArray == null) {
|
||||
throw new IllegalArgumentException("Parameter 'byteArray' cannot be null");
|
||||
}
|
||||
|
|
@ -459,7 +459,7 @@ public class Util {
|
|||
return value;
|
||||
}
|
||||
|
||||
public static long byteArrayToLong(byte[] byteArray, int startPos, int length) {
|
||||
public static long byteArrayToLong(byte[] byteArray, int startPos, int length) throws IllegalArgumentException {
|
||||
if (byteArray == null) {
|
||||
throw new IllegalArgumentException("Parameter 'byteArray' cannot be null");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue