diff --git a/app/src/main/java/com/tangem/data/network/ServerApiElectrum.java b/app/src/main/java/com/tangem/data/network/ServerApiElectrum.java index 38a86a3ebd..53b250d78b 100644 --- a/app/src/main/java/com/tangem/data/network/ServerApiElectrum.java +++ b/app/src/main/java/com/tangem/data/network/ServerApiElectrum.java @@ -157,7 +157,7 @@ public class ServerApiElectrum { Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " onComplete, answerData==null"); } Log.e(TAG, String.format("%d requests left in processing",requestsCount)); - if (electrumRequest.answerData != null) { + if (electrumRequest.answerData != null && electrumRequest.getError()==null) { electrumRequestDataListener.onSuccess(electrumRequest); } else { // if( error==null || error.isEmpty() ) setErrorOccurred(ctx.getString(R.string.cannot_obtain_data_from_blockchain)); @@ -172,6 +172,7 @@ public class ServerApiElectrum { String host; int port; String proto; + electrumRequest.setError(null); // todo - get available URL list from coinEngine, remove if( ctx.getBlockchain()==...) if (ctx.getBlockchain() == Blockchain.BitcoinTestNet) { BitcoinNodeTestNet bitcoinNodeTestNet = BitcoinNodeTestNet.values()[new Random().nextInt(BitcoinNodeTestNet.values().length)]; diff --git a/app/src/main/java/com/tangem/domain/wallet/btc/BtcData.java b/app/src/main/java/com/tangem/domain/wallet/btc/BtcData.java index 497ec30abe..f036a85aa0 100644 --- a/app/src/main/java/com/tangem/domain/wallet/btc/BtcData.java +++ b/app/src/main/java/com/tangem/domain/wallet/btc/BtcData.java @@ -18,11 +18,19 @@ public class BtcData extends CoinData { private Long balanceConfirmed, balanceUnconfirmed; public String getUnspentInputsDescription() { - int gatheredUnspents = 0; - for (int i=0; i 1) gatheredUnspents++; + try { + int gatheredUnspents = 0; + if( unspentTransactions==null ) return ""; + for (int i = 0; i < unspentTransactions.size(); i++) { + if (unspentTransactions.get(i).Raw != null && unspentTransactions.get(i).Raw.length() > 1) gatheredUnspents++; + } + return String.valueOf(unspentTransactions.size()) + " unspents (" + String.valueOf(gatheredUnspents) + " received)"; + } + catch (Exception e) + { + e.printStackTrace(); + return ""; } - return String.valueOf(unspentTransactions.size()) + " unspents (" + String.valueOf(gatheredUnspents) + " received)"; } public static class UnspentTransaction { diff --git a/app/src/main/java/com/tangem/domain/wallet/eth/EthEngine.java b/app/src/main/java/com/tangem/domain/wallet/eth/EthEngine.java index c3ba1ee6b4..876bc8bd17 100644 --- a/app/src/main/java/com/tangem/domain/wallet/eth/EthEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/eth/EthEngine.java @@ -82,7 +82,7 @@ public class EthEngine extends CoinEngine { @Override public String getBalanceCurrency() { - return "ETH"; + return Blockchain.Ethereum.getCurrency(); } @Override @@ -101,7 +101,7 @@ public class EthEngine extends CoinEngine { @Override public String getFeeCurrency() { - return "ETH"; + return Blockchain.Ethereum.getCurrency(); } public boolean isNeedCheckNode() { @@ -445,11 +445,11 @@ public class EthEngine extends CoinEngine { 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"); + Log.e(TAG, "invalid v"); throw new Exception("Error in EthEngine - invalid v"); } tx.signature.v = (byte) v; - Log.e("ETH_v", String.valueOf(v)); + Log.e(TAG, "ETH_v: " +String.valueOf(v)); byte[] txForSend = tx.getEncoded(); notifyOnNeedSendPayment(txForSend); diff --git a/app/src/main/java/com/tangem/domain/wallet/token/TokenEngine.java b/app/src/main/java/com/tangem/domain/wallet/token/TokenEngine.java index cadbac4caa..23bdd7d2e5 100644 --- a/app/src/main/java/com/tangem/domain/wallet/token/TokenEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/token/TokenEngine.java @@ -109,7 +109,7 @@ public class TokenEngine extends CoinEngine { if (coinData.getBalanceInInternalUnits().notZero()) { return currency; } else { - return "ETH"; + return Blockchain.Ethereum.getCurrency(); } } else { return currency; @@ -128,7 +128,7 @@ public class TokenEngine extends CoinEngine { @Override public String getFeeCurrency() { - return "ETH"; + return Blockchain.Ethereum.getCurrency(); } @Override @@ -227,7 +227,7 @@ public class TokenEngine extends CoinEngine { 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"); + return new Amount(d, Blockchain.Ethereum.getCurrency()); } else if (internalAmount.getCurrency().equals(ctx.getCard().getTokenSymbol())) { BigDecimal p = new BigDecimal(10); p = p.pow(getTokenDecimals()); @@ -244,7 +244,7 @@ public class TokenEngine extends CoinEngine { @Override public InternalAmount convertToInternalAmount(Amount amount) throws Exception { - if (amount.getCurrency().equals("ETH")) { + if (amount.getCurrency().equals(Blockchain.Ethereum.getCurrency())) { BigDecimal d = amount.multiply(new BigDecimal("1000000000000000000")); return new InternalAmount(d, "wei"); } else if (amount.getCurrency().equals(ctx.getCard().getTokenSymbol())) { @@ -325,7 +325,7 @@ public class TokenEngine extends CoinEngine { try { if (amount.getCurrency().equals(ctx.getCard().tokenSymbol)) { balance = convertToAmount(coinData.getBalanceInInternalUnits()); - } else if (amount.getCurrency().equals("ETH") && coinData.getBalanceInInternalUnits().isZero()) { + } else if (amount.getCurrency().equals(Blockchain.Ethereum.getCurrency()) && coinData.getBalanceInInternalUnits().isZero()) { balance = convertToAmount(coinData.getBalanceAlterInInternalUnits()); } else { return false; @@ -342,7 +342,7 @@ public class TokenEngine extends CoinEngine { if (!hasBalanceInfo()) return false; try { - Amount balance = convertToAmount(coinData.getBalanceAlterInInternalUnits()); + Amount balanceETH = convertToAmount(coinData.getBalanceAlterInInternalUnits()); if (fee == null || amount == null || fee.isZero() || amount.isZero()) return false; @@ -350,22 +350,20 @@ public class TokenEngine extends CoinEngine { if (amount.getCurrency().equals(ctx.getCard().tokenSymbol)) { // token transaction - if (fee.compareTo(balance) > 0) + if (fee.compareTo(balanceETH) > 0) return false; - } else if (amount.getCurrency().equals("ETH") && coinData.getBalanceInInternalUnits().isZero()) { + } else if (amount.getCurrency().equals(Blockchain.Ethereum.getCurrency()) && coinData.getBalanceInInternalUnits().isZero()) { // standard ETH transaction - try { - BigDecimal cardBalance = getBalance(); - - if (isFeeIncluded && amount.compareTo(cardBalance) > 0) +// try { + if (isFeeIncluded && (amount.compareTo(balanceETH) > 0 || fee.compareTo(balanceETH) > 0)) return false; - if (!isFeeIncluded && amount.add(fee).compareTo(cardBalance) > 0) + if (!isFeeIncluded && amount.add(fee).compareTo(balanceETH) > 0) return false; - } catch (NumberFormatException e) { - e.printStackTrace(); - } +// } catch (NumberFormatException e) { +// e.printStackTrace(); +// } } else { @@ -434,7 +432,7 @@ public class TokenEngine extends CoinEngine { @Override public SignTask.PaymentToSign constructPayment(Amount amountValue, Amount feeValue, boolean IncFee, String targetAddress) throws Exception { - if (amountValue.getCurrency().equals("ETH")) { + if (amountValue.getCurrency().equals(Blockchain.Ethereum.getCurrency())) { return constructPaymentETH(feeValue, amountValue, IncFee, targetAddress); } else { return constructPaymentToken(feeValue, amountValue, IncFee, targetAddress); @@ -511,11 +509,11 @@ public class TokenEngine extends CoinEngine { 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"); + Log.e(TAG, "invalid v"); throw new Exception("Error in EthEngine - invalid v"); } tx.signature.v = (byte) v; - Log.e("ETH_v", String.valueOf(v)); + Log.e(TAG,"ETH_v "+ String.valueOf(v)); byte[] txForSend = tx.getEncoded(); notifyOnNeedSendPayment(txForSend); @@ -619,11 +617,11 @@ public class TokenEngine extends CoinEngine { 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"); + Log.e(TAG, "invalid v"); throw new Exception("Error in EthEngine - invalid v"); } tx.signature.v = (byte) v; - Log.e("ETH_v", String.valueOf(v)); + Log.e(TAG,"ETH_v: "+ String.valueOf(v)); byte[] txForSend = tx.getEncoded(); notifyOnNeedSendPayment(txForSend); 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 a4a81817ad..5ab55e0c3c 100644 --- a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt @@ -62,7 +62,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { amount = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_AMOUNT), intent.getStringExtra(Constant.EXTRA_AMOUNT_CURRENCY)) - if (ctx.blockchain == Blockchain.Token && amount.currency != "ETH") + if (ctx.blockchain == Blockchain.Token && amount.currency != Blockchain.Ethereum.currency) tvIncFee.visibility = View.INVISIBLE else tvIncFee.visibility = View.VISIBLE 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 3089050014..faeffdc9a7 100644 --- a/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/PreparePaymentActivity.kt @@ -60,7 +60,7 @@ class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { tvBalance.text = html //TODO - to engine - if (ctx.blockchain == Blockchain.Token && engine.balance.currency!="ETH") { + if (ctx.blockchain == Blockchain.Token && engine.balance.currency!=Blockchain.Ethereum.currency) { rgIncFee!!.visibility = View.INVISIBLE } else { rgIncFee!!.visibility = View.VISIBLE 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 12e814738b..ca23b0aa1d 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -55,6 +55,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import java.io.InputStream import java.util.* +import kotlin.concurrent.timerTask class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener { companion object { @@ -83,14 +84,12 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific set(value) { field = value LOG.i(TAG, "requestCounter, set $field") - if (field <= 0 && srl != null && srl.isRefreshing) { + if (field <= 0) { LOG.e(TAG, "+++++++++++ FINISH REFRESH") - if (srl != null) srl!!.isRefreshing = false + if (srl != null && srl.isRefreshing) srl.isRefreshing = false //updateViews() - } + } else if (srl != null && !srl.isRefreshing) srl.isRefreshing = true } - private var timerRepeatRefresh: Timer? = null - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) nfcManager = NfcManager(activity, this) @@ -279,8 +278,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific override fun onPause() { super.onPause() nfcManager.onPause() - if (timerRepeatRefresh != null) - timerRepeatRefresh!!.cancel() + if (timerHideErrorAndMessage != null) { + timerHideErrorAndMessage!!.cancel() + timerHideErrorAndMessage = null + } } override fun onStart() { @@ -302,7 +303,10 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific @Subscribe fun onTransactionFinishWithSuccess(transactionFinishWithSuccess: TransactionFinishWithSuccess) { ctx.message = transactionFinishWithSuccess.message + ctx.coinData.clearInfo() updateViews() + srl?.isRefreshing=true + srl?.postDelayed({ refresh() }, 5000) } @Subscribe @@ -512,7 +516,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific } fun updateViews() { - if (activity == null || !UtilHelper.isOnline(activity!!)) return + if (activity == null) return if (timerHideErrorAndMessage != null) { timerHideErrorAndMessage!!.cancel() @@ -535,6 +539,21 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific tvMessage.visibility = View.VISIBLE } + if (tvError.visibility == View.VISIBLE || tvMessage.visibility == View.VISIBLE) { + timerHideErrorAndMessage = Timer() + timerHideErrorAndMessage!!.schedule( + timerTask { + activity?.runOnUiThread { + tvMessage?.visibility = View.GONE + tvError?.visibility = View.GONE + // clear only already viewed messages + if (tvMessage.text == ctx.message) ctx.message = null + if (tvError.text == ctx.error) ctx.error = null + } + }, + 5000) + } + if (srl!!.isRefreshing) { tvBalanceLine1.setTextColor(resources.getColor(R.color.primary)) tvBalanceLine1.text = getString(R.string.verifying_in_blockchain) @@ -599,63 +618,61 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific updateViews() + // Bitcoin + // Litecoin + // BitcoinCash + if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || + ctx.blockchain == Blockchain.Litecoin || ctx.blockchain == Blockchain.BitcoinCash) { + ctx.coinData.setIsBalanceEqual(true) + } + requestVerifyAndGetInfo() - val coinEngine = CoinEngineFactory.create(ctx) - requestCounter++ - coinEngine!!.requestBalanceAndUnspentTransactions( - object : CoinEngine.BlockchainRequestsCallbacks { - override fun onComplete(success: Boolean) { - LOG.i(TAG, "requestBalanceAndUnspentTransactions onComplete: " + success.toString() + ", request counter " + requestCounter.toString()) - if (activity == null || !UtilHelper.isOnline(activity!!)) return - requestCounter-- - if (!success) { - LOG.e(TAG, "ctx.error: " + ctx.error) + requestBalanceAndUnspentTransactions() + + requestRateInfo() + + if( requestCounter==0 ) + { + // if no connection and no requests posted + srl?.isRefreshing = false + updateViews() + } + } + + private fun requestBalanceAndUnspentTransactions() { + if (UtilHelper.isOnline(context as Activity)) { + val coinEngine = CoinEngineFactory.create(ctx) + requestCounter++ + coinEngine!!.requestBalanceAndUnspentTransactions( + object : CoinEngine.BlockchainRequestsCallbacks { + override fun onComplete(success: Boolean) { + LOG.i(TAG, "requestBalanceAndUnspentTransactions onComplete: " + success.toString() + ", request counter " + requestCounter.toString()) + if (activity == null) return + requestCounter-- + if (!success) { + LOG.e(TAG, "requestBalanceAndUnspentTransactions ctx.error: " + ctx.error) + } +// if (!UtilHelper.isOnline(activity!!)) { +// ctx.error = getString(R.string.no_connection) +// } + updateViews() + } + + override fun onProgress() { + if (activity == null) return + LOG.i(TAG, "requestBalanceAndUnspentTransactions onProgress") + updateViews() + } + + override fun allowAdvance(): Boolean { + return UtilHelper.isOnline(context as Activity) } - updateViews() } - - override fun onProgress() { - if (activity == null || !UtilHelper.isOnline(activity!!)) return - LOG.i(TAG, "requestBalanceAndUnspentTransactions onProgress") - updateViews() - } - - override fun allowAdvance(): Boolean { - return UtilHelper.isOnline(context as Activity) - } - } - ) - - // TODO - move requestRateInfo to CoinEngine - // Bitcoin - if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet) { - ctx.coinData.setIsBalanceEqual(true) - - requestRateInfo("bitcoin") - } - - // Litecoin - if (ctx.blockchain == Blockchain.Litecoin) { - ctx.coinData.setIsBalanceEqual(true) - - requestRateInfo("litecoin") - } - - // BitcoinCash - else if (ctx.blockchain == Blockchain.BitcoinCash) { - ctx.coinData.setIsBalanceEqual(true) - requestRateInfo("bitcoin-cash") - } - - // Ethereum - else if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet) { - requestRateInfo("ethereum") - } - - // Token - else if (ctx.blockchain == Blockchain.Token) { - requestRateInfo("ethereum") + ) + } else { + ctx.error = getString(R.string.no_connection) + updateViews() } } @@ -667,20 +684,38 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific serverApiTangem.cardVerifyAndGetInfo(ctx.card) } } else { - Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() - LOG.e(TAG, "+++++++++++ Hide refresh 1") - srl?.isRefreshing = false + ctx.error = getString(R.string.no_connection) + updateViews() + //Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() + //LOG.e(TAG, "+++++++++++ Hide refresh 1") + //srl?.isRefreshing = false } } - private fun requestRateInfo(cryptoId: String) { + private fun requestRateInfo() { if (UtilHelper.isOnline(context as Activity)) { LOG.i(TAG, "requestRateInfo") + + // TODO - move requestRateInfo to CoinEngine + val cryptoId: String = when (ctx.blockchain) { + Blockchain.Bitcoin -> "bitcoin" + Blockchain.BitcoinTestNet -> "bitcoin" + Blockchain.Ethereum -> "ethereum" + Blockchain.EthereumTestNet -> "ethereum" + Blockchain.Token -> "ethereum" + Blockchain.BitcoinCash -> "bitcoin-cash" + Blockchain.Litecoin -> "litecoin" + else -> { + throw Exception("Can''t get rate for blockchain " + ctx.blockchainName) + } + } serverApiCommon.rateInfoData(cryptoId) } else { - Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() - LOG.e(TAG, "+++++++++++ Hide refresh 2") - srl?.isRefreshing = false + ctx.error = getString(R.string.no_connection) + updateViews() +// Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() +// LOG.e(TAG, "+++++++++++ Hide refresh 2") +// srl?.isRefreshing = false } }