Updated on 2026-08-14

This commit is contained in:
Tangem 2018-10-30 12:25:49 +03:00
parent f2fc3e9886
commit e122ccd0eb
20 changed files with 615 additions and 472 deletions

View file

@ -585,10 +585,16 @@ public class CardProtocol {
mCard.setWalletPublicKey(pkUncompressed);
mCard.setWalletPublicKeyRar(pkCompresses);
TangemContext ctx=new TangemContext(mCard);
CoinEngine engineCoin = CoinEngineFactory.create(ctx);
String wallet = engineCoin.calculateAddress(pkUncompressed);
mCard.setWallet(wallet);
TangemContext ctx = new TangemContext(mCard);
try {
CoinEngine engineCoin = CoinEngineFactory.create(ctx);
if( engineCoin==null ) throw new Exception("Can't create CoinEngine!");
String wallet = engineCoin.calculateAddress(pkUncompressed);
mCard.setWallet(wallet);
} catch (Exception e) {
e.printStackTrace();
throw new TangemException("Can't define wallet address");
}
//mCard.setWallet(Blockchain.calculateWalletAddress(mCard, pkUncompressed));
mCard.setRemainingSignatures(readResult.getTagAsInt(TLV.Tag.TAG_RemainingSignatures));

View file

@ -56,11 +56,7 @@ public class BalanceValidator {
TangemCard card=ctx.getCard();
CoinEngine engine=CoinEngineFactory.create(ctx);
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( !engine.validateBalance(this) ) return;
// Verify card?
if (attest) {

View file

@ -19,13 +19,13 @@ public enum Blockchain {
Blockchain(String ID, String currency, double multiplier, int imageResource, String officialName) {
mID = ID;
mCurrency = currency;
mMultiplier = multiplier;
// mMultiplier = multiplier;
mImageResource = imageResource;
mOfficialName = officialName;
}
private String mID, mOfficialName;
private double mMultiplier;
//private double mMultiplier;
private String mCurrency;
private int mImageResource;
@ -37,9 +37,9 @@ public enum Blockchain {
return mOfficialName;
}
public double getMultiplier() {
return mMultiplier;
}
// public double getMultiplier() {
// return mMultiplier;
// }
public String getCurrency() {
return mCurrency;

View file

@ -13,6 +13,7 @@ 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;
@ -27,15 +28,15 @@ import java.util.List;
public class BtcCashEngine extends CoinEngine {
public BtcData btcData = null;
public BtcData coinData = null;
public BtcCashEngine(TangemContext context) throws Exception {
super(context);
if (context.getCoinData() == null) {
btcData = new BtcData();
context.setCoinData(btcData);
coinData = new BtcData();
context.setCoinData(coinData);
} else if (context.getCoinData() instanceof BtcData) {
btcData = (BtcData) context.getCoinData();
coinData = (BtcData) context.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for BtcEngine");
}
@ -45,21 +46,25 @@ public class BtcCashEngine extends CoinEngine {
}
private static int getDecimals() {
return 8;
}
private void checkBlockchainDataExists() throws Exception {
if (btcData == null) throw new Exception("No blockchain data");
if (coinData == null) throw new Exception("No blockchain data");
}
@Override
public boolean awaitingConfirmation(){
if( btcData==null ) return false;
return btcData.getBalanceUnconfirmed() != 0;
if( coinData ==null ) return false;
return coinData.getBalanceUnconfirmed() != 0;
}
@Override
public String getBalanceHTML() {
if (hasBalanceInfo()) {
Amount balance = convertToAmount(btcData.getBalanceInInternalUnits());
return balance.toString();
Amount balance=getBalance();
if( balance!=null ) {
return balance.toDescriptionString(getDecimals());
} else {
return "";
}
@ -67,7 +72,14 @@ public class BtcCashEngine extends CoinEngine {
@Override
public String getBalanceCurrencyHTML() {
return "mBCH";
return "BTH";
}
@Override
public String getOfflineBalanceHTML() {
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
Amount offlineAmount = convertToAmount(offlineInternalAmount);
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
@ -78,30 +90,21 @@ public class BtcCashEngine extends CoinEngine {
@Override
public boolean isBalanceNotZero() {
if( btcData==null ) return false;
if (btcData.getBalanceInInternalUnits() == null) return false;
return btcData.getBalanceInInternalUnits().notZero();
}
@Override
public boolean checkAmount(Amount amount) throws Exception {
checkBlockchainDataExists();
if (amount.compareTo(convertToAmount(btcData.getBalanceInInternalUnits())) > 0) {
return false;
}
return true;
if( coinData ==null ) return false;
if (coinData.getBalanceInInternalUnits() == null) return false;
return coinData.getBalanceInInternalUnits().notZero();
}
@Override
public boolean hasBalanceInfo(){
if( btcData==null ) return false;
return btcData.hasBalanceInfo();
if( coinData ==null ) return false;
return coinData.hasBalanceInfo();
}
@Override
public boolean checkUnspentTransaction() throws Exception {
checkBlockchainDataExists();
return btcData.getUnspentTransactions().size() != 0;
return coinData.getUnspentTransactions().size() != 0;
}
@Override
@ -173,18 +176,27 @@ public class BtcCashEngine extends CoinEngine {
@Override
public InputFilter[] getAmountInputFilters() {
return new InputFilter[] { new DecimalDigitsInputFilter(8) };
return new InputFilter[] { new DecimalDigitsInputFilter(getDecimals()) };
}
@Override
public boolean checkAmountValue(String amountValue, String feeValue, InternalAmount minFeeInInternalUnits, Boolean isIncludeFee) {
public boolean checkNewTransactionAmount(Amount amount){
if( coinData ==null ) return false;
if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) {
return false;
}
return true;
}
@Override
public boolean checkNewTransactionAmountAndFee(Amount amountValue, Amount feeValue, Boolean isIncludeFee, InternalAmount minFeeInInternalUnits) {
InternalAmount fee;
InternalAmount amount;
try {
checkBlockchainDataExists();
amount = convertToInternalAmount(new Amount(amountValue, ctx.getBlockchain()));
fee = convertToInternalAmount(new Amount(feeValue, ctx.getBlockchain()));
amount = convertToInternalAmount(amountValue);
fee = convertToInternalAmount(feeValue);
} catch (Exception e) {
e.printStackTrace();
return false;
@ -196,10 +208,10 @@ public class BtcCashEngine extends CoinEngine {
if (fee.isZero() || amount.isZero())
return false;
if (isIncludeFee && amount.compareTo(btcData.getBalanceInInternalUnits())>0)
if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits())>0)
return false;
if (!isIncludeFee && amount.add(fee).compareTo(btcData.getBalanceInInternalUnits())>0)
if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits())>0)
return false;
return true;
@ -222,18 +234,18 @@ public class BtcCashEngine extends CoinEngine {
// return;
// }
if (btcData.getBalanceUnconfirmed() != 0) {
if (coinData.getBalanceUnconfirmed() != 0) {
balanceValidator.setScore(0);
balanceValidator.setFirstLine("Transaction in progress");
balanceValidator.setSecondLine("Wait for confirmation in blockchain");
return false;
}
if (btcData.isBalanceReceived() && btcData.isBalanceEqual()) {
if (coinData.isBalanceReceived() && coinData.isBalanceEqual()) {
balanceValidator.setScore(100);
balanceValidator.setFirstLine("Verified balance");
balanceValidator.setSecondLine("Balance confirmed in blockchain");
if (btcData.getBalanceInInternalUnits().isZero()) {
if (coinData.getBalanceInInternalUnits().isZero()) {
balanceValidator.setFirstLine("Empty wallet");
balanceValidator.setSecondLine("");
}
@ -248,7 +260,7 @@ public class BtcCashEngine extends CoinEngine {
// return;
// }
if ((ctx.getCard().getOfflineBalance() != null) && !btcData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && btcData.getBalanceInInternalUnits().notZero() ) {
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.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. ");
@ -274,7 +286,7 @@ public class BtcCashEngine extends CoinEngine {
@Override
public Amount getBalance() {
return convertToAmount(btcData.getBalanceInInternalUnits());
return convertToAmount(coinData.getBalanceInInternalUnits());
}
@Override
@ -284,8 +296,8 @@ public class BtcCashEngine extends CoinEngine {
@Override
public String getBalanceEquivalent() {
if( btcData==null ) return "";
return btcData.getAmountEquivalentDescription(getBalance());
if( coinData ==null || !coinData.getAmountEquivalentDescriptionAvailable() ) return "";
return getBalance().toEquivalentString(coinData.getRate());
}
@Override
@ -325,12 +337,19 @@ public class BtcCashEngine extends CoinEngine {
@Override
public Amount convertToAmount(InternalAmount internalAmount) {
return null;
BigDecimal d=internalAmount.divide(new BigDecimal("100000000"));
return new Amount(d, getBalanceCurrencyHTML());
}
@Override
public Amount convertToAmount(String strAmount, String currency) {
return new Amount(strAmount, currency);
}
@Override
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
return null;
BigDecimal d=amount.multiply(new BigDecimal("100000000"));
return new InternalAmount(d, getBalanceCurrencyHTML());
}
@Override
@ -338,7 +357,7 @@ public class BtcCashEngine extends CoinEngine {
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));
return new InternalAmount(Util.byteArrayToLong(reversed),"Satoshi");
}
@Override
@ -356,7 +375,7 @@ public class BtcCashEngine extends CoinEngine {
@Override
public String getUnspentInputsDescription() {
return btcData.getUnspentInputsDescription();
return coinData.getUnspentInputsDescription();
}
// @Override
@ -372,8 +391,9 @@ public class BtcCashEngine extends CoinEngine {
}
}
public String getAmountEquivalentDescriptor(TangemCard mCard, String value) {
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), btcData.getRate());
public String getAmountEquivalentDescriptor(TangemCard card, String value) {
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), coinData.getRate());
}
@Override
@ -387,7 +407,7 @@ public class BtcCashEngine extends CoinEngine {
String changeAddress = myAddress;
// Build script for our address
List<BtcData.UnspentTransaction> rawTxList = btcData.getUnspentTransactions();
List<BtcData.UnspentTransaction> rawTxList = coinData.getUnspentTransactions();
byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
// Collect unspent
@ -409,7 +429,7 @@ public class BtcCashEngine extends CoinEngine {
}
if (amount + fees > fullAmount) {
throw new CardProtocol.TangemException_WrongAmount(String.format("Balance (%d) < amount (%d) + (%d)", fullAmount, change, amount));
throw new CardProtocol.TangemException_WrongAmount(String.format("Balance (%d) < change (%d) + amount (%d)", fullAmount, change, amount));
}
byte[][] dataForSign = new byte[unspentOutputs.size()][];

View file

@ -101,7 +101,7 @@ public class BtcData extends CoinData {
}
public CoinEngine.InternalAmount getBalanceInInternalUnits() {
return new CoinEngine.InternalAmount(BigDecimal.valueOf(balanceConfirmed).add(BigDecimal.valueOf(balanceUnconfirmed)));
return new CoinEngine.InternalAmount(BigDecimal.valueOf(balanceConfirmed).add(BigDecimal.valueOf(balanceUnconfirmed)),"Satoshi");
}
public Long getBalanceUnconfirmed() {

View file

@ -15,6 +15,7 @@ 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;
@ -25,15 +26,15 @@ import java.util.List;
public class BtcEngine extends CoinEngine {
public BtcData btcData = null;
public BtcData coinData = null;
public BtcEngine(TangemContext context) throws Exception {
super(context);
if (context.getCoinData() == null) {
btcData = new BtcData();
context.setCoinData(btcData);
coinData = new BtcData();
context.setCoinData(coinData);
} else if (context.getCoinData() instanceof BtcData) {
btcData = (BtcData) context.getCoinData();
coinData = (BtcData) context.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for BtcEngine");
}
@ -43,6 +44,10 @@ public class BtcEngine extends CoinEngine {
super();
}
private static int getDecimals() {
return 8;
}
private static String[] getBitcoinServiceHosts() {
return new String[]{
BitcoinNode.n1.getHost(),
@ -96,20 +101,20 @@ public class BtcEngine extends CoinEngine {
static int serviceIndex = 0;
private void checkBlockchainDataExists() throws Exception {
if (btcData == null) throw new Exception("No blockchain data");
if (coinData == null) throw new Exception("No blockchain data");
}
@Override
public boolean awaitingConfirmation(){
if( btcData==null ) return false;
return btcData.getBalanceUnconfirmed() != 0;
if( coinData ==null ) return false;
return coinData.getBalanceUnconfirmed() != 0;
}
@Override
public String getBalanceHTML() {
Amount balance=getBalance();
if( balance!=null ) {
return balance.toString();
return balance.toDescriptionString(getDecimals());
}else{
return "";
}
@ -124,7 +129,7 @@ public class BtcEngine extends CoinEngine {
public String getOfflineBalanceHTML() {
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
Amount offlineAmount = convertToAmount(offlineInternalAmount);
return offlineAmount.toString();
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
@ -134,22 +139,22 @@ public class BtcEngine extends CoinEngine {
@Override
public boolean isBalanceNotZero() {
if( btcData==null ) return false;
if (btcData.getBalanceInInternalUnits() == null) return false;
return btcData.getBalanceInInternalUnits().notZero();
if( coinData ==null ) return false;
if (coinData.getBalanceInInternalUnits() == null) return false;
return coinData.getBalanceInInternalUnits().notZero();
}
@Override
public boolean hasBalanceInfo(){
if( btcData==null ) return false;
return btcData.hasBalanceInfo();
if( coinData ==null ) return false;
return coinData.hasBalanceInfo();
}
@Override
public boolean checkUnspentTransaction() throws Exception {
checkBlockchainDataExists();
return btcData.getUnspentTransactions().size() != 0;
return coinData.getUnspentTransactions().size() != 0;
}
@Override
@ -226,13 +231,13 @@ public class BtcEngine extends CoinEngine {
@Override
public InputFilter[] getAmountInputFilters() {
return new InputFilter[] { new DecimalDigitsInputFilter(8) };
return new InputFilter[] { new DecimalDigitsInputFilter(getDecimals()) };
}
@Override
public boolean checkNewTransactionAmount(Amount amount){
if( btcData==null ) return false;
if (amount.compareTo(convertToAmount(btcData.getBalanceInInternalUnits())) > 0) {
if( coinData ==null ) return false;
if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) {
return false;
}
return true;
@ -258,10 +263,10 @@ public class BtcEngine extends CoinEngine {
if (fee.isZero() || amount.isZero())
return false;
if (isIncludeFee && amount.compareTo(btcData.getBalanceInInternalUnits())>0)
if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits())>0)
return false;
if (!isIncludeFee && amount.add(fee).compareTo(btcData.getBalanceInInternalUnits())>0)
if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits())>0)
return false;
return true;
@ -284,18 +289,18 @@ public class BtcEngine extends CoinEngine {
// return;
// }
if (btcData.getBalanceUnconfirmed() != 0) {
if (coinData.getBalanceUnconfirmed() != 0) {
balanceValidator.setScore(0);
balanceValidator.setFirstLine("Transaction in progress");
balanceValidator.setSecondLine("Wait for confirmation in blockchain");
return false;
}
if (btcData.isBalanceReceived() && btcData.isBalanceEqual()) {
if (coinData.isBalanceReceived() && coinData.isBalanceEqual()) {
balanceValidator.setScore(100);
balanceValidator.setFirstLine("Verified balance");
balanceValidator.setSecondLine("Balance confirmed in blockchain");
if (btcData.getBalanceInInternalUnits().isZero()) {
if (coinData.getBalanceInInternalUnits().isZero()) {
balanceValidator.setFirstLine("Empty wallet");
balanceValidator.setSecondLine("");
}
@ -310,7 +315,7 @@ public class BtcEngine extends CoinEngine {
// return;
// }
if ((ctx.getCard().getOfflineBalance() != null) && !btcData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && btcData.getBalanceInInternalUnits().notZero() ) {
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.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. ");
@ -336,18 +341,21 @@ public class BtcEngine extends CoinEngine {
@Override
public Amount getBalance() {
return convertToAmount(btcData.getBalanceInInternalUnits());
if( !hasBalanceInfo() ) return null;
return convertToAmount(coinData.getBalanceInInternalUnits());
}
@Override
public String evaluateFeeEquivalent(String fee) {
return getAmountEquivalentDescriptor(ctx.getCard(), fee);
if( !coinData.getAmountEquivalentDescriptionAvailable() ) return "";
Amount feeAmount=new Amount(fee, getFeeCurrencyHTML());
return feeAmount.toEquivalentString(coinData.getRate());
}
@Override
public String getBalanceEquivalent() {
if( btcData==null ) return "";
return btcData.getAmountEquivalentDescription(getBalance());
if( coinData ==null || !coinData.getAmountEquivalentDescriptionAvailable() ) return "";
return getBalance().toEquivalentString(coinData.getRate());
}
@Override
@ -386,20 +394,19 @@ public class BtcEngine extends CoinEngine {
@Override
public Amount convertToAmount(InternalAmount internalAmount) {
//TODO
return null;
BigDecimal d=internalAmount.divide(new BigDecimal("100000000"));
return new Amount(d, getBalanceCurrencyHTML());
}
@Override
public Amount convertToAmount(String strAmount) {
//TODO
return null;
public Amount convertToAmount(String strAmount, String currency) {
return new Amount(strAmount, currency);
}
@Override
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
//TODO
return null;
BigDecimal d=amount.multiply(new BigDecimal("100000000"));
return new InternalAmount(d, getBalanceCurrencyHTML());
}
@Override
@ -407,7 +414,7 @@ public class BtcEngine extends CoinEngine {
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));
return new InternalAmount(Util.byteArrayToLong(reversed),"Satoshi");
}
@Override
@ -425,25 +432,7 @@ public class BtcEngine extends CoinEngine {
@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);
} else {
return "";
}
}
public String getAmountEquivalentDescriptor(TangemCard card, String value) {
return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), btcData.getRate());
return coinData.getUnspentInputsDescription();
}
@Override
@ -457,7 +446,7 @@ public class BtcEngine extends CoinEngine {
String changeAddress = myAddress;
// Build script for our address
List<BtcData.UnspentTransaction> rawTxList = btcData.getUnspentTransactions();
List<BtcData.UnspentTransaction> rawTxList = coinData.getUnspentTransactions();
byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes;
// Collect unspent

View file

@ -7,7 +7,7 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;
public class CoinData {
public abstract class CoinData {
public CoinData() {
}
@ -114,14 +114,6 @@ public class CoinData {
// 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;
}

View file

@ -8,8 +8,10 @@ import com.tangem.domain.cardReader.CardProtocol;
import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.DecimalFormat;
/**
* Created by Ilia on 15.02.2018.
@ -21,20 +23,26 @@ public abstract class CoinEngine {
public static final String EXTRA_ENGINE = "CoinEngine";
public static class InternalAmount extends BigDecimal {
private String currency;
public InternalAmount() {
super(0);
currency="";
}
public InternalAmount(String amountString) {
public InternalAmount(String amountString, String currency) {
super(amountString);
this.currency=currency;
}
public InternalAmount(long amount) {
public InternalAmount(long amount, String currency) {
super(amount);
this.currency=currency;
}
public InternalAmount(BigDecimal amount) {
public InternalAmount(BigDecimal amount, String currency) {
super(amount.unscaledValue(), amount.scale());
this.currency=currency;
}
public boolean notZero()
@ -45,38 +53,42 @@ public abstract class CoinEngine {
public boolean isZero() {
return compareTo(BigDecimal.ZERO)==0;
}
public String getCurrency() {
return currency;
}
}
public static class Amount extends BigDecimal {
private Blockchain blockchain;
private String currency;
public Amount() {
super(0);
blockchain = Blockchain.Unknown;
currency="";
}
public Amount(String amountString, Blockchain blockchain) {
public Amount(String amountString, String currency) {
super(amountString);
this.blockchain = blockchain;
this.currency = currency;
}
public Amount(Long amount, Blockchain blockchain) {
public Amount(Long amount, String currency) {
super(amount);
this.blockchain=blockchain;
this.currency = currency;
}
public Amount(BigDecimal amount, Blockchain blockchain) {
public Amount(BigDecimal amount, String currency) {
super(amount.unscaledValue(), amount.scale());
this.blockchain=blockchain;
this.currency = currency;
}
public String getCurrency() {
return blockchain.getCurrency();
return currency;
}
@Override
public String toString() {
return super.toString() + " " + blockchain.getCurrency();
return super.toString() + " " + currency;
}
public boolean notZero()
@ -84,10 +96,27 @@ public abstract class CoinEngine {
return compareTo(BigDecimal.ZERO)>0;
}
public String getStringToEdit() {
public String toDescriptionString(int decimals) {
String pattern = "#0.#######################################"; // If you like 4 zeros
DecimalFormat myFormatter = new DecimalFormat(pattern.substring(0,3+decimals));
return myFormatter.format(this) + " " + currency;
}
public String toEditString() {
return super.toString();
}
public String toEquivalentString(double rateValue) {
if (rateValue > 0) {
BigDecimal biRate = new BigDecimal(rateValue);
BigDecimal exchangeCurs = biRate.multiply(this);
exchangeCurs = exchangeCurs.setScale(2, RoundingMode.DOWN);
return "USD " + exchangeCurs.toString();
} else {
return "";
}
}
public boolean isZero() {
return compareTo(BigDecimal.ZERO)==0;
}
@ -156,8 +185,8 @@ public abstract class CoinEngine {
public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException;
public abstract Amount convertToAmount(InternalAmount internalAmount);
public abstract Amount convertToAmount(String strAmount);
public abstract Amount convertToAmount(InternalAmount internalAmount) throws Exception;
public abstract Amount convertToAmount(String strAmount, String currency);
public abstract InternalAmount convertToInternalAmount(Amount amount) throws Exception;
public abstract InternalAmount convertToInternalAmount(byte[] bytes) throws Exception;

View file

@ -1,5 +1,7 @@
package com.tangem.domain.wallet;
import android.util.Log;
/**
* Created by Ilia on 15.02.2018.
*/
@ -25,16 +27,24 @@ public class CoinEngineFactory {
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;
try {
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;
}
}
catch (Exception e)
{
e.printStackTrace();
Log.e("CoinEngineFactory","Can't create CoinEngine!");
result=null;
}
return result;
}

View file

@ -2,14 +2,10 @@ 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;
public class EthData extends CoinData {
private CoinEngine.InternalAmount balance = null;
private BigInteger countConfirmedTX = null;
private BigInteger countUnconfirmedTX = BigInteger.valueOf(0);
@ -46,48 +42,24 @@ public class EthData extends CoinData
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"));
String currency = B.getString("BalanceCurrency");
balance = new CoinEngine.InternalAmount(B.getString("BalanceDecimal"), currency);
if (B.containsKey("confirmTx"))
countConfirmedTX = new BigInteger(B.getString("confirmTx"), 16);
@ -97,9 +69,10 @@ public class EthData extends CoinData
@Override
public void saveToBundle(Bundle B) {
super.saveToBundle(B);
try {
B.putString("BalanceCurrency", balance.getCurrency());
B.putString("BalanceDecimal", balance.toString());
B.putString("BalanceDecimalAlter", balance.toString());
B.putString("confirmTx", getConfirmedTXCount().toString(16));
B.putString("unconfirmTx", getUnconfirmedTXCount().toString(16));
@ -110,5 +83,4 @@ public class EthData extends CoinData
}
}
}

View file

@ -17,28 +17,25 @@ import java.math.BigInteger;
import java.math.RoundingMode;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.DecimalFormat;
import java.util.Arrays;
import static com.tangem.util.FormatUtil.GetDecimalFormat;
/**
* Created by Ilia on 15.02.2018.
*/
public class EthEngine extends CoinEngine {
public EthData ethData = null;
public EthData coinData = null;
public EthEngine(TangemContext ctx) throws Exception {
super(ctx);
if (ctx.getCoinData() == null) {
ethData = new EthData();
ctx.setCoinData(ethData);
coinData = new EthData();
ctx.setCoinData(coinData);
} else if (ctx.getCoinData() instanceof BtcData) {
ethData = (EthData) ctx.getCoinData();
coinData = (EthData) ctx.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for BtcEngine");
throw new Exception("Invalid type of Blockchain data for EthEngine");
}
}
@ -46,6 +43,9 @@ public class EthEngine extends CoinEngine {
super();
}
private static int getDecimals() {
return 18;
}
@Override
public boolean awaitingConfirmation(){
@ -57,14 +57,14 @@ public class EthEngine extends CoinEngine {
if (!hasBalanceInfo()) {
return null;
}
return convertToAmount(ethData.getBalanceInInternalUnits());
return convertToAmount(coinData.getBalanceInInternalUnits());
}
@Override
public String getBalanceHTML() {
Amount balance=getBalance();
if( balance!=null ) {
return balance.toString();
return balance.toDescriptionString(getDecimals());
}else{
return "";
}
@ -79,22 +79,22 @@ public class EthEngine extends CoinEngine {
public String getOfflineBalanceHTML() {
InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance());
Amount offlineAmount = convertToAmount(offlineInternalAmount);
return offlineAmount.toString();
return offlineAmount.toDescriptionString(getDecimals());
}
@Override
public boolean isBalanceAlterNotZero() {
return true; //TODO ???
// if( ethData==null ) return false;
// if (ethData.getBalanceAlterInInternalUnits() == null) return false;
// return ethData.getBalanceAlterInInternalUnits().notZero();
// if( coinData==null ) return false;
// if (coinData.getBalanceAlterInInternalUnits() == null) return false;
// return coinData.getBalanceAlterInInternalUnits().notZero();
}
@Override
public boolean isBalanceNotZero() {
if( ethData==null ) return false;
if (ethData.getBalanceInInternalUnits() == null) return false;
return ethData.getBalanceInInternalUnits().notZero();
if( coinData ==null ) return false;
if (coinData.getBalanceInInternalUnits() == null) return false;
return coinData.getBalanceInInternalUnits().notZero();
}
@Override
@ -127,7 +127,6 @@ public class EthEngine extends CoinEngine {
@Override
public boolean validateAddress(String address) {
if (address == null || address.isEmpty()) {
return false;
}
@ -144,7 +143,7 @@ public class EthEngine extends CoinEngine {
}
// public String getBalanceValue(TangemCard mCard) {
// String dec = ethData.getBalanceInInternalUnits();
// String dec = coinData.getBalanceInInternalUnits();
// BigDecimal d = convertToEth(dec);
// String s = d.toString();
//
@ -154,19 +153,19 @@ public class EthEngine extends CoinEngine {
// return output;
// }
public static String getAmountEquivalentDescription(Amount amount, double rateValue) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) == 0)
return "";
if (rateValue > 0) {
BigDecimal biRate = new BigDecimal(rateValue);
BigDecimal exchangeCurs = biRate.multiply(amount);
exchangeCurs = exchangeCurs.setScale(2, RoundingMode.DOWN);
return "USD " + exchangeCurs.toString();
} else {
return "";
}
}
// public static String getAmountEquivalentDescription(Amount amount, double rateValue) {
// if (amount == null || amount.compareTo(BigDecimal.ZERO) == 0)
// return "";
//
// if (rateValue > 0) {
// BigDecimal biRate = new BigDecimal(rateValue);
// BigDecimal exchangeCurs = biRate.multiply(amount);
// exchangeCurs = exchangeCurs.setScale(2, RoundingMode.DOWN);
// return "USD " + exchangeCurs.toString();
// } else {
// return "";
// }
// }
// public static String getAmountEquivalentDescriptionETH(Double amount, float rate) {
// if (amount == 0)
@ -183,23 +182,23 @@ public class EthEngine extends CoinEngine {
@Override
public String getBalanceEquivalent() {
return getAmountEquivalentDescription(getBalance(), ethData.getRate());
return getBalance().toEquivalentString(coinData.getRate());
}
@Override
public Amount convertToAmount(InternalAmount internalAmount) {
BigDecimal d = internalAmount.divide(new BigDecimal("1000000000000000000"), 8, RoundingMode.DOWN);
return new Amount(d, ctx.getBlockchain());
BigDecimal d = internalAmount.divide(new BigDecimal("1000000000000000000"), getDecimals(), RoundingMode.DOWN);
return new Amount(d, ctx.getBlockchain().getCurrency());
}
@Override
public Amount convertToAmount(String strAmount) {
return new Amount(strAmount, ctx.getBlockchain());
public Amount convertToAmount(String strAmount, String currency) {
return new Amount(strAmount, currency);
}
@Override
public InternalAmount convertToInternalAmount(Amount amount){
return new InternalAmount(amount.multiply(new BigDecimal("1000000000000000000")));
return new InternalAmount(amount.multiply(new BigDecimal("1000000000000000000")),"wei");
}
@Override
@ -216,7 +215,7 @@ public class EthEngine extends CoinEngine {
@Override
public boolean hasBalanceInfo() {
return ethData.getBalanceInInternalUnits()!=null;
return coinData.getBalanceInInternalUnits()!=null;
}
@Override
@ -243,12 +242,12 @@ public class EthEngine extends CoinEngine {
@Override
public InputFilter[] getAmountInputFilters() {
return new InputFilter[] { new DecimalDigitsInputFilter(18) };
return new InputFilter[] { new DecimalDigitsInputFilter(getDecimals()) };
}
@Override
public boolean checkNewTransactionAmount(Amount amount){
if( ethData==null ) return false;
if( coinData ==null ) return false;
Amount balance=getBalance();
if (balance==null || amount.compareTo(balance) > 0) {
return false;
@ -303,14 +302,14 @@ public class EthEngine extends CoinEngine {
return false;
}
if (!ethData.getUnconfirmedTXCount().equals(ethData.getConfirmedTXCount())) {
if (!coinData.getUnconfirmedTXCount().equals(coinData.getConfirmedTXCount())) {
balanceValidator.setScore(0);
balanceValidator.setFirstLine("Unguaranteed balance");
balanceValidator.setSecondLine("Transaction is in progress. Wait for confirmation in blockchain.");
return false;
}
if (ethData.isBalanceReceived()) {
if (coinData.isBalanceReceived()) {
balanceValidator.setScore(100);
balanceValidator.setFirstLine("Verified balance");
balanceValidator.setSecondLine("Balance confirmed in blockchain");
@ -320,7 +319,7 @@ public class EthEngine extends CoinEngine {
}
}
if ((ctx.getCard().getOfflineBalance() != null) && !ethData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && getBalance().notZero()) {
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && getBalance().notZero()) {
balanceValidator.setScore(80);
balanceValidator.setFirstLine("Verified offline balance");
balanceValidator.setSecondLine("Restore internet connection to obtain trusted balance from blockchain");
@ -332,8 +331,8 @@ public class EthEngine extends CoinEngine {
@Override
public String evaluateFeeEquivalent(String fee) {
Amount feeValue = new Amount(fee, ctx.getBlockchain());
return getAmountEquivalentDescription(feeValue, ethData.getRate());
Amount feeValue = new Amount(fee, ctx.getBlockchain().getCurrency());
return feeValue.toEquivalentString(coinData.getRate());
}
@Override
@ -360,7 +359,7 @@ public class EthEngine extends CoinEngine {
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
BigInteger nonceValue = ethData.getConfirmedTXCount();
BigInteger nonceValue = coinData.getConfirmedTXCount();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
boolean flag = (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = ctx.getCard().getIssuer();

View file

@ -81,10 +81,13 @@ public class TangemContext {
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));
if (tangemContext.getBlockchain() != null) {
if (bundle.containsKey(EXTRA_BLOCKCHAIN_DATA)) {
tangemContext.coinData = CoinData.fromBundle(tangemContext.getBlockchain(), bundle.getBundle(EXTRA_BLOCKCHAIN_DATA));
} else {
tangemContext.coinData = CoinEngineFactory.create(tangemContext).createCoinData();
}
}
tangemContext.error = bundle.getString("Error");
tangemContext.message = bundle.getString("Message");
@ -108,7 +111,7 @@ public class TangemContext {
}
public String getString(int stringId) {
if( context!=null ) return getContext().getResources().getString(stringId);
return "context.resources.string["+stringId+"]";
if (context != null) return getContext().getResources().getString(stringId);
return "context.resources.string[" + stringId + "]";
}
}

View file

@ -0,0 +1,46 @@
package com.tangem.domain.wallet;
import android.os.Bundle;
import android.util.Log;
import java.math.BigDecimal;
import java.math.BigInteger;
public class TokenData extends EthData {
private CoinEngine.InternalAmount balanceAlter = null;
@Override
public void clearInfo() {
super.clearInfo();
balanceAlter = null;
}
public CoinEngine.InternalAmount getBalanceAlterInInternalUnits() {
return balanceAlter;
}
public void setBalanceAlterInInternalUnits(CoinEngine.InternalAmount value) {
balanceAlter = value;
}
@Override
public void loadFromBundle(Bundle B) {
super.loadFromBundle(B);
balanceAlter = new CoinEngine.InternalAmount(B.getString("BalanceDecimalAlter"),"ETH");
}
@Override
public void saveToBundle(Bundle B) {
super.saveToBundle(B);
try {
B.putString("BalanceDecimalAlter", balanceAlter.toString());
} catch (Exception e) {
Log.e("Can't save to bundle ", e.getMessage());
}
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.domain.wallet;
import android.net.Uri;
import android.text.InputFilter;
import android.util.Log;
import com.google.common.base.Strings;
@ -8,6 +9,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.util.DecimalDigitsInputFilter;
import com.tangem.wallet.R;
import org.bitcoinj.core.ECKey;
@ -17,11 +19,7 @@ import java.math.BigInteger;
import java.math.RoundingMode;
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;
/**
* Created by Ilia on 20.03.2018.
@ -29,47 +27,103 @@ import static com.tangem.util.FormatUtil.GetDecimalFormat;
public class TokenEngine extends CoinEngine {
@Override
public String getOfflineBalanceHTML() {
return ctx.getString(R.string.not_implemented);
}
public TokenData coinData = null;
public TokenEngine(TangemContext context) {
super(context);
public TokenEngine(TangemContext ctx) throws Exception {
super(ctx);
if (ctx.getCoinData() == null) {
coinData = new TokenData();
ctx.setCoinData(coinData);
} else if (ctx.getCoinData() instanceof BtcData) {
coinData = (TokenData) ctx.getCoinData();
} else {
throw new Exception("Invalid type of Blockchain data for TokenEngine");
}
}
public TokenEngine() {
super();
}
@Override
public boolean awaitingConfirmation() {
return false;
}
@Override
public Amount getBalance() {
if (!hasBalanceInfo()) {
return null;
}
try {
if (coinData.getBalanceInInternalUnits().notZero()) {
return convertToAmount(coinData.getBalanceInInternalUnits());
} else {
return convertToAmount(coinData.getBalanceAlterInInternalUnits());
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String getBalanceCurrency(TangemCard card) {
String currency = card.getTokenSymbol();
@Override
public String getBalanceHTML() {
if (hasBalanceInfo()) {
try {
return " " + convertToAmount(coinData.getBalanceInInternalUnits()).toDescriptionString(getTokenDecimals()) + " <br><small><small> + " + convertToAmount(coinData.getBalanceAlterInInternalUnits()).toDescriptionString(getEthDecimals()) + " for gas</small></small>";
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
return "";
}
}
@Override
public String getBalanceCurrencyHTML() {
String currency = ctx.getCard().getTokenSymbol();
if (Strings.isNullOrEmpty(currency))
return "NoN";
return currency;
if (hasBalanceInfo()) {
if (coinData.getBalanceInInternalUnits().notZero()) {
return currency;
} else {
return "ETH";
}
} else {
return currency;
}
}
public String getFeeCurrency() {
return "Gwei";
@Override
public InputFilter[] getAmountInputFilters() {
if (!hasBalanceInfo()) return null;
if (coinData.getBalanceInInternalUnits().notZero()) {
return new InputFilter[]{new DecimalDigitsInputFilter(getTokenDecimals())};
} else {
return new InputFilter[]{new DecimalDigitsInputFilter(getEthDecimals())};
}
}
BigDecimal convertToEth(String value) {
BigInteger m = new BigInteger(value, 10);
BigDecimal n = new BigDecimal(m);
BigDecimal d = n.divide(new BigDecimal("1000000000000000000"));
d = d.setScale(8, RoundingMode.DOWN);
return d;
@Override
public String getFeeCurrencyHTML() {
return "ETH";
}
@Override
public String getOfflineBalanceHTML() {
return ctx.getString(R.string.not_implemented);
}
public int getTokenDecimals(TangemCard card) {
return card.getTokensDecimal();
public static int getEthDecimals() {
return 18;
}
public int getTokenDecimals() {
return ctx.getCard().getTokensDecimal();
}
public String getContractAddress(TangemCard card) {
@ -80,7 +134,8 @@ public class TokenEngine extends CoinEngine {
return false;
}
public boolean validateAddress(String address, TangemCard card) {
@Override
public boolean validateAddress(String address) {
if (address == null || address.isEmpty()) {
return false;
}
@ -96,140 +151,40 @@ public class TokenEngine extends CoinEngine {
return true;
}
// public String GetBalanceAlterValue(TangemCard mCard) {
// String dec = mCard.getDecimalBalanceAlter();
// if(dec == null || dec.isEmpty()) return "";
// BigDecimal d = convertToEth(dec);
// String s = d.toString();
//
// String pattern = "#0.##################"; // If you like 4 zeros
// DecimalFormat myFormatter = new DecimalFormat(pattern);
// String output = myFormatter.format(d);
// return output;
// }
//
// public BigDecimal getBalanceAlterValueBigDecimal(TangemCard card) {
// String dec = card.getDecimalBalanceAlter();
// BigDecimal d = convertToEth(dec);
//// String s = d.toString();
//
//// String pattern = "#0.000"; // If you like 4 zeros
//// DecimalFormat myFormatter = new DecimalFormat(pattern);
//// String output = myFormatter.format(d);
// return d;
// }
//
// public String getBalanceValue(TangemCard mCard) {
// if (!hasBalanceInfo(mCard))
// return "";
//
// String dec = mCard.getDecimalBalance();
// BigDecimal d = new BigDecimal(dec);
// BigDecimal p = new BigDecimal(10);
// p = p.pow(getTokenDecimals(mCard));
// BigDecimal l = d.divide(p);
//
// String pattern = "#0.##################"; // If you like 4 zeros
// DecimalFormat myFormatter = new DecimalFormat(pattern);
// String output = myFormatter.format(l);
// return output;
// }
//
// public BigDecimal GetBalanceValueBigDecimal(TangemCard mCard) {
//
// String dec = mCard.getDecimalBalance();
// BigDecimal d = new BigDecimal(dec);
// BigDecimal p = new BigDecimal(10);
// p = p.pow(getTokenDecimals(mCard));
// BigDecimal l = d.divide(p);
//
// return l;
// }
public boolean checkAmount(TangemCard card, String amount) throws Exception {
DecimalFormat decimalFormat = GetDecimalFormat();
BigDecimal amountValue = (BigDecimal) decimalFormat.parse(amount); //new BigDecimal(strAmount);
BigDecimal maxValue = GetBalanceValueBigDecimal(card);
if (amountValue.compareTo(maxValue) > 0) {
return false;
}
return true;
}
public Long getBalanceLong(TangemCard mCard) {
return mCard.getBalance();
}
public boolean isBalanceAlterNotZero(TangemCard card) {
String balance = card.getDecimalBalanceAlter();
if (balance == null || balance == "")
return false;
BigDecimal bi = new BigDecimal(balance);
if (BigDecimal.ZERO.compareTo(bi) == 0)
return false;
return true;
}
public boolean isBalanceNotZero(TangemCard card) {
String balance = card.getDecimalBalance();
if (balance == null || balance == "")
return false;
BigDecimal bi = new BigDecimal(balance);
if (BigDecimal.ZERO.compareTo(bi) == 0)
return false;
return true;
}
public boolean hasBalanceInfo(TangemCard card) {
String balance = card.getDecimalBalance();
if (balance == null || balance == "")
return false;
String balanceEx = card.getDecimalBalanceAlter();
if (balanceEx == null || balanceEx == "")
return false;
return true;
@Override
public boolean isBalanceAlterNotZero() {
if (coinData == null) return false;
if (coinData.getBalanceAlterInInternalUnits() == null) return false;
return coinData.getBalanceAlterInInternalUnits().notZero();
}
@Override
public String getBalanceEquivalent(TangemCard mCard) {
if (!hasBalanceInfo(mCard)) {
public boolean isBalanceNotZero() {
if (coinData == null) return false;
if (coinData.getBalanceInInternalUnits() == null) return false;
return coinData.getBalanceInInternalUnits().notZero();
}
@Override
public String getBalanceEquivalent() {
if (!hasBalanceInfo()) {
return "";
}
try {
if (coinData.getBalanceInInternalUnits().notZero()) {
return convertToAmount(coinData.getBalanceInInternalUnits()).toEquivalentString(coinData.getRate());
} else {
return convertToAmount(coinData.getBalanceAlterInInternalUnits()).toEquivalentString(coinData.getRateAlter());
}
} catch (Exception e) {
e.printStackTrace();
return "";
}
String dec = mCard.getDecimalBalance();
BigDecimal d = convertToEth(dec);
return EthEngine.getAmountEquivalentDescriptionETH(d, mCard.getRate());
}
@Override
public String getBalance(TangemCard mCard) {
if (!hasBalanceInfo(mCard)) {
return "";
}
String output = getBalanceValue(mCard);
String s = output + " " + getBalanceCurrency(mCard);
return s;
}
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>";
} else {
return "";
}
}
public String calculateAddress(TangemCard mCard, byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
public String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException {
Keccak256 kec = new Keccak256();
int lenPk = pkUncompressed.length;
if (lenPk < 2) {
@ -250,64 +205,124 @@ public class TokenEngine extends CoinEngine {
}
@Override
public String convertByteArrayToAmount(TangemCard mCard, byte[] bytes) throws Exception {
public Amount convertToAmount(InternalAmount internalAmount) throws Exception {
if (internalAmount.getCurrency().equals("wei")) {
BigDecimal d = internalAmount.divide(new BigDecimal("1000000000000000000"), getEthDecimals(), RoundingMode.DOWN);
return new Amount(d, "ETH");
} else if (internalAmount.getCurrency().equals(ctx.getCard().getTokenSymbol())) {
BigDecimal p = new BigDecimal(10);
p = p.pow(getTokenDecimals());
BigDecimal d = internalAmount.divide(p);
return new Amount(d, ctx.getCard().getTokenSymbol());
}
throw new Exception(String.format("Can't convert '%s' to '%s'", internalAmount.getCurrency(), ctx.getCard().getTokenSymbol()));
}
@Override
public Amount convertToAmount(String strAmount, String currency) {
return new Amount(strAmount, currency);
}
@Override
public InternalAmount convertToInternalAmount(Amount amount) throws Exception {
if (amount.getCurrency().equals("ETH")) {
BigDecimal d = amount.multiply(new BigDecimal("1000000000000000000"));
return new InternalAmount(d, "wei");
} else if (amount.getCurrency().equals(ctx.getCard().getTokenSymbol())) {
BigDecimal p = new BigDecimal(10);
p = p.pow(getTokenDecimals());
BigDecimal d = amount.multiply(p);
return new InternalAmount(d, ctx.getCard().getTokenSymbol());
}
throw new Exception(String.format("Can't convert '%s' to '%s'", amount.getCurrency(), ctx.getCard().getTokenSymbol()));
}
@Override
public InternalAmount convertToInternalAmount(byte[] bytes) throws Exception {
throw new Exception("Not implemented");
}
@Override
public byte[] convertAmountToByteArray(TangemCard mCard, String amount) throws Exception {
public byte[] convertToByteArray(InternalAmount amount) throws Exception {
throw new Exception("Not implemented");
}
@Override
public String getAmountDescription(TangemCard mCard, String amount) throws Exception {
throw new Exception("Not implemented");
public CoinData createCoinData() {
return new TokenData();
}
@Override
public String getUnspentInputsDescription() {
return "";
}
// @Override
// public String getFeeEquivalentDescriptor(String value) {
// BigDecimal d = new BigDecimal(value);
// return EthEngine.getAmountEquivalentDescription(d, coinData.getRateAlter());
// }
@Override
public boolean hasBalanceInfo() {
return coinData != null && coinData.getBalanceInInternalUnits() != null && coinData.getBalanceAlterInInternalUnits() != null;
}
public String getAmountEquivalentDescriptor(TangemCard mCard, String value) {
BigDecimal d = new BigDecimal(value);
return EthEngine.getAmountEquivalentDescriptionETH(d, mCard.getRate());
@Override
public Uri getShareWalletUriExplorer() {
return Uri.parse("https://etherscan.io/token/" + getContractAddress(ctx.getCard()) + "?a=" + ctx.getCard().getWallet());
}
public String getFeeEquivalentDescriptor(TangemCard card, String value) {
BigDecimal d = new BigDecimal(value);
return EthEngine.getAmountEquivalentDescriptionETH(d, card.getRateAlter());
}
public Uri getShareWalletUriExplorer(TangemCard mCard) {
return Uri.parse("https://etherscan.io/token/" + getContractAddress(mCard) + "?a=" + mCard.getWallet());
}
public Uri getShareWalletUri(TangemCard mCard) {
if (mCard.getDenomination() != null) {
return Uri.parse("ethereum:" + mCard.getWallet());// + "?value=" + mCard.getDenomination() +"e18");
@Override
public Uri getShareWalletUri() {
if (ctx.getCard().getDenomination() != null) {
return Uri.parse("ethereum:" + ctx.getCard().getWallet());// + "?value=" + mCard.getDenomination() +"e18");
} else {
return Uri.parse("ethereum:" + mCard.getWallet());
return Uri.parse("ethereum:" + ctx.getCard().getWallet());
}
}
public boolean checkUnspentTransaction(TangemCard mCard) {
@Override
public boolean checkUnspentTransaction() {
return true;
}
public boolean checkAmountValue(TangemCard card, String amountValue, String feeValue, Long minFeeInInternalUnits, Boolean incfee) {
Long fee;
BigDecimal amount;
@Override
public boolean checkNewTransactionAmount(Amount amount) {
if (!hasBalanceInfo()) return false;
Amount balance;
try {
amount = getBalanceAlterValueBigDecimal(card);//card.internalUnitsFromString(amountValue);
fee = card.internalUnitsFromString(feeValue);
} catch (Exception e) {
if (amount.getCurrency().equals(ctx.getCard().tokenSymbol)) {
balance = convertToAmount(coinData.getBalanceInInternalUnits());
} else if (amount.getCurrency().equals("ETH") && coinData.getBalanceInInternalUnits().isZero()) {
balance = convertToAmount(coinData.getBalanceInInternalUnits());
} else {
return false;
}
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return amount.compareTo(balance) <= 0;
}
if (fee == null || amount == null)
return false;
@Override
public boolean checkNewTransactionAmountAndFee(Amount amount, Amount fee, Boolean isFeeIncluded, InternalAmount minFeeInInternalUnits) {
if (!hasBalanceInfo()) return false;
if (fee == 0 || amount.compareTo(BigDecimal.ZERO) == 0)
return false;
try {
Amount balance = convertToAmount(coinData.getBalanceAlterInInternalUnits());
if (fee == null || amount == null || fee.isZero() || amount.isZero())
return false;
if (amount.getCurrency().equals(ctx.getCard().tokenSymbol)) {
// token transaction
//TODO ???
// BigDecimal tmpFee = new BigDecimal(feeValue);
// BigDecimal tmpAmount = amount;
// tmpAmount = tmpAmount.multiply(new BigDecimal("1000000000"));
@ -315,29 +330,94 @@ public class TokenEngine extends CoinEngine {
// if (tmpFee.compareTo(tmpAmount) > 0)
// return false;
} else if (amount.getCurrency().equals("ETH") && coinData.getBalanceInInternalUnits().isZero()) {
// standart ETH transaction
try {
BigDecimal cardBalance = getBalance();
if (isFeeIncluded && amount.compareTo(cardBalance) > 0)
return false;
if (!isFeeIncluded && amount.add(fee).compareTo(cardBalance) > 0)
return false;
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else
{
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public String evaluateFeeEquivalent(TangemCard mCard, String fee) {
BigDecimal gweFee = new BigDecimal(fee);
gweFee = gweFee.divide(new BigDecimal("1000000000"));
gweFee = gweFee.setScale(18, RoundingMode.DOWN);
return getFeeEquivalentDescriptor(mCard, gweFee.toString());
@Override
public boolean validateBalance(BalanceValidator balanceValidator) {
if (getBalance() == null) {
balanceValidator.setScore(0);
balanceValidator.setFirstLine("Unknown balance");
balanceValidator.setSecondLine("Balance cannot be verified. Swipe down to refresh.");
return false;
}
if (!coinData.getUnconfirmedTXCount().equals(coinData.getConfirmedTXCount())) {
balanceValidator.setScore(0);
balanceValidator.setFirstLine("Unguaranteed balance");
balanceValidator.setSecondLine("Transaction is in progress. Wait for confirmation in blockchain.");
return false;
}
if (coinData.isBalanceReceived()) {
balanceValidator.setScore(100);
balanceValidator.setFirstLine("Verified balance");
balanceValidator.setSecondLine("Balance confirmed in blockchain");
if (getBalance().isZero()) {
balanceValidator.setFirstLine("Empty wallet");
balanceValidator.setSecondLine("");
}
}
if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && getBalance().notZero()) {
balanceValidator.setScore(80);
balanceValidator.setFirstLine("Verified offline balance");
balanceValidator.setSecondLine("Restore internet connection to obtain trusted balance from blockchain");
}
return true;
}
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, TangemCard mCard, CardProtocol protocol) throws Exception {
BigInteger nonceValue = mCard.getConfirmedTXCount();
byte[] pbKey = mCard.getWalletPublicKey();
boolean flag = (mCard.getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = mCard.getIssuer();
@Override
public String evaluateFeeEquivalent(String fee) {
Amount feeValue = new Amount(fee, getFeeCurrencyHTML());
return feeValue.toEquivalentString(coinData.getRate());
//
// BigDecimal gweFee = new BigDecimal(fee);
// gweFee = gweFee.divide(new BigDecimal("1000000000"));
// gweFee = gweFee.setScale(18, RoundingMode.DOWN);
// return getFeeEquivalentDescriptor(mCard, gweFee.toString());
}
@Override
public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception {
BigInteger nonceValue = coinData.getConfirmedTXCount();
byte[] pbKey = ctx.getCard().getWalletPublicKey();
boolean flag = (ctx.getCard().getSigningMethod() == TangemCard.SigningMethod.Sign_Hash_Validated_By_Issuer);
Issuer issuer = ctx.getCard().getIssuer();
BigInteger fee = new BigInteger(feeValue, 10);
BigDecimal amountDecValue = new BigDecimal(amountValue);
int d = getTokenDecimals(mCard);
int d = getTokenDecimals();
BigDecimal amountDec = new BigDecimal("10");
amountDec = amountDec.pow(d);
amountDec = amountDecValue.multiply(amountDec);
@ -366,7 +446,7 @@ public class TokenEngine extends CoinEngine {
to = to.substring(2);
}
String contractAddress = getContractAddress(mCard);
String contractAddress = getContractAddress(ctx.getCard());
if (contractAddress.startsWith("0x") || contractAddress.startsWith("0X")) {
contractAddress = contractAddress.substring(2);

View file

@ -49,7 +49,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
private var maxFee: String? = null
private var normalFee: String? = null
private var isIncludeFee: Boolean = true
private var minFeeInInternalUnits: CoinEngine.InternalAmount? = CoinEngine.InternalAmount(0)
private var minFeeInInternalUnits: CoinEngine.InternalAmount? = CoinEngine.InternalAmount(0, "")
private var requestPIN2Count = 0
private var nodeCheck = false
private var dtVerified: Date? = null
@ -163,8 +163,8 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
return@setOnClickListener
}
val txFee = engineCoin.convertToAmount(etFee.text.toString())
val txAmount = engineCoin.convertToAmount(etAmount.text.toString())
val txFee = engineCoin.convertToAmount(etFee.text.toString(), tvCurrency2.text.toString())
val txAmount = engineCoin.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
if (!engineCoin.hasBalanceInfo()) {
finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_check_balance_no_connection_with_blockchain_nodes))
@ -200,7 +200,10 @@ 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")) / ctx.blockchain.multiplier * 1000000.0 < java.lang.Float.parseFloat(etAmount.text.toString())) {
val engine = CoinEngineFactory.create(ctx)
val balance= engine.convertToAmount(CoinEngine.InternalAmount(electrumRequest.result.getLong("confirmed") + electrumRequest.result.getLong("unconfirmed"), "Satoshi"))
val amount = CoinEngine.Amount(etAmount.text.toString(), ctx.blockchain.currency)
if (balance < amount) {
etFee.error = getString(R.string.not_enough_funds)
} else {
etFee.error = null
@ -232,6 +235,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
ServerApiHelper.INFURA_ETH_GAS_PRICE -> {
var gasPrice = infuraResponse.result
gasPrice = gasPrice.substring(2)
//TODO - remove Gwei
// rounding gas price to integer gwei
val l = BigInteger(gasPrice, 16).divide(BigInteger.valueOf(1000000000L)).multiply(BigInteger.valueOf(1000000000L))
@ -249,7 +253,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
feeRequestSuccess = true
balanceRequestSuccess = true
dtVerified = Date()
minFeeInInternalUnits = CoinEngine.InternalAmount(normalFeeInGwei)
minFeeInInternalUnits = CoinEngine.InternalAmount(normalFeeInGwei,"Gwei")
}
}
}
@ -292,7 +296,8 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
when (blockCount) {
ServerApiHelper.ESTIMATE_FEE_MINIMAL -> {
minFee = strFee
minFeeInInternalUnits = CoinEngine.InternalAmount(strFee)
//TODO - we must know currency of fee
minFeeInInternalUnits = CoinEngine.InternalAmount(strFee, tvCurrency2.text.toString())
}
ServerApiHelper.ESTIMATE_FEE_NORMAL -> {

View file

@ -60,7 +60,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters
// set listeners

View file

@ -60,7 +60,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
tvFeeCurrency.text = tvCurrency.text
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters
etAmount.setOnEditorActionListener { lv, actionId, event ->

View file

@ -66,7 +66,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML)
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toString())
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString())
etAmount.filters=engine.amountInputFilters
etAmount.setOnEditorActionListener { lv, actionId, event ->

View file

@ -9,17 +9,13 @@ 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
import android.view.inputmethod.InputMethodManager
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
import kotlinx.android.synthetic.main.activity_prepare_payment.*
import java.io.IOException
@ -64,7 +60,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
etAmount.isEnabled = false
tvCurrency.text = engine.balance.currency
etAmount.setText(engine.balance.stringToEdit)
etAmount.setText(engine.balance.toEditString())
// limit number of symbols after comma
etAmount.filters = engine.amountInputFilters
@ -85,7 +81,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
val engine1 = CoinEngineFactory.create(ctx.card!!.blockchain)
val strAmount: String = etAmount.text.toString().replace(",", ".")
val amount=engine1.convertToAmount(etAmount.text.toString())
val amount=engine1.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
try {
if (!engine.checkNewTransactionAmount(amount))

View file

@ -203,6 +203,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
btnExtract.setOnClickListener {
val engine=CoinEngineFactory.create(ctx)
if (UtilHelper.isOnline(activity)) {
// TODO - move checks to engine
if (!engine!!.hasBalanceInfo()) {
showSingleToast(R.string.cannot_obtain_data_from_blockchain)
} else if (!engine!!.isBalanceNotZero)
@ -237,7 +238,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
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()
@ -312,15 +312,19 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
var balanceCap = infuraResponse.result
balanceCap = balanceCap.substring(2)
val l = BigInteger(balanceCap, 16)
val d = l.divide(BigInteger("1000000000000000000", 10))
val balance = d.toLong()
// val d = l.divide(BigInteger("1000000000000000000", 10))
// val balance = d.toLong()
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)
// (ctx.coinData!! as EthData).setBalanceConfirmed(balance)
// (ctx.coinData!! as EthData).balanceUnconfirmed = 0L
if (ctx.blockchain != Blockchain.Token) {
(ctx.coinData!! as EthData).isBalanceReceived = true
(ctx.coinData!! as EthData).balanceInInternalUnits = CoinEngine.InternalAmount(l.toBigDecimal(),"wei")
}else{
(ctx.coinData!! as TokenData).isBalanceReceived = true
(ctx.coinData!! as TokenData).balanceInInternalUnits = CoinEngine.InternalAmount(l.toBigDecimal(),ctx.card.tokenSymbol)
(ctx.coinData!! as TokenData).balanceAlterInInternalUnits = CoinEngine.InternalAmount(l.toBigDecimal(), "wei")
}
// Log.i("$TAG eth_get_balance", balanceCap)
}
@ -329,7 +333,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
var nonce = infuraResponse.result
nonce = nonce.substring(2)
val count = BigInteger(nonce, 16)
ctx.coinData!!.confirmedTXCount = count
(ctx.coinData!! as EthData).confirmedTXCount = count
// Log.i("$TAG eth_getTransCount", nonce)
}
@ -338,7 +343,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
var pending = infuraResponse.result
pending = pending.substring(2)
val count = BigInteger(pending, 16)
ctx.coinData!!.unconfirmedTXCount = count
(ctx.coinData!! as EthData).unconfirmedTXCount = count
// Log.i("$TAG eth_getPendingTxCount", pending)
}
@ -353,7 +358,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
ctx.card!!.blockchainID = Blockchain.Ethereum.id
ctx.card!!.addTokenToBlockchainName()
ctx.blockchain=Blockchain.Ethereum
//TODO check
//ctx.blockchain=Blockchain.Ethereum
requestCounter--
if (requestCounter == 0) srl!!.isRefreshing = false
@ -363,9 +369,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
requestInfura(ServerApiHelper.INFURA_ETH_GET_PENDING_COUNT, "")
return
}
ctx.coinData!!.setBalanceConfirmed(balance)
ctx.coinData!!.balanceUnconfirmed = 0L
ctx.coinData!!.decimalBalance = l.toString(10)
(ctx.coinData!! as EthData).balanceInInternalUnits = CoinEngine.InternalAmount(l.toBigDecimal(),ctx.card.tokenSymbol)
// Log.i("$TAG eth_call", balanceCap)
@ -397,9 +401,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
Log.e("$TAG TX_RESULT", hashTX)
val nonce = ctx.coinData!!.confirmedTXCount
val nonce = (ctx.coinData!! as EthData).confirmedTXCount
nonce.add(BigInteger.valueOf(1))
ctx.coinData!!.confirmedTXCount = nonce
(ctx.coinData!! as EthData).confirmedTXCount = nonce
Log.e("$TAG TX_RESULT", hashTX)
@ -649,7 +653,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
REQUEST_CODE_SEND_PAYMENT, REQUEST_CODE_RECEIVE_PAYMENT -> {
if (resultCode == Activity.RESULT_OK) {
ctx.coinData!!.clearInfo()
ctx.card.clearInfo();
srl!!.postDelayed({ this.refresh() }, 5000)
srl!!.isRefreshing = true
updateViews()
@ -779,7 +782,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
tvBalanceEquivalent.text = ""
} else {
val validator = BalanceValidator()
validator.Check(ctx.card, false)
validator.Check(ctx, false)
tvBalanceLine1.setTextColor(ContextCompat.getColor(activity, validator.color))
tvBalanceLine1.text = validator.firstLine
tvBalanceLine2.text = validator.getSecondLine(false)
@ -828,8 +831,6 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
// clear all card data and request again
srl!!.isRefreshing = true
ctx.coinData.clearInfo();
ctx.card!!.clearInfo()
//engine=engine!!.swithToBaseEngine()
ctx.error = null
ctx.message = null
requestCounter = 0
@ -917,8 +918,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private fun openVerifyCard(cardProtocol: CardProtocol) {
val intent = Intent(activity, VerifyCardActivity::class.java)
intent.putExtra(TangemCard.EXTRA_UID, cardProtocol.card.uid)
intent.putExtra(TangemCard.EXTRA_CARD, cardProtocol.card.asBundle)
ctx.saveToBundle(intent.extras)
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD)
}