diff --git a/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java b/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java index e6e62646fd..d49e3fabb2 100644 --- a/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java +++ b/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java @@ -21,11 +21,11 @@ import java.io.IOException; public class SignPaymentTask extends Thread { public static final String TAG = SignPaymentTask.class.getSimpleName(); - private String txAmount = ""; - private String txFee = ""; + private CoinEngine.Amount txAmount; + private CoinEngine.Amount txFee; private Boolean txIncFee = true; - public void SetTransactionValue(String amount, String fee, Boolean incfee) { + public void SetTransactionValue(CoinEngine.Amount amount, CoinEngine.Amount fee, Boolean incfee) { txAmount = amount; txFee = fee; txIncFee = incfee; @@ -39,7 +39,7 @@ public class SignPaymentTask extends Thread { private CardProtocol.Notifications mNotifications; private boolean isCancelled = false; - public SignPaymentTask(Activity context, TangemContext ctx, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, String amount, String fee, Boolean IncFee, String outAddress) { + public SignPaymentTask(Activity context, TangemContext ctx, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications, CoinEngine.Amount amount, CoinEngine.Amount fee, Boolean IncFee, String outAddress) { mCtx=ctx; mContext = context; mNfcManager = nfcManager; @@ -87,7 +87,7 @@ public class SignPaymentTask extends Thread { // SignBTC_TX(protocol); // } - CoinEngine engine = CoinEngineFactory.create(mCtx.getCard().getBlockchain()); + CoinEngine engine = CoinEngineFactory.create(mCtx); if (engine != null) { if (mCtx.getCard().getPauseBeforePIN2() > 0) { mNotifications.onReadWait(mCtx.getCard().getPauseBeforePIN2()); @@ -112,7 +112,7 @@ public class SignPaymentTask extends Thread { } Intent intent = new Intent(mContext, SendTransactionActivity.class); - mCtx.saveToBundle(intent.getExtras()); + mCtx.saveToIntent(intent); intent.putExtra(SendTransactionActivity.EXTRA_TX, txStr); mContext.startActivityForResult(intent, SignPaymentActivity.REQUEST_CODE_SEND_PAYMENT); } 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 aadf36dfc5..cb75f071e0 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcCashEngine.java @@ -11,6 +11,7 @@ import com.tangem.util.DecimalDigitsInputFilter; import com.tangem.util.DerEncodingUtil; import com.tangem.util.FormatUtil; import com.tangem.util.Util; +import com.tangem.wallet.R; import java.io.ByteArrayOutputStream; import java.math.BigDecimal; @@ -55,15 +56,15 @@ public class BtcCashEngine extends CoinEngine { } @Override - public boolean awaitingConfirmation(){ - if( coinData ==null ) return false; + public boolean awaitingConfirmation() { + if (coinData == null) return false; return coinData.getBalanceUnconfirmed() != 0; } @Override public String getBalanceHTML() { - Amount balance=getBalance(); - if( balance!=null ) { + Amount balance = getBalance(); + if (balance != null) { return balance.toDescriptionString(getDecimals()); } else { return ""; @@ -71,44 +72,48 @@ public class BtcCashEngine extends CoinEngine { } @Override - public String getBalanceCurrencyHTML() { + public String getBalanceCurrency() { return "BTH"; } @Override public String getOfflineBalanceHTML() { - InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance()); - Amount offlineAmount = convertToAmount(offlineInternalAmount); - return offlineAmount.toDescriptionString(getDecimals()); + InternalAmount offlineInternalAmount = convertToInternalAmount(ctx.getCard().getOfflineBalance()); + Amount offlineAmount = convertToAmount(offlineInternalAmount); + return offlineAmount.toDescriptionString(getDecimals()); } - @Override - public boolean isBalanceAlterNotZero() { - return true; - } - - @Override public boolean isBalanceNotZero() { - if( coinData ==null ) return false; + if (coinData == null) return false; if (coinData.getBalanceInInternalUnits() == null) return false; return coinData.getBalanceInInternalUnits().notZero(); } @Override - public boolean hasBalanceInfo(){ - if( coinData ==null ) return false; + public boolean hasBalanceInfo() { + if (coinData == null) return false; return coinData.hasBalanceInfo(); } @Override - public boolean checkUnspentTransaction() throws Exception { - checkBlockchainDataExists(); - return coinData.getUnspentTransactions().size() != 0; + public boolean isExtractPossible() { + if (!hasBalanceInfo()) { + ctx.setMessage(R.string.cannot_obtain_data_from_blockchain); + } else if (!isBalanceNotZero()) { + ctx.setMessage(R.string.wallet_empty); + } else if (awaitingConfirmation()) { + ctx.setMessage(R.string.please_wait_while_previous); + } else if (coinData.getUnspentTransactions().size() == 0) { + ctx.setMessage(R.string.please_wait_for_confirmation); + } else { + return true; + } + return false; } @Override - public String getFeeCurrencyHTML() { + public String getFeeCurrency() { return "mBCH"; } @@ -176,12 +181,12 @@ public class BtcCashEngine extends CoinEngine { @Override public InputFilter[] getAmountInputFilters() { - return new InputFilter[] { new DecimalDigitsInputFilter(getDecimals()) }; + return new InputFilter[]{new DecimalDigitsInputFilter(getDecimals())}; } @Override - public boolean checkNewTransactionAmount(Amount amount){ - if( coinData ==null ) return false; + public boolean checkNewTransactionAmount(Amount amount) { + if (coinData == null) return false; if (amount.compareTo(convertToAmount(coinData.getBalanceInInternalUnits())) > 0) { return false; } @@ -208,10 +213,10 @@ public class BtcCashEngine extends CoinEngine { if (fee.isZero() || amount.isZero()) return false; - if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits())>0) + if (isIncludeFee && amount.compareTo(coinData.getBalanceInInternalUnits()) > 0) return false; - if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits())>0) + if (!isIncludeFee && amount.add(fee).compareTo(coinData.getBalanceInInternalUnits()) > 0) return false; return true; @@ -260,7 +265,7 @@ public class BtcCashEngine extends CoinEngine { // return; // } - if ((ctx.getCard().getOfflineBalance() != null) && !coinData.isBalanceReceived() && (ctx.getCard().getRemainingSignatures() == ctx.getCard().getMaxSignatures()) && coinData.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. "); @@ -291,12 +296,18 @@ public class BtcCashEngine extends CoinEngine { @Override public String evaluateFeeEquivalent(String fee) { - return getAmountEquivalentDescriptor(ctx.getCard(), fee); + if (!coinData.getAmountEquivalentDescriptionAvailable()) return ""; + try { + Amount feeAmount = new Amount(fee, getFeeCurrency()); + return feeAmount.toEquivalentString(coinData.getRate()); + } catch (Exception e) { + return ""; + } } @Override public String getBalanceEquivalent() { - if( coinData ==null || !coinData.getAmountEquivalentDescriptionAvailable() ) return ""; + if (coinData == null || !coinData.getAmountEquivalentDescriptionAvailable()) return ""; return getBalance().toEquivalentString(coinData.getRate()); } @@ -337,8 +348,8 @@ public class BtcCashEngine extends CoinEngine { @Override public Amount convertToAmount(InternalAmount internalAmount) { - BigDecimal d=internalAmount.divide(new BigDecimal("100000000")); - return new Amount(d, getBalanceCurrencyHTML()); + BigDecimal d = internalAmount.divide(new BigDecimal("100000000")); + return new Amount(d, getBalanceCurrency()); } @Override @@ -348,8 +359,8 @@ public class BtcCashEngine extends CoinEngine { @Override public InternalAmount convertToInternalAmount(Amount amount) throws Exception { - BigDecimal d=amount.multiply(new BigDecimal("100000000")); - return new InternalAmount(d, getBalanceCurrencyHTML()); + BigDecimal d = amount.multiply(new BigDecimal("100000000")); + return new InternalAmount(d, getBalanceCurrency()); } @Override @@ -357,7 +368,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),"Satoshi"); + return new InternalAmount(Util.byteArrayToLong(reversed), "Satoshi"); } @Override @@ -383,28 +394,13 @@ public class BtcCashEngine extends CoinEngine { // return mCard.getAmountDescription(Double.parseDouble(amount)); // } - public static String getAmountEquivalentDescriptionBTC(Double amount, float rate) { - if ((rate > 0) && (amount > 0)) { - return String.format("≈ USD %.2f", amount * rate); - } else { - return ""; - } - } - - public String getAmountEquivalentDescriptor(TangemCard card, String value) { - - return getAmountEquivalentDescriptionBTC(Double.parseDouble(value), coinData.getRate()); - } - @Override - public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception { + public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { checkBlockchainDataExists(); String myAddress = ctx.getCard().getWallet(); byte[] pbKey = ctx.getCard().getWalletPublicKeyRar(); //ALWAYS USING COMPRESS KEY - String outputAddress = toValue; - String changeAddress = myAddress; // Build script for our address List rawTxList = coinData.getUnspentTransactions(); @@ -419,8 +415,8 @@ public class BtcCashEngine extends CoinEngine { } - long fees = FormatUtil.ConvertStringToLong(feeValue); - long amount = FormatUtil.ConvertStringToLong(amountValue); + long fees = convertToInternalAmount(feeValue).longValueExact(); + long amount = convertToInternalAmount(amountValue).longValueExact(); long change = fullAmount - amount; if (IncFee) { amount = amount - fees; @@ -435,7 +431,7 @@ public class BtcCashEngine extends CoinEngine { byte[][] dataForSign = new byte[unspentOutputs.size()][]; for (int i = 0; i < unspentOutputs.size(); ++i) { - byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, changeAddress, unspentOutputs, i, amount, change); + byte[] newTX = BTCUtils.buildTXForSign(myAddress, targetAddress, myAddress, unspentOutputs, i, amount, change); byte[] hashData = Util.calculateSHA256(newTX); byte[] doubleHashData = Util.calculateSHA256(hashData); @@ -474,6 +470,6 @@ public class BtcCashEngine extends CoinEngine { unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDerBitcoinCash(r, s, pbKey); } - return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change); + return BTCUtils.buildTXForSend(targetAddress, myAddress, unspentOutputs, amount, change); } } 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 a15b1a18fb..db0f08a68a 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java @@ -13,6 +13,7 @@ import com.tangem.util.DecimalDigitsInputFilter; import com.tangem.util.DerEncodingUtil; import com.tangem.util.FormatUtil; import com.tangem.util.Util; +import com.tangem.wallet.R; import java.io.ByteArrayOutputStream; import java.math.BigDecimal; @@ -48,57 +49,6 @@ public class BtcEngine extends CoinEngine { return 8; } - private static String[] getBitcoinServiceHosts() { - return new String[]{ - BitcoinNode.n1.getHost(), - BitcoinNode.n2.getHost(), - BitcoinNode.n3.getHost(), - BitcoinNode.n4.getHost(), - BitcoinNode.n5.getHost(), - BitcoinNode.n6.getHost(), - BitcoinNode.n7.getHost(), - BitcoinNode.n8.getHost(), - BitcoinNode.n9.getHost(), - BitcoinNode.n10.getHost(), - BitcoinNode.n11.getHost(), - BitcoinNode.n12.getHost(), - }; - } - - private static Integer[] getBitcoinServicePorts() { - return new Integer[]{ - BitcoinNode.n1.getPort(), - BitcoinNode.n2.getPort(), - BitcoinNode.n3.getPort(), - BitcoinNode.n4.getPort(), - BitcoinNode.n5.getPort(), - BitcoinNode.n6.getPort(), - BitcoinNode.n7.getPort(), - BitcoinNode.n8.getPort(), - BitcoinNode.n9.getPort(), - BitcoinNode.n10.getPort(), - BitcoinNode.n11.getPort(), - BitcoinNode.n12.getPort(), - }; - } - - private static String[] getBitcoinTestNetServiceHosts() { - return new String[]{ - BitcoinNodeTestNet.n1.getHost(), - BitcoinNodeTestNet.n2.getHost(), - BitcoinNodeTestNet.n3.getHost(), - BitcoinNodeTestNet.n4.getHost()}; - } - - private static Integer[] getBitcoinTestNetServicePorts() { - return new Integer[]{ - BitcoinNodeTestNet.n1.getPort(), - BitcoinNodeTestNet.n2.getPort(), - BitcoinNodeTestNet.n3.getPort(), - BitcoinNodeTestNet.n4.getPort()}; - } - - static int serviceIndex = 0; private void checkBlockchainDataExists() throws Exception { if (coinData == null) throw new Exception("No blockchain data"); @@ -121,7 +71,7 @@ public class BtcEngine extends CoinEngine { } @Override - public String getBalanceCurrencyHTML() { + public String getBalanceCurrency() { return "BTC"; } @@ -132,11 +82,6 @@ public class BtcEngine extends CoinEngine { return offlineAmount.toDescriptionString(getDecimals()); } - @Override - public boolean isBalanceAlterNotZero() { - return true; - } - @Override public boolean isBalanceNotZero() { if( coinData ==null ) return false; @@ -152,13 +97,23 @@ public class BtcEngine extends CoinEngine { @Override - public boolean checkUnspentTransaction() throws Exception { - checkBlockchainDataExists(); - return coinData.getUnspentTransactions().size() != 0; + public boolean isExtractPossible() { + if (!hasBalanceInfo()) { + ctx.setMessage(R.string.cannot_obtain_data_from_blockchain); + } else if (!isBalanceNotZero()) { + ctx.setMessage(R.string.wallet_empty); + } else if (awaitingConfirmation()) { + ctx.setMessage(R.string.please_wait_while_previous); + } else if (coinData.getUnspentTransactions().size() == 0) { + ctx.setMessage(R.string.please_wait_for_confirmation); + } else { + return true; + } + return false; } @Override - public String getFeeCurrencyHTML() { + public String getFeeCurrency() { return "BTC"; } @@ -348,8 +303,14 @@ public class BtcEngine extends CoinEngine { @Override public String evaluateFeeEquivalent(String fee) { if( !coinData.getAmountEquivalentDescriptionAvailable() ) return ""; - Amount feeAmount=new Amount(fee, getFeeCurrencyHTML()); - return feeAmount.toEquivalentString(coinData.getRate()); + try { + Amount feeAmount = new Amount(fee, getFeeCurrency()); + return feeAmount.toEquivalentString(coinData.getRate()); + } + catch (Exception e) + { + return ""; + } } @Override @@ -395,7 +356,7 @@ public class BtcEngine extends CoinEngine { @Override public Amount convertToAmount(InternalAmount internalAmount) { BigDecimal d=internalAmount.divide(new BigDecimal("100000000")); - return new Amount(d, getBalanceCurrencyHTML()); + return new Amount(d, getBalanceCurrency()); } @Override @@ -406,7 +367,7 @@ public class BtcEngine extends CoinEngine { @Override public InternalAmount convertToInternalAmount(Amount amount) throws Exception { BigDecimal d=amount.multiply(new BigDecimal("100000000")); - return new InternalAmount(d, getBalanceCurrencyHTML()); + return new InternalAmount(d, getBalanceCurrency()); } @Override @@ -436,14 +397,12 @@ public class BtcEngine extends CoinEngine { } @Override - public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception { + public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { checkBlockchainDataExists(); String myAddress = ctx.getCard().getWallet(); byte[] pbKey = ctx.getCard().getWalletPublicKey(); - String outputAddress = toValue; - String changeAddress = myAddress; // Build script for our address List rawTxList = coinData.getUnspentTransactions(); @@ -458,8 +417,8 @@ public class BtcEngine extends CoinEngine { } - long fees = FormatUtil.ConvertStringToLong(feeValue); - long amount = FormatUtil.ConvertStringToLong(amountValue); + long fees = convertToInternalAmount(feeValue).longValueExact(); + long amount = convertToInternalAmount(amountValue).longValueExact(); long change = fullAmount - amount; if (IncFee) { amount = amount - fees; @@ -474,7 +433,7 @@ public class BtcEngine extends CoinEngine { byte[][] dataForSign = new byte[unspentOutputs.size()][]; for (int i = 0; i < unspentOutputs.size(); ++i) { - byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, changeAddress, unspentOutputs, i, amount, change); + byte[] newTX = BTCUtils.buildTXForSign(myAddress, targetAddress, myAddress, unspentOutputs, i, amount, change); byte[] hashData = Util.calculateSHA256(newTX); byte[] doubleHashData = Util.calculateSHA256(hashData); @@ -512,7 +471,7 @@ public class BtcEngine extends CoinEngine { unspentOutputs.get(i).scriptForBuild = DerEncodingUtil.packSignDer(r, s, pbKey); } - return BTCUtils.buildTXForSend(outputAddress, changeAddress, unspentOutputs, amount, change); + return BTCUtils.buildTXForSend(targetAddress, myAddress, unspentOutputs, amount, change); } } \ No newline at end of file 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 b5077bcc9b..f3d2a2b6d0 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java @@ -5,13 +5,13 @@ import android.text.InputFilter; 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; +import java.text.DecimalFormatSymbols; +import java.util.Locale; /** * Created by Ilia on 15.02.2018. @@ -19,9 +19,6 @@ import java.text.DecimalFormat; public abstract class CoinEngine { - @Nullable - public static final String EXTRA_ENGINE = "CoinEngine"; - public static class InternalAmount extends BigDecimal { private String currency; @@ -31,7 +28,7 @@ public abstract class CoinEngine { } public InternalAmount(String amountString, String currency) { - super(amountString); + super(amountString.replace(',','.')); this.currency=currency; } @@ -68,7 +65,7 @@ public abstract class CoinEngine { } public Amount(String amountString, String currency) { - super(amountString); + super(amountString.replace(',','.')); this.currency = currency; } @@ -97,9 +94,19 @@ public abstract class CoinEngine { } 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; + DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); + symbols.setDecimalSeparator('.'); + DecimalFormat df = new DecimalFormat(); + df.setDecimalFormatSymbols(symbols); + df.setMaximumFractionDigits(decimals); + + df.setMinimumFractionDigits(0); + + df.setGroupingUsed(false); + + BigDecimal bd=new BigDecimal(unscaledValue(), scale()); + bd.setScale(decimals, ROUND_DOWN); + return df.format(bd)+ " " + currency; } public String toEditString() { @@ -138,18 +145,15 @@ public abstract class CoinEngine { public abstract boolean isBalanceNotZero(); - public abstract boolean isBalanceAlterNotZero(); + public abstract byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception; - public abstract byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception; - - public abstract boolean checkUnspentTransaction() throws Exception; + // TODO - change isExtractPossible to isExtractPossible and if not - return string message + public abstract boolean isExtractPossible(); public abstract Uri getShareWalletUriExplorer(); public abstract Uri getShareWalletUri(); -// public abstract Long getBalanceLong(TangemCard card); - public abstract boolean checkNewTransactionAmount(Amount amount); // TODO - move minFeeInInternalUnits to CoinData @@ -161,7 +165,7 @@ public abstract class CoinEngine { public abstract String getBalanceHTML(); - public abstract String getBalanceCurrencyHTML(); + public abstract String getBalanceCurrency(); public abstract InputFilter[] getAmountInputFilters(); @@ -169,18 +173,12 @@ public abstract class CoinEngine { public abstract String evaluateFeeEquivalent(String fee); - public abstract String getFeeCurrencyHTML(); + public abstract String getFeeCurrency(); public abstract boolean isNeedCheckNode(); public abstract String getBalanceEquivalent(); -// public abstract String getBalanceValue(TangemCard card); - -// public abstract String getAmountDescription(TangemCard card, String amount) throws Exception; - -// public abstract String getAmountEquivalentDescriptor(TangemCard card, String value); - public abstract boolean validateAddress(String address); public abstract String calculateAddress(byte[] pkUncompressed) throws NoSuchProviderException, NoSuchAlgorithmException; @@ -193,9 +191,6 @@ public abstract class CoinEngine { public abstract byte[] convertToByteArray(InternalAmount internalAmount) throws Exception; - -// public abstract CoinEngine swithToBaseEngine(); - public abstract CoinData createCoinData(); public abstract String getUnspentInputsDescription(); 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 320b0f1da7..1c9e691803 100644 --- a/app/src/main/java/com/tangem/domain/wallet/EthEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/EthEngine.java @@ -9,6 +9,7 @@ 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; @@ -32,7 +33,7 @@ public class EthEngine extends CoinEngine { if (ctx.getCoinData() == null) { coinData = new EthData(); ctx.setCoinData(coinData); - } else if (ctx.getCoinData() instanceof BtcData) { + } else if (ctx.getCoinData() instanceof EthData) { coinData = (EthData) ctx.getCoinData(); } else { throw new Exception("Invalid type of Blockchain data for EthEngine"); @@ -71,7 +72,7 @@ public class EthEngine extends CoinEngine { } @Override - public String getBalanceCurrencyHTML() { + public String getBalanceCurrency() { return "ETH"; } @@ -82,14 +83,6 @@ public class EthEngine extends CoinEngine { return offlineAmount.toDescriptionString(getDecimals()); } - @Override - public boolean isBalanceAlterNotZero() { - return true; //TODO ??? -// if( coinData==null ) return false; -// if (coinData.getBalanceAlterInInternalUnits() == null) return false; -// return coinData.getBalanceAlterInInternalUnits().notZero(); - } - @Override public boolean isBalanceNotZero() { if( coinData ==null ) return false; @@ -98,7 +91,7 @@ public class EthEngine extends CoinEngine { } @Override - public String getFeeCurrencyHTML() { + public String getFeeCurrency() { return "ETH"; } @@ -236,8 +229,17 @@ public class EthEngine extends CoinEngine { } @Override - public boolean checkUnspentTransaction() { - return true; + public boolean isExtractPossible() { + if (!hasBalanceInfo()) { + ctx.setMessage(R.string.cannot_obtain_data_from_blockchain); + } else if (!isBalanceNotZero()) { + ctx.setMessage(R.string.wallet_empty); + } else if (awaitingConfirmation()) { + ctx.setMessage(R.string.please_wait_while_previous); + } else { + return true; + } + return false; } @Override @@ -331,8 +333,15 @@ public class EthEngine extends CoinEngine { @Override public String evaluateFeeEquivalent(String fee) { - Amount feeValue = new Amount(fee, ctx.getBlockchain().getCurrency()); - return feeValue.toEquivalentString(coinData.getRate()); + try { + Amount feeValue = new Amount(fee, ctx.getBlockchain().getCurrency()); + return feeValue.toEquivalentString(coinData.getRate()); + } + catch (Exception e) + { + e.printStackTrace(); + return ""; + } } @Override @@ -357,7 +366,7 @@ public class EthEngine extends CoinEngine { } @Override - public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception { + public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { BigInteger nonceValue = coinData.getConfirmedTXCount(); byte[] pbKey = ctx.getCard().getWalletPublicKey(); @@ -365,33 +374,27 @@ public class EthEngine extends CoinEngine { Issuer issuer = ctx.getCard().getIssuer(); - BigInteger fee = new BigInteger(feeValue, 10); + BigInteger gigaK = BigInteger.valueOf(1000000000L); - BigDecimal amountDec = new BigDecimal(amountValue); - amountDec = amountDec.multiply(new BigDecimal("1000000000")); + BigInteger weiFee=convertToInternalAmount(feeValue).toBigIntegerExact(); + BigInteger weiAmount=convertToInternalAmount(amountValue).toBigIntegerExact(); - - BigInteger amount = amountDec.toBigInteger(); //new BigInteger(amountValue, 10); if (IncFee) { - amount = amount.subtract(fee); + weiAmount = weiAmount.subtract(weiFee); } BigInteger nonce = nonceValue; - BigInteger gasPrice = fee.divide(BigInteger.valueOf(21000)); + BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(21000)).multiply(gigaK); BigInteger gasLimit = BigInteger.valueOf(21000); Integer chainId = ctx.getBlockchain() == Blockchain.Ethereum ? EthTransaction.ChainEnum.Mainnet.getValue() : EthTransaction.ChainEnum.Rinkeby.getValue(); - Long multiplicator = 1000000000L; - amount = amount.multiply(BigInteger.valueOf(multiplicator)); - gasPrice = gasPrice.multiply(BigInteger.valueOf(multiplicator)); - - String to = toValue; + String to = targetAddress; if (to.startsWith("0x") || to.startsWith("0X")) { to = to.substring(2); } - EthTransaction tx = EthTransaction.create(to, amount, nonce, gasPrice, gasLimit, chainId); + EthTransaction tx = EthTransaction.create(to, weiAmount, nonce, gasPrice, gasLimit, chainId); byte[][] hashesForSign = new byte[1][]; byte[] for_hash = tx.getRawHash(); 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 7101f43269..7ab12cebbf 100644 --- a/app/src/main/java/com/tangem/domain/wallet/TangemContext.java +++ b/app/src/main/java/com/tangem/domain/wallet/TangemContext.java @@ -1,6 +1,7 @@ package com.tangem.domain.wallet; import android.content.Context; +import android.content.Intent; import android.os.Bundle; @@ -67,6 +68,10 @@ public class TangemContext { this.message = value; } + public void setMessage(int valueId) { + this.message = getString(valueId); + } + public String getMessage() { return message; } @@ -94,19 +99,19 @@ public class TangemContext { return tangemContext; } - public void saveToBundle(Bundle bundle) { + public void saveToIntent(Intent intent) { if (card != null) { - bundle.putString(TangemCard.EXTRA_UID, card.getUID()); - bundle.putBundle(TangemCard.EXTRA_CARD, card.getAsBundle()); + intent.putExtra(TangemCard.EXTRA_UID, card.getUID()); + intent.putExtra(TangemCard.EXTRA_CARD, card.getAsBundle()); } if (coinData != null) { - bundle.putBundle(EXTRA_BLOCKCHAIN_DATA, coinData.asBundle()); + intent.putExtra(EXTRA_BLOCKCHAIN_DATA, coinData.asBundle()); } - bundle.putString("Error", error); - bundle.putString("Message", message); + intent.putExtra("Error", error); + intent.putExtra("Message", message); } 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 38e46687b0..8388b4c701 100644 --- a/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/TokenEngine.java @@ -34,7 +34,7 @@ public class TokenEngine extends CoinEngine { if (ctx.getCoinData() == null) { coinData = new TokenData(); ctx.setCoinData(coinData); - } else if (ctx.getCoinData() instanceof BtcData) { + } else if (ctx.getCoinData() instanceof TokenData) { coinData = (TokenData) ctx.getCoinData(); } else { throw new Exception("Invalid type of Blockchain data for TokenEngine"); @@ -83,7 +83,7 @@ public class TokenEngine extends CoinEngine { } @Override - public String getBalanceCurrencyHTML() { + public String getBalanceCurrency() { String currency = ctx.getCard().getTokenSymbol(); if (Strings.isNullOrEmpty(currency)) return "NoN"; @@ -109,7 +109,7 @@ public class TokenEngine extends CoinEngine { } @Override - public String getFeeCurrencyHTML() { + public String getFeeCurrency() { return "ETH"; } @@ -151,7 +151,6 @@ public class TokenEngine extends CoinEngine { return true; } - @Override public boolean isBalanceAlterNotZero() { if (coinData == null) return false; if (coinData.getBalanceAlterInInternalUnits() == null) return false; @@ -284,8 +283,19 @@ public class TokenEngine extends CoinEngine { } @Override - public boolean checkUnspentTransaction() { - return true; + public boolean isExtractPossible() { + if (!hasBalanceInfo()) { + ctx.setMessage(R.string.cannot_obtain_data_from_blockchain); + } else if (!isBalanceNotZero()) { + ctx.setMessage(R.string.wallet_empty); + } else if (awaitingConfirmation()) { + ctx.setMessage(R.string.please_wait_while_previous); + } else if (!isBalanceAlterNotZero()) { + ctx.setMessage(ctx.getString(R.string.not_enough_eth_for_gas)); + } else { + return true; + } + return false; } @Override @@ -300,9 +310,7 @@ public class TokenEngine extends CoinEngine { } else { return false; } - } - catch (Exception e) - { + } catch (Exception e) { e.printStackTrace(); return false; } @@ -395,8 +403,13 @@ public class TokenEngine extends CoinEngine { @Override public String evaluateFeeEquivalent(String fee) { - Amount feeValue = new Amount(fee, getFeeCurrencyHTML()); - return feeValue.toEquivalentString(coinData.getRate()); + try { + Amount feeValue = new Amount(fee, getFeeCurrency()); + return feeValue.toEquivalentString(coinData.getRate()); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } // // BigDecimal gweFee = new BigDecimal(fee); @@ -406,41 +419,104 @@ public class TokenEngine extends CoinEngine { } @Override - public byte[] sign(String feeValue, String amountValue, boolean IncFee, String toValue, CardProtocol protocol) throws Exception { + public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { + if (amountValue.getCurrency().equals("ETH")) { + return signETH(feeValue, amountValue, IncFee, targetAddress, protocol); + } else { + return signToken(feeValue, amountValue, IncFee, targetAddress, protocol); + } + } + + public byte[] signETH(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, 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); + BigInteger gigaK = BigInteger.valueOf(1000000000L); - BigDecimal amountDecValue = new BigDecimal(amountValue); + BigInteger weiFee = convertToInternalAmount(feeValue).toBigIntegerExact(); + BigInteger weiAmount = convertToInternalAmount(amountValue).toBigIntegerExact(); - int d = getTokenDecimals(); - BigDecimal amountDec = new BigDecimal("10"); - amountDec = amountDec.pow(d); - amountDec = amountDecValue.multiply(amountDec); + if (IncFee) { + weiAmount = weiAmount.subtract(weiFee); + } - //amountDec = amountDec.multiply(new BigDecimal("1000000000")); + BigInteger nonce = nonceValue; + BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(21000)).multiply(gigaK); + BigInteger gasLimit = BigInteger.valueOf(21000); + Integer chainId = ctx.getBlockchain() == Blockchain.Ethereum ? EthTransaction.ChainEnum.Mainnet.getValue() : EthTransaction.ChainEnum.Rinkeby.getValue(); + + String to = targetAddress; + + if (to.startsWith("0x") || to.startsWith("0X")) { + to = to.substring(2); + } + + EthTransaction tx = EthTransaction.create(to, weiAmount, nonce, gasPrice, gasLimit, chainId); + + byte[][] hashesForSign = new byte[1][]; + byte[] for_hash = tx.getRawHash(); + hashesForSign[0] = for_hash; + + byte[] signFromCard = null; + try { + signFromCard = protocol.run_SignHashes(PINStorage.getPIN2(), hashesForSign, flag, null, issuer).getTLV(TLV.Tag.TAG_Signature).Value; + // TODO slice signFromCard to hashes.length parts + } catch (Exception ex) { + Log.e("ETH", ex.getMessage()); + return null; + } + + BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0, 32)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32, 64)); + s = CryptoUtil.toCanonicalised(s); + + boolean f = ECKey.verify(for_hash, new ECKey.ECDSASignature(r, s), pbKey); + + if (!f) { + Log.e("ETH-CHECK", "sign Failed."); + } + + tx.signature = new ECDSASignatureETH(r, s); + int v = tx.BruteRecoveryID2(tx.signature, for_hash, pbKey); + if (v != 27 && v != 28) { + Log.e("ETH", "invalid v"); + return null; + } + tx.signature.v = (byte) v; + Log.e("ETH_v", String.valueOf(v)); + + byte[] realTX = tx.getEncoded(); + return realTX; + } + + public byte[] signToken(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, 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 gigaK = BigInteger.valueOf(1000000000L); + + BigInteger weiFee = convertToInternalAmount(feeValue).toBigIntegerExact(); + + InternalAmount amountDec=convertToInternalAmount(amountValue); BigInteger amount = amountDec.toBigInteger(); //new BigInteger(amountValue, 10); //amount = amount.subtract(fee); BigInteger nonce = nonceValue; - BigInteger gasPrice = fee.divide(BigInteger.valueOf(60000)); + BigInteger gasPrice = weiFee.divide(gigaK).divide(BigInteger.valueOf(60000)).multiply(gigaK); BigInteger gasLimit = BigInteger.valueOf(60000); Integer chainId = EthTransaction.ChainEnum.Mainnet.getValue(); BigInteger amountZero = BigInteger.ZERO; - Long multiplicator = 1000000000L; - - gasPrice = gasPrice.multiply(BigInteger.valueOf(multiplicator)); - - String to = toValue; + String to = targetAddress; if (to.startsWith("0x") || to.startsWith("0X")) { to = to.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 bfe1683911..20e830c3ac 100644 --- a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt @@ -72,7 +72,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { val html = Html.fromHtml(engine!!.balanceHTML) tvBalance.text = html - isIncludeFee = intent.getBooleanExtra("IncFee", true) + isIncludeFee = intent.getBooleanExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, true) if (isIncludeFee) tvIncFee.setText(R.string.including_fee) @@ -83,10 +83,10 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { else tvIncFee.visibility = View.VISIBLE etAmount.setText(intent.getStringExtra(SignPaymentActivity.EXTRA_AMOUNT)) - tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML) - tvCurrency2.text = Html.fromHtml(engine.feeCurrencyHTML) + tvCurrency.text = engine.balanceCurrency + tvCurrency2.text = engine.feeCurrency tvCardID.text = ctx.card!!.cidDescription - etWallet.setText(intent.getStringExtra("Wallet")) + etWallet.setText(intent.getStringExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS)) etFee.setText("") btnSend.visibility = View.INVISIBLE @@ -126,7 +126,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { try { - val engine = CoinEngineFactory.create(ctx.blockchain) + val engine = CoinEngineFactory.create(ctx) val eqFee = engine!!.evaluateFeeEquivalent(etFee!!.text.toString()) tvFeeEquivalent.text = eqFee @@ -174,7 +174,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { finishWithError(Activity.RESULT_CANCELED, getString(R.string.the_wallet_is_empty)) return@setOnClickListener - } else if (!engineCoin.checkUnspentTransaction()) { + } else if (!engineCoin.isExtractPossible()) { finishWithError(Activity.RESULT_CANCELED, getString(R.string.please_wait_for_confirmation_of_incoming_transaction)) return@setOnClickListener } @@ -187,10 +187,10 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { requestPIN2Count = 0 val intent = Intent(baseContext, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) // intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) // intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) - intent.putExtra("IncFee", isIncludeFee) + intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2) } @@ -354,10 +354,8 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { requestPIN2Count++ val intent = Intent(baseContext, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra("Card", card!!.asBundle) - intent.putExtra("IncFee", isIncludeFee) + ctx.saveToIntent(intent) + intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2) return } @@ -366,13 +364,13 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { } else if (requestCode == REQUEST_CODE_REQUEST_PIN2) { if (resultCode == Activity.RESULT_OK) { val intent = Intent(baseContext, SignPaymentActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra("Card", card!!.asBundle) - intent.putExtra("Wallet", etWallet!!.text.toString()) + ctx.saveToIntent(intent) + intent.putExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString()) intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, etAmount.text.toString()) - intent.putExtra("Fee", etFee.text.toString()) - intent.putExtra("IncFee", isIncludeFee) + intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString()) + intent.putExtra(SignPaymentActivity.EXTRA_FEE, etFee.text.toString()) + intent.putExtra(SignPaymentActivity.EXTRA_FEE_CURRENCY, tvCurrency2.text.toString()) + intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, isIncludeFee) startActivityForResult(intent, REQUEST_CODE_SIGN_PAYMENT) } else Toast.makeText(baseContext, R.string.pin_2_is_required_to_sign_the_payment, Toast.LENGTH_LONG).show() 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 6224d019e9..ced8c667d8 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitOtherAPIWithdrawalActivity.kt @@ -9,15 +9,12 @@ import android.nfc.Tag import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.text.Html -import android.text.InputFilter import android.view.View import com.tangem.data.network.Cryptonit_OtherAPI import com.tangem.domain.cardReader.NfcManager import com.tangem.domain.wallet.Blockchain import com.tangem.domain.wallet.CoinEngineFactory -import com.tangem.domain.wallet.TangemCard import com.tangem.domain.wallet.TangemContext -import com.tangem.util.DecimalDigitsInputFilter import com.tangem.wallet.R import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.* import java.io.IOException @@ -58,7 +55,7 @@ class PrepareCryptonitOtherAPIWithdrawalActivity : AppCompatActivity(), NfcAdapt tvWallet.text = ctx.card!!.wallet val engine = CoinEngineFactory.create(ctx) - tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML) + tvCurrency.text = engine.balanceCurrency etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString()) etAmount.filters=engine.amountInputFilters 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 9ffc2e0309..4e62c4892a 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareCryptonitWithdrawalActivity.kt @@ -17,7 +17,6 @@ import com.tangem.data.network.Cryptonit import com.tangem.domain.cardReader.NfcManager import com.tangem.domain.wallet.Blockchain import com.tangem.domain.wallet.CoinEngineFactory -import com.tangem.domain.wallet.TangemCard import com.tangem.domain.wallet.TangemContext import com.tangem.util.DecimalDigitsInputFilter import com.tangem.wallet.R @@ -57,8 +56,8 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade tvWallet.text = ctx.card!!.wallet val engine = CoinEngineFactory.create(ctx) - tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML) - tvFeeCurrency.text = tvCurrency.text + tvCurrency.text = engine.balanceCurrency + tvFeeCurrency.text = engine.feeCurrency etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString()) etAmount.filters=engine.amountInputFilters 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 1db5e89d67..2eeaeb6907 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PrepareKrakenWithdrawalActivity.kt @@ -12,7 +12,6 @@ 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 @@ -21,9 +20,7 @@ import com.tangem.data.network.Kraken import com.tangem.domain.cardReader.NfcManager import com.tangem.domain.wallet.Blockchain import com.tangem.domain.wallet.CoinEngineFactory -import com.tangem.domain.wallet.TangemCard import com.tangem.domain.wallet.TangemContext -import com.tangem.util.DecimalDigitsInputFilter import com.tangem.wallet.R import kotlinx.android.synthetic.main.activity_prepare_kraken_withdrawal.* import java.io.IOException @@ -64,7 +61,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa tvWallet.text = ctx.card!!.wallet val engine = CoinEngineFactory.create(ctx) - tvCurrency.text = Html.fromHtml(engine.balanceCurrencyHTML) + tvCurrency.text = engine.balanceCurrency etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toEditString()) etAmount.filters=engine.amountInputFilters 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 aa27f270dc..2f1256688d 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt @@ -78,7 +78,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { } btnVerify.setOnClickListener { - val engine1 = CoinEngineFactory.create(ctx.card!!.blockchain) + val engine1 = CoinEngineFactory.create(ctx) val strAmount: String = etAmount.text.toString().replace(",", ".") val amount=engine1.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString()) @@ -113,10 +113,11 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { // } val intent = Intent(baseContext, ConfirmPaymentActivity::class.java) - ctx.saveToBundle(intent.extras) - intent.putExtra("Wallet", etWallet!!.text.toString()) - intent.putExtra("IncFee", (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn)) + ctx.saveToIntent(intent) + intent.putExtra(SignPaymentActivity.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString()) + intent.putExtra(SignPaymentActivity.EXTRA_FEE_INCLUDED, (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn)) intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, strAmount) + intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString()) startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT) } ivCamera.setOnClickListener { diff --git a/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt b/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt index 7916cd31c6..e64b5770dd 100644 --- a/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/SignPaymentActivity.kt @@ -16,6 +16,7 @@ import android.widget.Toast import com.tangem.data.nfc.SignPaymentTask import com.tangem.domain.cardReader.CardProtocol import com.tangem.domain.cardReader.NfcManager +import com.tangem.domain.wallet.CoinEngine import com.tangem.domain.wallet.TangemCard import com.tangem.domain.wallet.TangemContext import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog @@ -32,6 +33,11 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card val TAG: String = SignPaymentActivity::class.java.simpleName const val EXTRA_AMOUNT = "Amount" + const val EXTRA_AMOUNT_CURRENCY = "AmountCurrency" + const val EXTRA_FEE = "Fee" + const val EXTRA_FEE_CURRENCY = "FeeCurrency" + const val EXTRA_FEE_INCLUDED = "FeeIncluded" + const val EXTRA_TARGET_ADDRESS = "TargetAddress" const val REQUEST_CODE_SEND_PAYMENT = 1 const val RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER } @@ -41,8 +47,8 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card private var signPaymentTask: SignPaymentTask? = null - private var amountStr: String? = null - private var feeStr: String? = null + private var amount: CoinEngine.Amount? = null + private var fee: CoinEngine.Amount? = null private var isIncludeFee = true private var outAddressStr: String? = null private var lastReadSuccess = true @@ -59,10 +65,10 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card ctx=TangemContext.loadFromBundle(this, intent.extras) - amountStr = intent.getStringExtra(EXTRA_AMOUNT) - feeStr = intent.getStringExtra("Fee") - isIncludeFee = intent.getBooleanExtra("IncFee", true) - outAddressStr = intent.getStringExtra("Wallet") + amount = CoinEngine.Amount(intent.getStringExtra(EXTRA_AMOUNT), intent.getStringExtra(EXTRA_AMOUNT_CURRENCY)) + fee = CoinEngine.Amount(intent.getStringExtra(EXTRA_FEE), intent.getStringExtra(EXTRA_FEE_CURRENCY)) + isIncludeFee = intent.getBooleanExtra(EXTRA_FEE_INCLUDED, true) + outAddressStr = intent.getStringExtra(EXTRA_TARGET_ADDRESS) tvCardID.text = ctx.card!!.cidDescription @@ -127,7 +133,7 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card } else { isoDep.timeout = ctx.card!!.pauseBeforePIN2 + 65000 } - signPaymentTask = SignPaymentTask(this, ctx, nfcManager, isoDep, this, amountStr, feeStr, isIncludeFee, outAddressStr) + signPaymentTask = SignPaymentTask(this, ctx, nfcManager, isoDep, this, amount, fee, isIncludeFee, outAddressStr) signPaymentTask!!.start() } else { // Log.d(TAG, "Mismatch card UID (" + sUID + " instead of " + card!!.uid + ")") 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 b66ccb23e2..6d9b919858 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -159,16 +159,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific // } getString(R.string.via_cryptonit) -> { val intent = Intent(activity, PrepareCryptonitWithdrawalActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra("Card", card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT) } getString(R.string.via_kraken) -> { val intent = Intent(activity, PrepareKrakenWithdrawalActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra("Card", card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_RECEIVE_PAYMENT) } else -> { @@ -203,24 +199,13 @@ 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) - showSingleToast(R.string.wallet_empty) - else if (!engine!!.isBalanceAlterNotZero) - showSingleToast(R.string.not_enough_eth_for_gas) - else if (engine!!.awaitingConfirmation()) - showSingleToast(R.string.please_wait_while_previous) - else if (!engine!!.checkUnspentTransaction()) - showSingleToast(R.string.please_wait_for_confirmation) + if (!engine!!.isExtractPossible) + showSingleToast(ctx.message) else if (ctx.card!!.remainingSignatures == 0) showSingleToast(R.string.card_has_no_remaining_signature) else { val intent = Intent(activity, PreparePaymentActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra("Card", card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT) } } else @@ -523,9 +508,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific if (data.extras != null && data.extras!!.containsKey("confirmPIN")) { val intent = Intent(activity, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) -// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) newPIN = data.getStringExtra("newPIN") startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) } else { @@ -541,9 +524,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific if (data.extras != null && data.extras!!.containsKey("confirmPIN2")) { val intent = Intent(activity, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) -// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) newPIN2 = data.getStringExtra("newPIN2") startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) } else { @@ -575,9 +556,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) { if (data == null) { data = Intent() - ctx.saveToBundle(data.extras) -// data.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(data) data.putExtra("modification", "delete") } else data.putExtra("modification", "update") @@ -596,9 +575,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific requestPIN2Count++ val intent = Intent(activity, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) -// intent.putExtra("UID", card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) return } else { @@ -609,17 +586,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific } REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) { val intent = Intent(activity, PurgeActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_PURGE) } REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) { if (data == null) { data = Intent() - ctx.saveToBundle(data.extras) -// data.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// data.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(data) data.putExtra("modification", "delete") } else { data.putExtra("modification", "update") @@ -638,9 +611,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific requestPIN2Count++ val intent = Intent(activity, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) -// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE) return } else { @@ -918,7 +889,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific private fun openVerifyCard(cardProtocol: CardProtocol) { val intent = Intent(activity, VerifyCardActivity::class.java) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD) } @@ -986,9 +957,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific private fun startSwapPINActivity() { val intent = Intent(activity, PinSwapActivity::class.java) - ctx.saveToBundle(intent.extras) -// intent.putExtra(TangemCard.EXTRA_UID, card!!.uid) -// intent.putExtra(TangemCard.EXTRA_CARD, card!!.asBundle) + ctx.saveToIntent(intent) intent.putExtra("newPIN", newPIN) intent.putExtra("newPIN2", newPIN2) startActivityForResult(intent, REQUEST_CODE_SWAP_PIN) @@ -1006,4 +975,13 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific } } + private fun showSingleToast(text: String) { + if (singleToast == null || !singleToast!!.view.isShown || showTime.time + 2000 < Date().time) { + if (singleToast != null) + singleToast!!.cancel() + singleToast = Toast.makeText(activity, text, Toast.LENGTH_LONG) + singleToast!!.show() + showTime = Date() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt b/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt index 5c496dc7f1..7e69ae0d5b 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt @@ -101,7 +101,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { if (data.extras!!.containsKey("confirmPIN")) { val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) newPIN = data.getStringExtra("newPIN") startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) } else { @@ -117,7 +117,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { if (data.extras!!.containsKey("confirmPIN2")) { val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) newPIN2 = data.getStringExtra("newPIN2") startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) } else { @@ -147,7 +147,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { REQUEST_CODE_SWAP_PIN -> if (resultCode == Activity.RESULT_OK) { if (data == null) { data = Intent() - ctx.saveToBundle(data.extras) + ctx.saveToIntent(data) data.putExtra("modification", "delete") } else data.putExtra("modification", "update") @@ -163,7 +163,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { requestPIN2Count++ val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) return } else { @@ -174,14 +174,13 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { } REQUEST_CODE_REQUEST_PIN2_FOR_PURGE -> if (resultCode == Activity.RESULT_OK) { val intent = Intent(context, PurgeActivity::class.java) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_PURGE) } REQUEST_CODE_PURGE -> if (resultCode == Activity.RESULT_OK) { if (data == null) { data = Intent() - - ctx.saveToBundle(data.extras) + ctx.saveToIntent(data) data.putExtra("modification", "delete") } else { data.putExtra("modification", "update") @@ -198,7 +197,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { requestPIN2Count++ val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE) return } else { @@ -430,7 +429,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { requestPIN2Count = 0 val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) newPIN = PINStorage.getDefaultPIN() newPIN2 = "" startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) @@ -440,7 +439,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { requestPIN2Count = 0 val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) newPIN = "" newPIN2 = PINStorage.getDefaultPIN2() startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) @@ -450,7 +449,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { requestPIN2Count = 0 val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) newPIN = PINStorage.getDefaultPIN() newPIN2 = PINStorage.getDefaultPIN2() startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_SWAP_PIN) @@ -477,13 +476,13 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { val intent = Intent(context, PinRequestActivity::class.java) intent.putExtra("mode", PinRequestActivity.Mode.RequestPIN2.toString()) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2_FOR_PURGE) } private fun startSwapPINActivity() { val intent = Intent(context, PinSwapActivity::class.java) - ctx.saveToBundle(intent.extras) + ctx.saveToIntent(intent) intent.putExtra("newPIN", newPIN) intent.putExtra("newPIN2", newPIN2) startActivityForResult(intent, REQUEST_CODE_SWAP_PIN) @@ -491,7 +490,7 @@ class VerifyCard : Fragment(), NfcAdapter.ReaderCallback { fun prepareResultIntent(): Intent { val data = Intent() - ctx.saveToBundle(data.extras) + ctx.saveToIntent(data) return data }