diff --git a/app/src/main/java/com/tangem/data/network/request/ElectrumRequest.java b/app/src/main/java/com/tangem/data/network/request/ElectrumRequest.java index cabe3dfe88..9f8e9d24e5 100644 --- a/app/src/main/java/com/tangem/data/network/request/ElectrumRequest.java +++ b/app/src/main/java/com/tangem/data/network/request/ElectrumRequest.java @@ -22,6 +22,7 @@ public class ElectrumRequest { public String error; public String WalletAddress; public String TxHash; + public String TX; public String Host; public int Port; @@ -125,6 +126,7 @@ public class ElectrumRequest { ElectrumRequest request = new ElectrumRequest(); try { request.WalletAddress=wallet; + request.TX=tx; request.jsRequestData = new JSONObject("{ \"method\":\"" + METHOD_SendTransaction + "\", \"params\":[\"" + tx + "\"] }"); } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/com/tangem/data/network/task/send_transaction/ConnectTask.java b/app/src/main/java/com/tangem/data/network/task/send_transaction/ConnectTask.java index c85696de48..7bba59cca9 100644 --- a/app/src/main/java/com/tangem/data/network/task/send_transaction/ConnectTask.java +++ b/app/src/main/java/com/tangem/data/network/task/send_transaction/ConnectTask.java @@ -9,6 +9,7 @@ import com.tangem.domain.wallet.CoinEngine; import com.tangem.domain.wallet.CoinEngineFactory; import com.tangem.domain.wallet.LastSignStorage; import com.tangem.domain.wallet.SharedData; +import com.tangem.domain.wallet.TangemCard; import com.tangem.presentation.activity.SendTransactionActivity; import org.json.JSONException; @@ -19,15 +20,46 @@ import java.util.List; public class ConnectTask extends ElectrumTask { private WeakReference reference; + private int remaining_attempts; - public ConnectTask(SendTransactionActivity context, String host, int port) { - super(host, port); - reference = new WeakReference<>(context); + + private void CreateChildTask (TangemCard mCard, String tx, String error_message) { + + if (remaining_attempts > 0) { + + remaining_attempts--; + + CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain()); + + if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) { + String nodeAddress = engine.GetNode(mCard); + int nodePort = engine.GetNodePort(mCard); + ConnectTask connectTask = new ConnectTask(reference.get(), nodeAddress, nodePort, remaining_attempts); + connectTask.execute(ElectrumRequest.Broadcast(mCard.getWallet(), tx)); + } else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) { + String nodeAddress = engine.GetNode(mCard); + int nodePort = engine.GetNodePort(mCard); + ConnectTask connectTask = new ConnectTask(reference.get(), nodeAddress, nodePort,remaining_attempts); + connectTask.execute(ElectrumRequest.Broadcast(mCard.getWallet(), tx)); + } + + } else { + reference.get().finishWithError(error_message); + } } - public ConnectTask(SendTransactionActivity context, String host, int port, SharedData sharedData) { + + + public ConnectTask(SendTransactionActivity context, String host, int port, int attempts) { + super(host, port); + reference = new WeakReference<>(context); + remaining_attempts = attempts; + } + + public ConnectTask(SendTransactionActivity context, String host, int port, int attempts, SharedData sharedData) { super(host, port, sharedData); reference = new WeakReference<>(context); + remaining_attempts = attempts; } @Override @@ -61,24 +93,27 @@ public class ConnectTask extends ElectrumTask { sendTransactionActivity.finishWithSuccess(); } catch (Exception e) { engine.SwitchNode(null); - sendTransactionActivity.finishWithError(hashTX); - return; +// sendTransactionActivity.finishWithError(hashTX); + CreateChildTask(sendTransactionActivity.mCard, request.TX, hashTX); } } catch (JSONException e) { e.printStackTrace(); engine.SwitchNode(null); - sendTransactionActivity.finishWithError(e.toString()); +// sendTransactionActivity.finishWithError(e.toString()); + CreateChildTask(sendTransactionActivity.mCard, request.TX, e.toString()); } } - } else if (request.error != null) { + } else { engine.SwitchNode(null); - sendTransactionActivity.finishWithError(request.error); +// sendTransactionActivity.finishWithError(request.error); + CreateChildTask(sendTransactionActivity.mCard, request.TX, request.error); } } catch (JSONException e) { e.printStackTrace(); engine.SwitchNode(null); - sendTransactionActivity.finishWithError(e.toString()); +// sendTransactionActivity.finishWithError(e.toString()); + CreateChildTask(sendTransactionActivity.mCard, request.TX, e.toString()); } } } diff --git a/app/src/main/java/com/tangem/data/network/task/send_transaction/ETHRequestTask.java b/app/src/main/java/com/tangem/data/network/task/send_transaction/ETHRequestTask.java index 2ce61c4fab..c4b241f362 100644 --- a/app/src/main/java/com/tangem/data/network/task/send_transaction/ETHRequestTask.java +++ b/app/src/main/java/com/tangem/data/network/task/send_transaction/ETHRequestTask.java @@ -42,6 +42,7 @@ public class ETHRequestTask extends InfuraTask { JSONObject err = msg.getJSONObject("error"); hashTX = err.getString("message"); LastSignStorage.setLastMessage(sendTransactionActivity.mCard.getWallet(), hashTX); + Log.e("Send_TX_Error:", hashTX); sendTransactionActivity.finishWithError(hashTX); return; } 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 7d9a15992d..1caec05568 100644 --- a/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java +++ b/app/src/main/java/com/tangem/data/nfc/SignPaymentTask.java @@ -69,6 +69,7 @@ public class SignPaymentTask extends Thread { Log.i(TAG, "[-- Start sign payment --]"); if (isCancelled) return; + protocol.run_Read(false); protocol.run_VerifyCard(); Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName()); @@ -102,7 +103,7 @@ public class SignPaymentTask extends Thread { txStr = String.format("0x%s", txStr); } - LastSignStorage.setLastTX(mCard.getWallet(), txStr); + //LastSignStorage.setLastTX(mCard.getWallet(), txStr); Intent intent = new Intent(mContext, SendTransactionActivity.class); intent.putExtra("UID", mCard.getUID()); diff --git a/app/src/main/java/com/tangem/data/nfc/VerifyCardTask.java b/app/src/main/java/com/tangem/data/nfc/VerifyCardTask.java index 894cc73af5..0cf5df18b6 100644 --- a/app/src/main/java/com/tangem/data/nfc/VerifyCardTask.java +++ b/app/src/main/java/com/tangem/data/nfc/VerifyCardTask.java @@ -57,7 +57,7 @@ public class VerifyCardTask extends Thread { String PIN = mCard.getPIN(); protocol.setPIN(PIN); - protocol.run_Read(); + protocol.run_Read(false); PINStorage.setLastUsedPIN(PIN); mNotifications.OnReadProgress(protocol, 30); if (isCancelled) return; diff --git a/app/src/main/java/com/tangem/domain/BitcoinNode.kt b/app/src/main/java/com/tangem/domain/BitcoinNode.kt new file mode 100644 index 0000000000..b8e36d6414 --- /dev/null +++ b/app/src/main/java/com/tangem/domain/BitcoinNode.kt @@ -0,0 +1,16 @@ +package com.tangem.domain + +enum class BitcoinNode(val host: String, val port: Int) { + n1("174.138.11.174", 50001), + n2("btc.cihar.com", 50001), + n3("electrum.leblancnet.us", 50001), + n4("electrum.qtornado.com", 50001), + n5("electrum.vom-stausee.de", 50001), + n6("helicarrier.bauerj.eu", 50001), + n7("kirsche.emzy.de", 50001), + n8("ndnd.selfhost.eu", 50001), + n9("spv.48.org", 50003), + n10("such.ninja", 50001), + n11("tardis.bauerj.eu", 50001), + n12("vps.hsmiths.com", 50001) +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/BitcoinNodeTestNet.kt b/app/src/main/java/com/tangem/domain/BitcoinNodeTestNet.kt index 19eb277f5a..bdd06a5428 100644 --- a/app/src/main/java/com/tangem/domain/BitcoinNodeTestNet.kt +++ b/app/src/main/java/com/tangem/domain/BitcoinNodeTestNet.kt @@ -1,9 +1,9 @@ package com.tangem.domain enum class BitcoinNodeTestNet(val host: String, val port: Int) { - arihanc_com("testnetnode.arihanc.com", 51001), - hsmiths_com("testnet.hsmiths.com", 53011), - qtornado_com("testnet.qtornado.com", 51001), - bauerj_eu("testnet1.bauerj.eu", 50001), + n1("testnetnode.arihanc.com", 51001), + n2("testnet.hsmiths.com", 53011), + n3("testnet.qtornado.com", 51001), + n4("testnet1.bauerj.eu", 50001), } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java b/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java index ccfd198590..e7b3f1801b 100644 --- a/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java +++ b/app/src/main/java/com/tangem/domain/cardReader/CardProtocol.java @@ -408,6 +408,9 @@ public class CardProtocol { } public void run_Read() throws Exception { + run_Read(true); + } + public void run_Read(boolean parseResult) throws Exception { CommandApdu rqApdu = StartPrepareCommand(INS.Read); Log.i(logTag, String.format("[%s]\n%s", rqApdu.getCommandName(), rqApdu.getTLVs().getParsedTLVs(" "))); @@ -421,9 +424,12 @@ public class CardProtocol { readResult = rspApdu.getTLVs(); - parseReadResult(); - - run_ReadWriteIssuerData(); + if( parseResult ){ + parseReadResult(); + run_ReadWriteIssuerData(); + }else{ + //TODO: проверить что карта та же + } } else if (rspApdu.isStatus(SW_PIN_ERROR)) { throw new TangemException_InvalidPIN(String.format("FAILED: [%04X] - Possible PIN is invalid!\n", rspApdu.getSW1SW2())); 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 92d2794d58..9f5f870ac6 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java +++ b/app/src/main/java/com/tangem/domain/wallet/BtcEngine.java @@ -2,6 +2,7 @@ package com.tangem.domain.wallet; import android.net.Uri; +import com.tangem.domain.BitcoinNode; import com.tangem.domain.BitcoinNodeTestNet; import com.tangem.domain.cardReader.CardProtocol; import com.tangem.domain.cardReader.TLV; @@ -55,20 +56,22 @@ public class BtcEngine extends CoinEngine { } public static String[] GetBitcoinServiceHosts() { - return new String[]{"vps.hsmiths.com", "tardis.bauerj.eu" /*"arihancckjge66iv.onion"*/, "electrumx.bot.nu", "electrumx.hopto.org"/* "btc.asis.io"*/, "e-x.not.fyi", "electrum.backplanedns.org", "helicarrier.bauerj.eu", "electrum.vom-stausee.de", "electrum0.snel.it", "kirsche.emzy.de"}; +// return new String[]{"vps.hsmiths.com", "tardis.bauerj.eu" /*"arihancckjge66iv.onion"*/, "electrumx.bot.nu", "electrumx.hopto.org"/* "btc.asis.io"*/, "e-x.not.fyi", "electrum.backplanedns.org", "helicarrier.bauerj.eu", "electrum.vom-stausee.de", "electrum0.snel.it", "kirsche.emzy.de"}; + 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(),}; } public static Integer[] GetBitcoinServicePorts() { - return new Integer[]{8080, 50001/* 8080*/, 50001, 50001, 50001, 50001, 50001, 50001, 50001, 50001}; +// return new Integer[]{8080, 50001/* 8080*/, 50001, 50001, 50001, 50001, 50001, 50001, 50001, 50001}; + 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(),}; } public static String[] GetBitcoinTestNetServiceHosts() { - return new String[]{/*"testnetnode.arihanc.com"*/BitcoinNodeTestNet.hsmiths_com.getHost(), BitcoinNodeTestNet.qtornado_com.getHost(), BitcoinNodeTestNet.bauerj_eu.getHost()}; + return new String[]{BitcoinNodeTestNet.n1.getHost(), BitcoinNodeTestNet.n2.getHost(), BitcoinNodeTestNet.n3.getHost(), BitcoinNodeTestNet.n4.getHost()}; } public static Integer[] GetBitcoinTestNetServicePorts() { - return new Integer[]{/*51001*/BitcoinNodeTestNet.hsmiths_com.getPort(), BitcoinNodeTestNet.qtornado_com.getPort(), BitcoinNodeTestNet.bauerj_eu.getPort()}; + return new Integer[]{BitcoinNodeTestNet.n1.getPort(), BitcoinNodeTestNet.n2.getPort(), BitcoinNodeTestNet.n3.getPort(), BitcoinNodeTestNet.n4.getPort()}; } diff --git a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.java b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.java index 628b299437..136b837345 100644 --- a/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/ConfirmPaymentActivity.java @@ -59,7 +59,7 @@ public class ConfirmPaymentActivity extends AppCompatActivity implements NfcAdap public boolean balanceRequestSuccess = false; private EditText etWallet; // private TextView tvAmountEquivalent; -// private TextView tvFeeEquivalent; + private TextView tvFeeEquivalent; public EditText etAmount; public EditText etFee; private ImageView ivCamera; @@ -95,7 +95,7 @@ public class ConfirmPaymentActivity extends AppCompatActivity implements NfcAdap etFee = findViewById(R.id.etFee); // TextView tvBalanceEquivalent = findViewById(R.id.tvBalanceEquivalent); // tvAmountEquivalent = findViewById(R.id.tvAmountEquivalent); -// tvFeeEquivalent = findViewById(R.id.tvFeeEquivalent); + tvFeeEquivalent = findViewById(R.id.tvFeeEquivalent); ivCamera = findViewById(R.id.ivCamera); rgFee = findViewById(R.id.rgFee); @@ -138,21 +138,21 @@ public class ConfirmPaymentActivity extends AppCompatActivity implements NfcAdap @Override public void onTextChanged(CharSequence s, int start, int before, int count) { -// try { -// -// CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain()); -// String eqFee = engine.EvaluteFeeEquivalent(mCard, etFee.getText().toString()); -// tvFeeEquivalent.setText(eqFee); -// -// if (!mCard.getAmountEquivalentDescriptionAvailable()) { -// tvFeeEquivalent.setError("Service unavailable"); -// } else { -// tvFeeEquivalent.setError(null); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// tvFeeEquivalent.setText(""); -// } + try { + + CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain()); + String eqFee = engine.EvaluteFeeEquivalent(mCard, etFee.getText().toString()); + tvFeeEquivalent.setText(eqFee); + + if (!mCard.getAmountEquivalentDescriptionAvailable()) { + tvFeeEquivalent.setError("Service unavailable"); + } else { + tvFeeEquivalent.setError(null); + } + } catch (Exception e) { + e.printStackTrace(); + tvFeeEquivalent.setText(""); + } } @Override diff --git a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java index f769bffe6e..cf66309198 100644 --- a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java @@ -47,12 +47,12 @@ public class SendTransactionActivity extends AppCompatActivity { } else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) { String nodeAddress = engine.GetNode(mCard); int nodePort = engine.GetNodePort(mCard); - ConnectTask connectTask = new ConnectTask(SendTransactionActivity.this, nodeAddress, nodePort); + ConnectTask connectTask = new ConnectTask(SendTransactionActivity.this, nodeAddress, nodePort,3); connectTask.execute(ElectrumRequest.Broadcast(mCard.getWallet(), tx)); } else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) { String nodeAddress = engine.GetNode(mCard); int nodePort = engine.GetNodePort(mCard); - ConnectTask connectTask = new ConnectTask(SendTransactionActivity.this, nodeAddress, nodePort); + ConnectTask connectTask = new ConnectTask(SendTransactionActivity.this, nodeAddress, nodePort,3); connectTask.execute(ElectrumRequest.Broadcast(mCard.getWallet(), tx)); } @@ -70,7 +70,7 @@ public class SendTransactionActivity extends AppCompatActivity { public void finishWithError(String Message) { Intent intent = new Intent(); - intent.putExtra("message", "Failed to send transaction. Try again."); + intent.putExtra("message", "Try again. Failed to send transaction (" + Message + ")"); setResult(MainActivity.RESULT_CANCELED, intent); finish(); } diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java index 406ebeccb7..705c882765 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java @@ -680,7 +680,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre tvMessage.setVisibility(View.GONE); } else { if (needResendTX) { - tvMessage.setText(R.string.sending_cached_transaction); + //tvMessage.setText(R.string.sending_cached_transaction); } else { tvMessage.setText(mCard.getMessage()); } diff --git a/app/src/main/res/layout/activity_confirm_payment.xml b/app/src/main/res/layout/activity_confirm_payment.xml index 8d71a994ee..81c73d830f 100644 --- a/app/src/main/res/layout/activity_confirm_payment.xml +++ b/app/src/main/res/layout/activity_confirm_payment.xml @@ -330,18 +330,18 @@ app:layout_constraintLeft_toRightOf="@+id/etFee" app:layout_constraintTop_toTopOf="parent"/> - - - - - - - - - - - - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7598d2ed11..7be1e07de2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -90,7 +90,7 @@ The wallet is empty Not enough funds for transaction fee (gas)! Please wait while previous transaction is confirmed in blockchain - Please wait for confirmation of incoming transaction! + Could not obtain all inputs. Swipe down to refresh. Card hasn\'t remaining signature! REUSABLE WALLET BANKNOTE