diff --git a/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java b/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java index 72fe570e28..00e1b86583 100644 --- a/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java +++ b/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java @@ -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)); diff --git a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java index 8f4cc60699..d555f5b165 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java +++ b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java @@ -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) { diff --git a/app/src/main/java/com/tangem/domain/wallet/Blockchain.java b/app/src/main/java/com/tangem/domain/wallet/Blockchain.java index 112a0ec6c1..5e52880c0c 100644 --- a/app/src/main/java/com/tangem/domain/wallet/Blockchain.java +++ b/app/src/main/java/com/tangem/domain/wallet/Blockchain.java @@ -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; diff --git a/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java b/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java index 60dd904a3c..aadf36dfc5 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java @@ -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 rawTxList = btcData.getUnspentTransactions(); + List 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()][]; diff --git a/app/src/main/java/com/tangem/domain/wallet/BtcData.java b/app/src/main/java/com/tangem/domain/wallet/BtcData.java index 80ab1db1c3..acb6f43f5c 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcData.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcData.java @@ -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() { diff --git a/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java b/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java index 8b5e8c0d42..a15b1a18fb 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java @@ -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 rawTxList = btcData.getUnspentTransactions(); + List rawTxList = coinData.getUnspentTransactions(); byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes; // Collect unspent diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinData.java b/app/src/main/java/com/tangem/domain/wallet/CoinData.java index c23e6fb16f..b11ccb2108 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinData.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinData.java @@ -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; } diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java index 018b459744..b5077bcc9b 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java @@ -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; diff --git a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.java b/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.java index 18d87dbd2a..35bbe4a891 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngineFactory.java @@ -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; } diff --git a/app/src/main/java/com/tangem/domain/wallet/EthData.java b/app/src/main/java/com/tangem/domain/wallet/EthData.java index ea3b052066..d81539bab5 100644 --- a/app/src/main/java/com/tangem/domain/wallet/EthData.java +++ b/app/src/main/java/com/tangem/domain/wallet/EthData.java @@ -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 } - -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/wallet/EthEngine.java b/app/src/main/java/com/tangem/domain/wallet/EthEngine.java index 081444831e..320b0f1da7 100644 --- a/app/src/main/java/com/tangem/domain/wallet/EthEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/EthEngine.java @@ -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(); diff --git a/app/src/main/java/com/tangem/domain/wallet/TangemContext.java b/app/src/main/java/com/tangem/domain/wallet/TangemContext.java index b9b070ceb6..7101f43269 100644 --- a/app/src/main/java/com/tangem/domain/wallet/TangemContext.java +++ b/app/src/main/java/com/tangem/domain/wallet/TangemContext.java @@ -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 + "]"; } } diff --git a/app/src/main/java/com/tangem/domain/wallet/TokenData.java b/app/src/main/java/com/tangem/domain/wallet/TokenData.java new file mode 100644 index 0000000000..1a8b1ed9ea --- /dev/null +++ b/app/src/main/java/com/tangem/domain/wallet/TokenData.java @@ -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()); + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java b/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java index f97cb30e5e..38e46687b0 100644 --- a/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java @@ -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()) + "
+ " + convertToAmount(coinData.getBalanceAlterInInternalUnits()).toDescriptionString(getEthDecimals()) + " for gas"; + } 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) + "
+ " + GetBalanceAlterValue(mCard) + " ETH for gas"; - } 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); diff --git a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt index 32581170ec..bfe1683911 100644 --- a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt @@ -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 -> { diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt index ff58b3a8ee..6224d019e9 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt @@ -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 diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt index bf8201f324..9ffc2e0309 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt @@ -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 -> diff --git a/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt b/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt index 329489ba25..1db5e89d67 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt @@ -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 -> diff --git a/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt b/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt index 8ebddcfd2b..aa27f270dc 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt @@ -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)) diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt index 1395b7f021..b66ccb23e2 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -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) }