From e7c57f1e113c41a1386f80d6e431f2c86c9338ce Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Dec 2018 11:50:13 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/data/network/ServerApiInfura.java | 17 + .../com/tangem/domain/wallet/CoinEngine.java | 14 +- .../domain/wallet/bch/BtcCashEngine.java | 8 +- .../tangem/domain/wallet/btc/BtcEngine.java | 174 ++++++++- .../tangem/domain/wallet/eth/EthEngine.java | 136 +++---- .../domain/wallet/token/TokenEngine.java | 115 +++++- .../activity/ConfirmPaymentActivity.kt | 338 ++++++++---------- .../presentation/activity/MainActivity.kt | 8 +- .../presentation/fragment/LoadedWallet.kt | 55 ++- .../tangemserver/android/data/LocalStorage.kt | 2 +- 10 files changed, 530 insertions(+), 337 deletions(-) diff --git a/app/src/main/java/com/tangem/data/network/ServerApiInfura.java b/app/src/main/java/com/tangem/data/network/ServerApiInfura.java index fb8e407099..c6d33242ca 100644 --- a/app/src/main/java/com/tangem/data/network/ServerApiInfura.java +++ b/app/src/main/java/com/tangem/data/network/ServerApiInfura.java @@ -31,6 +31,21 @@ public class ServerApiInfura { public static final String INFURA_ETH_SEND_RAW_TRANSACTION = "eth_sendRawTransaction"; public static final String INFURA_ETH_GAS_PRICE = "eth_gasPrice"; + private int requestsCount=0; + + public boolean hasRequests() { + return requestsCount>0; + } + + private String error=null; + public boolean isErrorOccured() { + return error!=null; + } + + public void setErrorOccured(String error) { + this.error=error; + } + private InfuraBodyListener infuraBodyListener; public interface InfuraBodyListener { @@ -44,6 +59,7 @@ public class ServerApiInfura { } public void infura(String method, int id, String wallet, String contract, String tx) { + requestsCount++; InfuraApi infuraApi = App.getNetworkComponent().getRetrofitInfura().create(InfuraApi.class); InfuraBody infuraBody; @@ -77,6 +93,7 @@ public class ServerApiInfura { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.code() == 200) { + requestsCount--; infuraBodyListener.onSuccess(method, response.body()); Log.i(TAG, "infura " + method + " onResponse " + response.code()); } else { 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 e789f9ffd3..2ad484f4c8 100644 --- a/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/CoinEngine.java @@ -265,11 +265,19 @@ public abstract class CoinEngine { } - - public interface BlockchainRequestsNotifications + public interface BalanceAndUnspentTransactionsNotifications { void onComplete(Boolean success); boolean needTerminate(); } - public abstract void requestBalanceAndUnspentTransactions(BlockchainRequestsNotifications blockchainRequestsNotifications) throws Exception; + public abstract void requestBalanceAndUnspentTransactions(BalanceAndUnspentTransactionsNotifications balanceAndUnspentTransactionsNotifications) throws Exception; + + + public interface FeeRequestsNotifications + { + void onComplete(boolean success, Amount minFee, Amount normalFee, Amount maxFee); + boolean needTerminate(); + } + public abstract void requestFee(FeeRequestsNotifications feeRequestsNotifications, CoinEngine.Amount amount) throws Exception; + } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java b/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java index e104579b68..82656791fd 100644 --- a/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/bch/BtcCashEngine.java @@ -555,7 +555,7 @@ public class BtcCashEngine extends CoinEngine { } @Override - public void requestBalanceAndUnspentTransactions(BlockchainRequestsNotifications blockchainRequestsNotifications) throws Exception { + public void requestBalanceAndUnspentTransactions(BalanceAndUnspentTransactionsNotifications balanceAndUnspentTransactionsNotifications) throws Exception { final ServerApiElectrum serverApiElectrum = new ServerApiElectrum(); ServerApiElectrum.ElectrumRequestDataListener electrumBodyListener = new ServerApiElectrum.ElectrumRequestDataListener() { @@ -607,7 +607,7 @@ public class BtcCashEngine extends CoinEngine { Integer height = jsUnspent.getInt("height"); String hash = jsUnspent.getString("tx_hash"); if (height != -1) { - if (!blockchainRequestsNotifications.needTerminate()) { + if (!balanceAndUnspentTransactionsNotifications.needTerminate()) { serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getTransaction(walletAddress, hash)); } else { serverApiElectrum.setErrorOccured("Terminated by user"); @@ -633,14 +633,14 @@ public class BtcCashEngine extends CoinEngine { } if (!serverApiElectrum.hasRequests()) { - blockchainRequestsNotifications.onComplete(serverApiElectrum.isErrorOccured()); + balanceAndUnspentTransactionsNotifications.onComplete(serverApiElectrum.isErrorOccured()); } } @Override public void onFail(String method) { if (!serverApiElectrum.hasRequests()) { - blockchainRequestsNotifications.onComplete(serverApiElectrum.isErrorOccured()); + balanceAndUnspentTransactionsNotifications.onComplete(serverApiElectrum.isErrorOccured()); } } }; diff --git a/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java b/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java index d71d05ae77..53d97fe589 100644 --- a/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/btc/BtcEngine.java @@ -4,6 +4,7 @@ import android.net.Uri; import android.text.InputFilter; import android.util.Log; +import com.tangem.data.network.ServerApiCommon; import com.tangem.tangemcard.reader.CardProtocol; import com.tangem.domain.wallet.BalanceValidator; import com.tangem.domain.wallet.Base58; @@ -20,6 +21,7 @@ import com.tangem.util.CryptoUtil; import com.tangem.util.DecimalDigitsInputFilter; import com.tangem.util.DerEncodingUtil; import com.tangem.tangemcard.util.Util; +import com.tangem.util.FormatUtil; import com.tangem.wallet.R; import com.tangem.data.network.ElectrumRequest; import com.tangem.data.network.ServerApiElectrum; @@ -32,6 +34,7 @@ import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.math.BigDecimal; import java.math.BigInteger; +import java.math.RoundingMode; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -514,7 +517,7 @@ public class BtcEngine extends CoinEngine { } @Override - public void requestBalanceAndUnspentTransactions(BlockchainRequestsNotifications blockchainRequestsNotifications) { + public void requestBalanceAndUnspentTransactions(BalanceAndUnspentTransactionsNotifications balanceAndUnspentTransactionsNotifications) { final ServerApiElectrum serverApiElectrum = new ServerApiElectrum(); ServerApiElectrum.ElectrumRequestDataListener electrumBodyListener = new ServerApiElectrum.ElectrumRequestDataListener() { @@ -523,8 +526,7 @@ public class BtcEngine extends CoinEngine { if (electrumRequest.isMethod(ElectrumRequest.METHOD_GetBalance)) { try { String walletAddress = electrumRequest.getParams().getString(0); - if( !walletAddress.equals(coinData.getWallet())) - { + if (!walletAddress.equals(coinData.getWallet())) { // todo - check throw new Exception("Invalid wallet address in answer!"); } @@ -537,8 +539,7 @@ public class BtcEngine extends CoinEngine { } catch (JSONException e) { e.printStackTrace(); Log.e(TAG, "FAIL METHOD_GetBalance JSONException"); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "FAIL METHOD_GetBalance Exception"); } @@ -568,9 +569,9 @@ public class BtcEngine extends CoinEngine { Integer height = jsUnspent.getInt("height"); String hash = jsUnspent.getString("tx_hash"); if (height != -1) { - if( !blockchainRequestsNotifications.needTerminate() ) { + if (!balanceAndUnspentTransactionsNotifications.needTerminate()) { serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.getTransaction(walletAddress, hash)); - }else{ + } else { serverApiElectrum.setErrorOccured("Terminated by user"); } } @@ -593,17 +594,15 @@ public class BtcEngine extends CoinEngine { } } - if( !serverApiElectrum.hasRequests() ) - { - blockchainRequestsNotifications.onComplete(serverApiElectrum.isErrorOccured()); + if (!serverApiElectrum.hasRequests()) { + balanceAndUnspentTransactionsNotifications.onComplete(serverApiElectrum.isErrorOccured()); } } @Override public void onFail(String method) { - if( !serverApiElectrum.hasRequests() ) - { - blockchainRequestsNotifications.onComplete(serverApiElectrum.isErrorOccured()); + if (!serverApiElectrum.hasRequests()) { + balanceAndUnspentTransactionsNotifications.onComplete(serverApiElectrum.isErrorOccured()); } } }; @@ -614,7 +613,154 @@ public class BtcEngine extends CoinEngine { serverApiElectrum.electrumRequestData(ctx, ElectrumRequest.listUnspent(coinData.getWallet())); } -// @Override + Integer buildSize(String outputAddress, String outFee, String outAmount) throws Exception { + String myAddress = coinData.getWallet(); + byte[] pbKey = ctx.getCard().getWalletPublicKey(); + byte[] pbComprKey = ctx.getCard().getWalletPublicKeyRar(); + + // build script for our address + List rawTxList = coinData.getUnspentTransactions(); + byte[] outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes; + + // collect unspent + ArrayList unspentOutputs = BTCUtils.getOutputs(rawTxList, outputScriptWeAreAbleToSpend); + + Long fullAmount = 0L; + for (int i = 0; i < unspentOutputs.size(); i++) { + fullAmount += unspentOutputs.get(i).value; + } + + // get first unspent +// val outPut = unspentOutputs[0] +// val outPutIndex = outPut.outputIndex + + // get prev TX id; +// val prevTXID = rawTxList[0].txID//"f67b838d6e2c0c587f476f583843e93ff20368eaf96a798bdc25e01f53f8f5d2"; + + Long fees = FormatUtil.ConvertStringToLong(outFee); + Long amount = FormatUtil.ConvertStringToLong(outAmount); + amount -= fees; + + Long change = fullAmount - fees - amount; + + if (amount + fees > fullAmount) { + throw new Exception(String.format("Balance (%d) < amount (%d) + (%d)", fullAmount, change, amount)); + } + + byte[][] hashesForSign = new byte[unspentOutputs.size()][]; + + for (int i = 0; i < unspentOutputs.size(); i++) { + byte[] newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, myAddress, unspentOutputs, i, amount, change); + byte[] hashData = Util.calculateSHA256(newTX); + byte[] doubleHashData = Util.calculateSHA256(hashData); +// Log.e("TX_BODY_1", BTCUtils.toHex(newTX)) +// Log.e("TX_HASH_1", BTCUtils.toHex(hashData)) +// Log.e("TX_HASH_2", BTCUtils.toHex(doubleHashData)) + +// unspentOutputs[i].bodyDoubleHash = doubleHashData +// unspentOutputs[i].bodyHash = hashData + hashesForSign[i] = doubleHashData; + } + + byte[] signFromCard = new byte[64 * unspentOutputs.size()]; + + for (int i = 0; i < unspentOutputs.size(); i++) { + BigInteger r = new BigInteger(1, Arrays.copyOfRange(signFromCard, 0 + i * 64, 32 + i * 64)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64)); + byte[] encodingSign = DerEncodingUtil.packSignDer(r, s, pbKey); + unspentOutputs.get(i).scriptForBuild = encodingSign; + } + + byte[] realTX = BTCUtils.buildTXForSend(outputAddress, myAddress, unspentOutputs, amount, change); + + return realTX.length; + } + + @Override + public void requestFee(FeeRequestsNotifications feeRequestsNotifications, CoinEngine.Amount amount) throws Exception { +// request estimate fee listener +// int calcSize = 256; +// try { + + final int calcSize = buildSize(coinData.getWallet(), "0.00", amount.toValueString()); +// } catch (Exception ex) { +// Log.e(TAG,"Build Fee error: "+ ex.getMessage()); +// } + + final ServerApiCommon serverApiCommon = new ServerApiCommon(); + + final ServerApiCommon.EstimateFeeListener estimateFeeListener = new ServerApiCommon.EstimateFeeListener() { + @Override + public void onSuccess(int blockCount, String estimateFeeResponse) { + BigDecimal fee = new BigDecimal(estimateFeeResponse); // BTC per 1 kb + + if (fee.equals(BigDecimal.ZERO)) { +// progressBar.visibility = View.INVISIBLE + if( !feeRequestsNotifications.needTerminate()) { + serverApiCommon.estimateFee(blockCount); + } + return; + } + + if (calcSize != 0) { + fee = fee.multiply(new BigDecimal(calcSize)).divide(new BigDecimal(1024)); // per Kb -> per byte + } else { + if( !feeRequestsNotifications.needTerminate()) { + serverApiCommon.estimateFee(blockCount); + } + return; + } + +// progressBar.visibility = View.INVISIBLE + + fee = fee.setScale(8, RoundingMode.DOWN); + + switch (blockCount) { + case ServerApiCommon.ESTIMATE_FEE_MINIMAL: { + CoinEngine.Amount minFee = new CoinEngine.Amount(fee, getFeeCurrency()); + feeRequestsNotifications.onComplete(true, minFee, null, null); +// if (rgFee.checkedRadioButtonId == R.id.rbMinimalFee) doSetFee(rgFee.checkedRadioButtonId) + } + break; + + case ServerApiCommon.ESTIMATE_FEE_NORMAL: { + CoinEngine.Amount normalFee = new CoinEngine.Amount(fee, getFeeCurrency()); + feeRequestsNotifications.onComplete(true, null, normalFee, null); +// if (rgFee.checkedRadioButtonId == R.id.rbNormalFee) doSetFee(rgFee.checkedRadioButtonId) + } + break; + + case ServerApiCommon.ESTIMATE_FEE_PRIORITY: { + CoinEngine.Amount maxFee = new CoinEngine.Amount(fee, getFeeCurrency()); + feeRequestsNotifications.onComplete(true, null, null, maxFee); +// if (rgFee.checkedRadioButtonId == R.id.rbMaximumFee) doSetFee(rgFee.checkedRadioButtonId) + } + } + +// etFee.error = null +// feeRequestSuccess = true +// if (feeRequestSuccess) +// if (feeRequestSuccess && balanceRequestSuccess) +// btnSend.visibility = View.VISIBLE +// dtVerified = Date() + } + + @Override + public void onFail(String message) { + feeRequestsNotifications.onComplete(false, null, null, null); + + } + }; + serverApiCommon.setEstimateFee(estimateFeeListener); + + serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_PRIORITY); + serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_NORMAL); + serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_MINIMAL); + + } + + + // @Override // public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { // // checkBlockchainDataExists(); 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 bf4eeb0c7b..a36467c6a5 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 @@ -1,10 +1,8 @@ package com.tangem.domain.wallet.eth; -import android.app.Activity; import android.net.Uri; import android.text.InputFilter; import android.util.Log; -import android.widget.Toast; import com.tangem.data.network.ServerApiInfura; import com.tangem.data.network.model.InfuraResponse; @@ -12,19 +10,16 @@ import com.tangem.domain.wallet.BalanceValidator; import com.tangem.data.Blockchain; import com.tangem.domain.wallet.CoinData; import com.tangem.domain.wallet.CoinEngine; -import com.tangem.domain.wallet.CoinEngineFactory; import com.tangem.domain.wallet.ECDSASignatureETH; import com.tangem.domain.wallet.EthTransaction; import com.tangem.domain.wallet.Keccak256; import com.tangem.domain.wallet.token.TokenData; -import com.tangem.domain.wallet.token.TokenEngine; import com.tangem.tangemcard.data.TangemCard; import com.tangem.domain.wallet.TangemContext; import com.tangem.domain.wallet.BTCUtils; import com.tangem.tangemcard.tasks.SignTask; import com.tangem.util.CryptoUtil; import com.tangem.util.DecimalDigitsInputFilter; -import com.tangem.util.UtilHelper; import com.tangem.wallet.R; import org.bitcoinj.core.ECKey; @@ -462,7 +457,7 @@ public class EthEngine extends CoinEngine { } @Override - public void requestBalanceAndUnspentTransactions(BlockchainRequestsNotifications blockchainRequestsNotifications) throws Exception { + public void requestBalanceAndUnspentTransactions(BalanceAndUnspentTransactionsNotifications balanceAndUnspentTransactionsNotifications) { final ServerApiInfura serverApiInfura = new ServerApiInfura(); // request infura listener ServerApiInfura.InfuraBodyListener infuraBodyListener = new ServerApiInfura.InfuraBodyListener() { @@ -473,8 +468,8 @@ public class EthEngine extends CoinEngine { String balanceCap = infuraResponse.getResult(); balanceCap = balanceCap.substring(2); BigInteger l = new BigInteger(balanceCap, 16); - BigInteger d = l.divide(new BigInteger("1000000000000000000", 10)); - Long balance = d.longValue(); +// BigInteger d = l.divide(new BigInteger("1000000000000000000", 10)); +// Long balance = d.longValue(); // (ctx.coinData!! as EthData).setBalanceConfirmed(balance) // (ctx.coinData!! as EthData).balanceUnconfirmed = 0L @@ -510,102 +505,71 @@ public class EthEngine extends CoinEngine { // Log.i("$TAG eth_getPendingTxCount", pending) } -// - case ServerApiInfura.INFURA_ETH_CALL: { - try { - String balanceCap = infuraResponse.getResult(); - balanceCap = balanceCap.substring(2); - BigInteger l = new BigInteger(balanceCap, 16); - Long balance = l.longValue(); -// if (l.compareTo(BigInteger.ZERO) == 0) { -// //ctx.card!!.blockchainID = Blockchain.Ethereum.id -// ctx.card!!.addTokenToBlockchainName() -// -// //TODO check -// //ctx.blockchain=lBlockchain.Ethereum -// -// requestCounter-- -// if (requestCounter == 0) srl!!.isRefreshing = false -// -// requestInfura(ServerApiCommon.INFURA_ETH_GET_BALANCE, "") -// requestInfura(ServerApiCommon.INFURA_ETH_GET_TRANSACTION_COUNT, "") -// requestInfura(ServerApiCommon.INFURA_ETH_GET_PENDING_COUNT, "") -// return -// } - coinData.setBalanceInInternalUnits(new CoinEngine.InternalAmount(l, ctx.getCard().tokenSymbol)); - -// Log.i("$TAG eth_call", balanceCap) - - if (!blockchainRequestsNotifications.needTerminate()) { - serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_BALANCE, 67, coinData.getWallet(), "", ""); - serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_TRANSACTION_COUNT, 67, coinData.getWallet(), "", ""); - serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_PENDING_COUNT, 67, coinData.getWallet(), "", ""); - } else { - serverApiInfura.setErrorOccured("Terminated by user"); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - -// ServerApiInfura.INFURA_ETH_SEND_RAW_TRANSACTION -> { -// try { -// var hashTX: String -// try { -// val tmp = infuraResponse.result -// hashTX = tmp -// } catch (e: JSONException) { -// return -// } -// -// if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) { -// hashTX = hashTX.substring(2) -// } -// -// Log.e("$TAG TX_RESULT", hashTX) -// -// val nonce = (ctx.coinData!! as EthData).confirmedTXCount -// nonce.add(BigInteger.valueOf(1)) -// (ctx.coinData!! as EthData).confirmedTXCount = nonce -// -// Log.e("$TAG TX_RESULT", hashTX) -// -// } catch (e: Exception) { -// e.printStackTrace() -// } -// } } -// -// counterMinus() + if (!serverApiInfura.hasRequests()) { - blockchainRequestsNotifications.onComplete(serverApiInfura.isErrorOccured()); + balanceAndUnspentTransactionsNotifications.onComplete(serverApiInfura.isErrorOccured()); } } @Override public void onFail(String method, String message) { if (!serverApiInfura.hasRequests()) { - blockchainRequestsNotifications.onComplete(serverApiInfura.isErrorOccured()); + balanceAndUnspentTransactionsNotifications.onComplete(serverApiInfura.isErrorOccured()); } } }; serverApiInfura.setInfuraResponse(infuraBodyListener); - if (ctx.getBlockchain() == Blockchain.Ethereum || ctx.getBlockchain() == Blockchain.EthereumTestNet) { serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_BALANCE, 67, coinData.getWallet(), "", ""); serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_TRANSACTION_COUNT, 67, coinData.getWallet(), "", ""); serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_PENDING_COUNT, 67, coinData.getWallet(), "", ""); - } + } - // Token - else if (ctx.getBlockchain() == Blockchain.Token) { - final CoinEngine engine = CoinEngineFactory.INSTANCE.create(ctx); - serverApiInfura.infura(ServerApiInfura.INFURA_ETH_CALL, 67, coinData.getWallet(), ((TokenEngine) engine).getContractAddress(ctx.getCard()), ""); - } + @Override + public void requestFee(FeeRequestsNotifications feeRequestsNotifications, CoinEngine.Amount amount) throws Exception { + ServerApiInfura serverApiInfura = new ServerApiInfura(); + // request infura eth gasPrice listener + ServerApiInfura.InfuraBodyListener infuraBodyListener = new ServerApiInfura.InfuraBodyListener() { + @Override + public void onSuccess(String method, InfuraResponse infuraResponse) { + if(method== ServerApiInfura.INFURA_ETH_GAS_PRICE) + { + String gasPrice = infuraResponse.getResult(); + gasPrice = gasPrice.substring(2); + // rounding gas price to integer gwei + BigInteger l = new BigInteger(gasPrice, 16).divide(BigInteger.valueOf(1000000000L)).multiply(BigInteger.valueOf(1000000000L)); + //val m = if (ctx.blockchain==Blockchain.Token) BigInteger.valueOf(60000) else BigInteger.valueOf(21000) + BigInteger m; + if (amount.getCurrency().equals("ETH")) m = BigInteger.valueOf(60000); + else m = BigInteger.valueOf(21000); -// @Override + CoinEngine.InternalAmount weiMinFee = new CoinEngine.InternalAmount(l.multiply(m), "wei"); + CoinEngine.InternalAmount weiNormalFee = new CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(12)).divide(BigDecimal.valueOf(10)), "wei"); + CoinEngine.InternalAmount weiMaxFee = new CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(15)).divide(BigDecimal.valueOf(10)), "wei"); + + CoinEngine.Amount minFee = convertToAmount(weiMinFee); + CoinEngine.Amount normalFee = convertToAmount(weiNormalFee); + CoinEngine.Amount maxFee = convertToAmount(weiMaxFee); + feeRequestsNotifications.onComplete(true, minFee, normalFee, maxFee); + } + + } + + @Override + public void onFail(String method, String message) { + if( method==ServerApiInfura.INFURA_ETH_GAS_PRICE ){ + feeRequestsNotifications.onComplete(false, null, null, null); + } + } + }; + serverApiInfura.setInfuraResponse(infuraBodyListener); + + serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GAS_PRICE, 67, coinData.getWallet(), "", ""); + } + + // @Override // public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { // // BigInteger nonceValue = coinData.getConfirmedTXCount(); @@ -668,4 +632,4 @@ public class EthEngine extends CoinEngine { // byte[] realTX = tx.getEncoded(); // return realTX; // } - } +} 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 3e0a8d00c2..ee00616785 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 @@ -5,6 +5,9 @@ import android.text.InputFilter; import android.util.Log; import com.google.common.base.Strings; +import com.tangem.data.Blockchain; +import com.tangem.data.network.ServerApiInfura; +import com.tangem.data.network.model.InfuraResponse; import com.tangem.domain.wallet.BalanceValidator; import com.tangem.domain.wallet.CoinData; import com.tangem.domain.wallet.CoinEngine; @@ -430,11 +433,6 @@ public class TokenEngine extends CoinEngine { } } - @Override - public void requestBalanceAndUnspentTransactions(BlockchainRequestsNotifications blockchainRequestsNotifications) throws Exception { - //TODO("NOT IMPLEMENTED") - } - // @Override // public byte[] sign(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { // if (amountValue.getCurrency().equals("ETH")) { @@ -629,6 +627,113 @@ public class TokenEngine extends CoinEngine { } + @Override + public void requestBalanceAndUnspentTransactions(BalanceAndUnspentTransactionsNotifications balanceAndUnspentTransactionsNotifications) { + final ServerApiInfura serverApiInfura = new ServerApiInfura(); + // request infura listener + ServerApiInfura.InfuraBodyListener infuraBodyListener = new ServerApiInfura.InfuraBodyListener() { + @Override + public void onSuccess(String method, InfuraResponse infuraResponse) { + switch (method) { + case ServerApiInfura.INFURA_ETH_GET_BALANCE: { + String balanceCap = infuraResponse.getResult(); + balanceCap = balanceCap.substring(2); + BigInteger l = new BigInteger(balanceCap, 16); +// BigInteger d = l.divide(new BigInteger("1000000000000000000", 10)); +// Long balance = d.longValue(); + +// (ctx.coinData!! as EthData).setBalanceConfirmed(balance) +// (ctx.coinData!! as EthData).balanceUnconfirmed = 0L + if (ctx.getBlockchain() != Blockchain.Token) { + coinData.setBalanceReceived(true); + coinData.setBalanceInInternalUnits(new CoinEngine.InternalAmount(l, "wei")); + } else { + coinData.setBalanceReceived(true); + //(ctx.coinData!! as TokenData).balanceInInternalUnits = CoinEngine.InternalAmount(l.toBigDecimal(),ctx.card.tokenSymbol) + ((TokenData) coinData).setBalanceAlterInInternalUnits(new CoinEngine.InternalAmount(l, "wei")); + } + +// Log.i("$TAG eth_get_balance", balanceCap) + } + break; + + case ServerApiInfura.INFURA_ETH_GET_TRANSACTION_COUNT: { + String nonce = infuraResponse.getResult(); + nonce = nonce.substring(2); + BigInteger count = new BigInteger(nonce, 16); + coinData.setConfirmedTXCount(count); + + +// Log.i("$TAG eth_getTransCount", nonce) + } + break; + + case ServerApiInfura.INFURA_ETH_GET_PENDING_COUNT: { + String pending = infuraResponse.getResult(); + pending = pending.substring(2); + BigInteger count = new BigInteger(pending, 16); + coinData.setUnconfirmedTXCount(count); + +// Log.i("$TAG eth_getPendingTxCount", pending) + } +// + case ServerApiInfura.INFURA_ETH_CALL: { + try { + String balanceCap = infuraResponse.getResult(); + balanceCap = balanceCap.substring(2); + BigInteger l = new BigInteger(balanceCap, 16); + Long balance = l.longValue(); +// if (l.compareTo(BigInteger.ZERO) == 0) { +// //ctx.card!!.blockchainID = Blockchain.Ethereum.id +// ctx.card!!.addTokenToBlockchainName() +// +// //TODO check +// //ctx.blockchain=lBlockchain.Ethereum +// +// requestCounter-- +// if (requestCounter == 0) srl!!.isRefreshing = false +// +// requestInfura(ServerApiCommon.INFURA_ETH_GET_BALANCE, "") +// requestInfura(ServerApiCommon.INFURA_ETH_GET_TRANSACTION_COUNT, "") +// requestInfura(ServerApiCommon.INFURA_ETH_GET_PENDING_COUNT, "") +// return +// } + coinData.setBalanceInInternalUnits(new CoinEngine.InternalAmount(l, ctx.getCard().tokenSymbol)); + +// Log.i("$TAG eth_call", balanceCap) + + if (!balanceAndUnspentTransactionsNotifications.needTerminate()) { + serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_BALANCE, 67, coinData.getWallet(), "", ""); + serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_TRANSACTION_COUNT, 67, coinData.getWallet(), "", ""); + serverApiInfura.infura(ServerApiInfura.INFURA_ETH_GET_PENDING_COUNT, 67, coinData.getWallet(), "", ""); + } else { + serverApiInfura.setErrorOccured("Terminated by user"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + if (!serverApiInfura.hasRequests()) { + balanceAndUnspentTransactionsNotifications.onComplete(serverApiInfura.isErrorOccured()); + } + } + + @Override + public void onFail(String method, String message) { + if (!serverApiInfura.hasRequests()) { + balanceAndUnspentTransactionsNotifications.onComplete(serverApiInfura.isErrorOccured()); + } + } + }; + serverApiInfura.setInfuraResponse(infuraBodyListener); + + serverApiInfura.infura(ServerApiInfura.INFURA_ETH_CALL, 67, coinData.getWallet(), getContractAddress(ctx.getCard()), ""); + } + + // public byte[] signETH(Amount feeValue, Amount amountValue, boolean IncFee, String targetAddress, CardProtocol protocol) throws Exception { // BigInteger nonceValue = coinData.getConfirmedTXCount(); // byte[] pbKey = ctx.getCard().getWalletPublicKey(); 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 93dc3ab3af..df26fa1b02 100644 --- a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.kt @@ -42,15 +42,15 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { private var nfcManager: NfcManager? = null - private var serverApiCommon: ServerApiCommon = ServerApiCommon() - private var serverApiInfura: ServerApiInfura = ServerApiInfura() - private var serverApiElectrum: ServerApiElectrum = ServerApiElectrum() +// private var serverApiCommon: ServerApiCommon = ServerApiCommon() +// private var serverApiInfura: ServerApiInfura = ServerApiInfura() +// private var serverApiElectrum: ServerApiElectrum = ServerApiElectrum() private lateinit var ctx: TangemContext private lateinit var amount: CoinEngine.Amount private var feeRequestSuccess = false -// private var balanceRequestSuccess = false + // private var balanceRequestSuccess = false private var minFee: CoinEngine.Amount? = null private var maxFee: CoinEngine.Amount? = null private var normalFee: CoinEngine.Amount? = null @@ -58,7 +58,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { private var requestPIN2Count = 0 private var nodeCheck = true private var dtVerified: Date? = null - private var calcSize: Int = 0 +// private var calcSize: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -84,7 +84,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { amount = CoinEngine.Amount(intent.getStringExtra(SignPaymentActivity.EXTRA_AMOUNT), intent.getStringExtra(SignPaymentActivity.EXTRA_AMOUNT_CURRENCY)) - if (ctx.blockchain == Blockchain.Token && amount.currency!="ETH") + if (ctx.blockchain == Blockchain.Token && amount.currency != "ETH") tvIncFee.visibility = View.INVISIBLE else tvIncFee.visibility = View.VISIBLE @@ -103,7 +103,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { if (ctx.blockchain == Blockchain.Ethereum || ctx.blockchain == Blockchain.EthereumTestNet || ctx.blockchain == Blockchain.Token) { rgFee.isEnabled = false - requestInfura(ServerApiInfura.INFURA_ETH_GAS_PRICE) +// requestInfura(ServerApiInfura.INFURA_ETH_GAS_PRICE) } else { rgFee.isEnabled = true @@ -114,7 +114,7 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { progressBar.visibility = View.VISIBLE - requestEstimateFee() +// requestEstimateFee() } // set listeners @@ -192,6 +192,33 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2) } + val coinEngine = CoinEngineFactory.create(ctx) + coinEngine!!.requestFee( + object : CoinEngine.FeeRequestsNotifications { + override fun onComplete(success: Boolean, minFee: CoinEngine.Amount?, normalFee: CoinEngine.Amount?, maxFee: CoinEngine.Amount?) { + if (success) { + this@ConfirmPaymentActivity.minFee = minFee + this@ConfirmPaymentActivity.normalFee = normalFee + this@ConfirmPaymentActivity.maxFee = maxFee + doSetFee(rgFee.checkedRadioButtonId) + etFee.error = null + btnSend.visibility = View.VISIBLE + feeRequestSuccess = true +// balanceRequestSuccess = true + dtVerified = Date() + } else { + finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) + } + } + + override fun needTerminate(): Boolean { + return !UtilHelper.isOnline(this@ConfirmPaymentActivity) + } + }, + amount + ) + + // request electrum listener // val electrumBodyListener: ServerApiHelperElectrum.ElectrumRequestDataListener = object : ServerApiHelperElectrum.ElectrumRequestDataListener { // override fun onSuccess(electrumRequest: ElectrumRequest?) { @@ -227,97 +254,97 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { // serverApiHelperElectrum.setElectrumRequestData(electrumBodyListener) // request infura eth gasPrice listener - val infuraBodyListener: ServerApiInfura.InfuraBodyListener = object : ServerApiInfura.InfuraBodyListener { - override fun onSuccess(method: String, infuraResponse: InfuraResponse) { - when (method) { - ServerApiInfura.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)) +// val infuraBodyListener: ServerApiInfura.InfuraBodyListener = object : ServerApiInfura.InfuraBodyListener { +// override fun onSuccess(method: String, infuraResponse: InfuraResponse) { +// when (method) { +// ServerApiInfura.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)) +// +// //val m = if (ctx.blockchain==Blockchain.Token) BigInteger.valueOf(60000) else BigInteger.valueOf(21000) +// val m = if (amount.currency != "ETH") BigInteger.valueOf(60000) else BigInteger.valueOf(21000) +// val weiMinFee = CoinEngine.InternalAmount(l.multiply(m), "wei") +// val weiNormalFee = CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(12)).divide(BigDecimal.valueOf(10)), "wei") +// val weiMaxFee = CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(15)).divide(BigDecimal.valueOf(10)), "wei") +// +// minFee = engine.convertToAmount(weiMinFee) +// normalFee = engine.convertToAmount(weiNormalFee) +// maxFee = engine.convertToAmount(weiMaxFee) +// doSetFee(rgFee.checkedRadioButtonId) +// //etFee.setText(weiNormalFee.toValueString()) +// etFee.error = null +// btnSend.visibility = View.VISIBLE +// feeRequestSuccess = true +//// balanceRequestSuccess = true +// dtVerified = Date() +// } +// } +// } +// +// override fun onFail(method: String, message: String) { +// when (method) { +// ServerApiInfura.INFURA_ETH_GAS_PRICE -> { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) +// } +// } +// } +// } +// serverApiInfura.setInfuraResponse(infuraBodyListener) - //val m = if (ctx.blockchain==Blockchain.Token) BigInteger.valueOf(60000) else BigInteger.valueOf(21000) - val m = if (amount.currency != "ETH") BigInteger.valueOf(60000) else BigInteger.valueOf(21000) - val weiMinFee = CoinEngine.InternalAmount(l.multiply(m), "wei") - val weiNormalFee = CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(12)).divide(BigDecimal.valueOf(10)), "wei") - val weiMaxFee = CoinEngine.InternalAmount(weiMinFee.multiply(BigDecimal.valueOf(15)).divide(BigDecimal.valueOf(10)), "wei") - - minFee = engine.convertToAmount(weiMinFee) - normalFee = engine.convertToAmount(weiNormalFee) - maxFee = engine.convertToAmount(weiMaxFee) - doSetFee(rgFee.checkedRadioButtonId) - //etFee.setText(weiNormalFee.toValueString()) - etFee.error = null - btnSend.visibility = View.VISIBLE - feeRequestSuccess = true -// balanceRequestSuccess = true - dtVerified = Date() - } - } - } - - override fun onFail(method: String, message: String) { - when (method) { - ServerApiInfura.INFURA_ETH_GAS_PRICE -> { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) - } - } - } - } - serverApiInfura.setInfuraResponse(infuraBodyListener) - - // request estimate fee listener - val estimateFeeListener: ServerApiCommon.EstimateFeeListener = object : ServerApiCommon.EstimateFeeListener { - override fun onSuccess(blockCount: Int, estimateFeeResponse: String?) { - var fee: BigDecimal? - fee = BigDecimal(estimateFeeResponse) // BTC per 1 kb - - if (fee == BigDecimal.ZERO) { - progressBar.visibility = View.INVISIBLE - requestEstimateFee() - } - - if (calcSize.toLong() != 0L) { - fee = fee.multiply(BigDecimal(calcSize.toLong())).divide(BigDecimal(1024)) // per Kb -> per byte - } else { - requestEstimateFee() - } - - progressBar.visibility = View.INVISIBLE - - fee = fee!!.setScale(8, RoundingMode.DOWN) - - when (blockCount) { - ServerApiCommon.ESTIMATE_FEE_MINIMAL -> { - minFee = CoinEngine.Amount(fee, engine.feeCurrency) - if (rgFee.checkedRadioButtonId == R.id.rbMinimalFee) doSetFee(rgFee.checkedRadioButtonId) - } - - ServerApiCommon.ESTIMATE_FEE_NORMAL -> { - normalFee = CoinEngine.Amount(fee, engine.feeCurrency) - if (rgFee.checkedRadioButtonId == R.id.rbNormalFee) doSetFee(rgFee.checkedRadioButtonId) - } - - ServerApiCommon.ESTIMATE_FEE_PRIORITY -> { - maxFee = CoinEngine.Amount(fee, engine.feeCurrency) - if (rgFee.checkedRadioButtonId == R.id.rbMaximumFee) doSetFee(rgFee.checkedRadioButtonId) - } - } - - etFee.error = null - feeRequestSuccess = true - if (feeRequestSuccess) -// if (feeRequestSuccess && balanceRequestSuccess) - btnSend.visibility = View.VISIBLE - dtVerified = Date() - } - - override fun onFail(message: String?) { - finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_calculate_fee_wrong_data_received_from_node)) - } - } - serverApiCommon.setEstimateFee(estimateFeeListener) +// // request estimate fee listener +// val estimateFeeListener: ServerApiCommon.EstimateFeeListener = object : ServerApiCommon.EstimateFeeListener { +// override fun onSuccess(blockCount: Int, estimateFeeResponse: String?) { +// var fee: BigDecimal? +// fee = BigDecimal(estimateFeeResponse) // BTC per 1 kb +// +// if (fee == BigDecimal.ZERO) { +// progressBar.visibility = View.INVISIBLE +// requestEstimateFee() +// } +// +// if (calcSize.toLong() != 0L) { +// fee = fee.multiply(BigDecimal(calcSize.toLong())).divide(BigDecimal(1024)) // per Kb -> per byte +// } else { +// requestEstimateFee() +// } +// +// progressBar.visibility = View.INVISIBLE +// +// fee = fee!!.setScale(8, RoundingMode.DOWN) +// +// when (blockCount) { +// ServerApiCommon.ESTIMATE_FEE_MINIMAL -> { +// minFee = CoinEngine.Amount(fee, engine.feeCurrency) +// if (rgFee.checkedRadioButtonId == R.id.rbMinimalFee) doSetFee(rgFee.checkedRadioButtonId) +// } +// +// ServerApiCommon.ESTIMATE_FEE_NORMAL -> { +// normalFee = CoinEngine.Amount(fee, engine.feeCurrency) +// if (rgFee.checkedRadioButtonId == R.id.rbNormalFee) doSetFee(rgFee.checkedRadioButtonId) +// } +// +// ServerApiCommon.ESTIMATE_FEE_PRIORITY -> { +// maxFee = CoinEngine.Amount(fee, engine.feeCurrency) +// if (rgFee.checkedRadioButtonId == R.id.rbMaximumFee) doSetFee(rgFee.checkedRadioButtonId) +// } +// } +// +// etFee.error = null +// feeRequestSuccess = true +// if (feeRequestSuccess) +//// if (feeRequestSuccess && balanceRequestSuccess) +// btnSend.visibility = View.VISIBLE +// dtVerified = Date() +// } +// +// override fun onFail(message: String?) { +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_calculate_fee_wrong_data_received_from_node)) +// } +// } +// serverApiCommon.setEstimateFee(estimateFeeListener) } public override fun onResume() { @@ -394,98 +421,35 @@ class ConfirmPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback { // TODO - move to BtcEngine @Throws(Exception::class) - internal fun buildSize(outputAddress: String, outFee: String, outAmount: String): Int { - val myAddress = ctx.coinData!!.wallet - val pbKey = ctx.card!!.walletPublicKey - val pbComprKey = ctx.card!!.walletPublicKeyRar - // build script for our address - val rawTxList = (ctx.coinData!! as BtcData).unspentTransactions - val outputScriptWeAreAbleToSpend = Transaction.Script.buildOutput(myAddress).bytes +// private fun requestElectrum(ctx: TangemContext, electrumRequest: ElectrumRequest) { +// if (UtilHelper.isOnline(this)) { +// serverApiElectrum.electrumRequestData(ctx, electrumRequest) +// } else +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) +// } - // collect unspent - val unspentOutputs = BTCUtils.getOutputs(rawTxList, outputScriptWeAreAbleToSpend) +// private fun requestInfura(method: String) { +// if (UtilHelper.isOnline(this)) { +// serverApiInfura.infura(method, 67, ctx.coinData!!.wallet, "", "") +// } else +// finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) +// } - var fullAmount: Long = 0 - for (i in unspentOutputs.indices) { - fullAmount += unspentOutputs[i].value - } - - // get first unspent -// val outPut = unspentOutputs[0] -// val outPutIndex = outPut.outputIndex - - // get prev TX id; -// val prevTXID = rawTxList[0].txID//"f67b838d6e2c0c587f476f583843e93ff20368eaf96a798bdc25e01f53f8f5d2"; - - val fees = FormatUtil.ConvertStringToLong(outFee) - var amount = FormatUtil.ConvertStringToLong(outAmount) - amount -= fees - - val change = fullAmount - fees - amount - - if (amount + fees > fullAmount) { - throw Exception(String.format("Balance (%d) < amount (%d) + (%d)", fullAmount, change, amount)) - } - - val hashesForSign = arrayOfNulls(unspentOutputs.size) - - for (i in unspentOutputs.indices) { - val newTX = BTCUtils.buildTXForSign(myAddress, outputAddress, myAddress, unspentOutputs, i, amount, change) - val hashData = Util.calculateSHA256(newTX) - val doubleHashData = Util.calculateSHA256(hashData) -// Log.e("TX_BODY_1", BTCUtils.toHex(newTX)) -// Log.e("TX_HASH_1", BTCUtils.toHex(hashData)) -// Log.e("TX_HASH_2", BTCUtils.toHex(doubleHashData)) - -// unspentOutputs[i].bodyDoubleHash = doubleHashData -// unspentOutputs[i].bodyHash = hashData - hashesForSign[i] = doubleHashData - } - - val signFromCard = ByteArray(64 * unspentOutputs.size) - - for (i in unspentOutputs.indices) { - val r = BigInteger(1, Arrays.copyOfRange(signFromCard, 0 + i * 64, 32 + i * 64)) - val s = BigInteger(1, Arrays.copyOfRange(signFromCard, 32 + i * 64, 64 + i * 64)) - val encodingSign = DerEncodingUtil.packSignDer(r, s, pbKey) - unspentOutputs[i].scriptForBuild = encodingSign - } - - val realTX = BTCUtils.buildTXForSend(outputAddress, myAddress, unspentOutputs, amount, change) - - return realTX.size - } - - private fun requestElectrum(ctx: TangemContext, electrumRequest: ElectrumRequest) { - if (UtilHelper.isOnline(this)) { - serverApiElectrum.electrumRequestData(ctx, electrumRequest) - } else - finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) - } - - private fun requestInfura(method: String) { - if (UtilHelper.isOnline(this)) { - serverApiInfura.infura(method, 67, ctx.coinData!!.wallet, "", "") - } else - finishWithError(Activity.RESULT_CANCELED, getString(R.string.cannot_obtain_data_from_blockchain)) - } - - private fun requestEstimateFee() { - if( calcSize==0 ) - { - calcSize = 256 - try { - - calcSize = buildSize(etWallet!!.text.toString(), "0.00", etAmount.text.toString()) - } catch (ex: Exception) { - Log.e("Build Fee error", ex.message) - } - } - serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_PRIORITY) - serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_NORMAL) - serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_MINIMAL) - } +// private fun requestEstimateFee() { +// if (calcSize == 0) { +// calcSize = 256 +// try { +// +// calcSize = buildSize(etWallet!!.text.toString(), "0.00", etAmount.text.toString()) +// } catch (ex: Exception) { +// Log.e("Build Fee error", ex.message) +// } +// } +// serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_PRIORITY) +// serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_NORMAL) +// serverApiCommon.estimateFee(ServerApiCommon.ESTIMATE_FEE_MINIMAL) +// } private fun doSetFee(checkedRadioButtonId: Int) { var txtFee = "" diff --git a/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt b/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt index 86e7dbe7d3..7a9f10344d 100644 --- a/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt +++ b/app/src/main/java/com/tangem/presentation/activity/MainActivity.kt @@ -271,7 +271,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco } catch (e: Exception) { e.printStackTrace() - nfcManager!!.notifyReadResult(false) + nfcManager.notifyReadResult(false) } } @@ -279,11 +279,11 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco super.onResume() animate() ReadCardInfoTask.resetLastReadInfo() - nfcManager!!.onResume() + nfcManager.onResume() } public override fun onPause() { - nfcManager!!.onPause() + nfcManager.onPause() if (readCardInfoTask != null) { readCardInfoTask!!.cancel(true) } @@ -292,7 +292,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco public override fun onStop() { // dismiss enable NFC dialog - nfcManager!!.onStop() + nfcManager.onStop() if (readCardInfoTask != null) { readCardInfoTask!!.cancel(true) } 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 a3779a6d78..48ccfa9006 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -22,24 +22,17 @@ import android.widget.Toast import com.tangem.App import com.tangem.Constant import com.tangem.data.network.ServerApiCommon -import com.tangem.data.network.ServerApiInfura import com.tangem.tangemserver.android.model.CardVerifyAndGetInfo -import com.tangem.data.network.model.InfuraResponse import com.tangem.tangemcard.tasks.VerifyCardTask import com.tangem.tangemcard.reader.CardProtocol import com.tangem.tangemcard.android.reader.NfcManager import com.tangem.domain.wallet.* -import com.tangem.domain.wallet.bch.BtcCashEngine -import com.tangem.domain.wallet.eth.EthData -import com.tangem.domain.wallet.token.TokenData -import com.tangem.domain.wallet.token.TokenEngine import com.tangem.presentation.activity.* import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog import com.tangem.presentation.dialog.PINSwapWarningDialog import com.tangem.presentation.dialog.ShowQRCodeDialog import com.tangem.presentation.dialog.WaitSecurityDelayDialog import com.tangem.data.Blockchain -import com.tangem.data.network.ElectrumRequest import com.tangem.tangemcard.android.reader.NfcReader import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD_UID @@ -50,9 +43,7 @@ import com.tangem.tangemserver.android.ServerApiTangem import com.tangem.util.UtilHelper import com.tangem.wallet.R import kotlinx.android.synthetic.main.fr_loaded_wallet.* -import org.json.JSONException import java.io.InputStream -import java.math.BigInteger import java.util.* class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener { @@ -802,23 +793,21 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific requestVerifyAndGetInfo() - if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || ctx.blockchain == Blockchain.BitcoinCash) { - val coinEngine = CoinEngineFactory.create(ctx) - requestCounter++ - coinEngine!!.requestBalanceAndUnspentTransactions( - object : CoinEngine.BlockchainRequestsNotifications { - override fun onComplete(success: Boolean?) { - counterMinus() - updateViews() - } - - override fun needTerminate(): Boolean { - return !UtilHelper.isOnline(context as Activity) - } + val coinEngine = CoinEngineFactory.create(ctx) + requestCounter++ + coinEngine!!.requestBalanceAndUnspentTransactions( + object : CoinEngine.BalanceAndUnspentTransactionsNotifications { + override fun onComplete(success: Boolean?) { + counterMinus() + updateViews() } - ) - } + override fun needTerminate(): Boolean { + return !UtilHelper.isOnline(context as Activity) + } + } + ) + // Bitcoin if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet) { @@ -865,15 +854,15 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific // } // } - private fun requestInfura(method: String, contract: String) { - if (UtilHelper.isOnline(context as Activity)) { - requestCounter++ - serverApiInfura.infura(method, 67, ctx.coinData!!.wallet, contract, "") - } else { - Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() - srl?.isRefreshing = false - } - } +// private fun requestInfura(method: String, contract: String) { +// if (UtilHelper.isOnline(context as Activity)) { +// requestCounter++ +// serverApiInfura.infura(method, 67, ctx.coinData!!.wallet, contract, "") +// } else { +// Toast.makeText(activity, getString(R.string.no_connection), Toast.LENGTH_SHORT).show() +// srl?.isRefreshing = false +// } +// } private fun requestVerifyAndGetInfo() { if (UtilHelper.isOnline(context as Activity)) { diff --git a/tangemserver-android/src/main/java/com/tangem/tangemserver/android/data/LocalStorage.kt b/tangemserver-android/src/main/java/com/tangem/tangemserver/android/data/LocalStorage.kt index 009c26bb75..426ac14e0e 100644 --- a/tangemserver-android/src/main/java/com/tangem/tangemserver/android/data/LocalStorage.kt +++ b/tangemserver-android/src/main/java/com/tangem/tangemserver/android/data/LocalStorage.kt @@ -112,7 +112,7 @@ class LocalStorage var sData: String? = result.substitution?.data var sSignature: String? = result.substitution?.signature if (card.batch != result.batch) { - Log.e("CardDataSubstitutionProvider", "Invalid batch received!") + Log.e("CardDataSubstitution", "Invalid batch received!") return false } if (!BatchInfo.CardDataSubstitution.verifySignature(card, sData, sSignature)) {